public VaginaCreator(VaginaType vaginaType, double?clitLengthInInches = null, VaginalWetness vaginalWetness = VaginalWetness.NORMAL, VaginalLooseness vaginalLooseness = VaginalLooseness.TIGHT, bool omnibusClit = false, bool isVirgin = true, Dictionary <ClitPiercingLocation, PiercingJewelry> clitJewelry = null, Dictionary <LabiaPiercingLocation, PiercingJewelry> labiaJewelry = null) { type = vaginaType; clitLength = clitLengthInInches; wetness = vaginalWetness; looseness = vaginalLooseness; hasClitCock = omnibusClit; clitPiercings = clitJewelry == null ? null : new ReadOnlyDictionary <ClitPiercingLocation, PiercingJewelry>(clitJewelry); labiaPiercings = labiaJewelry == null ? null : new ReadOnlyDictionary <LabiaPiercingLocation, PiercingJewelry>(labiaJewelry); virgin = isVirgin; }
public static string AsAdjective(this VaginalWetness vaginalWetness) { switch (vaginalWetness) { case VaginalWetness.SLAVERING: return("absolutely drenched in fem-spunk"); case VaginalWetness.DROOLING: return("dripping natural lubricant"); case VaginalWetness.SLICK: return("slick with fem-spunk"); case VaginalWetness.WET: return("wetter than normal"); case VaginalWetness.DRY: return("rather dry"); case VaginalWetness.NORMAL: default: return("only a little wet"); } }
public static string AsDescriptor(this VaginalWetness vaginalWetness) { switch (vaginalWetness) { case VaginalWetness.SLAVERING: return("slavering"); case VaginalWetness.DROOLING: return("drooling"); case VaginalWetness.SLICK: return("slick"); case VaginalWetness.WET: return("wet"); case VaginalWetness.DRY: return("dry"); case VaginalWetness.NORMAL: default: return(""); } }
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(); //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. if (remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } //Any transformation related changes go here. these typically cost 1 change. these can be anything from body parts to gender (which technically also changes body parts, //but w/e). You are required to make sure you return as soon as you've applied changeCount changes, but a single line of code can be applied at the end of a change to do //this for you. //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); //----------------------- // MAJOR TRANSFORMATIONS //----------------------- //1st priority: Change lower body to bipedal. if (Utils.Rand(4) == 0) { LowerBodyData oldData = target.lowerBody.AsReadOnlyData(); target.RestoreLowerBody(); sb.Append(RestoredLowerBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove Oviposition Perk if (target.womb.canRemoveOviposition && Utils.Rand(5) == 0) { target.womb.ClearOviposition(); sb.Append(ClearOvipositionText(target)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove Incorporeality Perk, if not permanent if (target.HasPerk <Incorporeal>() && Utils.Rand(4) == 0) { target.RemovePerk <Incorporeal>(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Restore neck if (target.neck.type != NeckType.HUMANOID && Utils.Rand(5) == 0) { NeckData oldData = target.neck.AsReadOnlyData(); target.RestoreNeck(); sb.Append(RestoredNeckText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Rear body restore if (!target.back.isDefault && Utils.Rand(5) == 0) { BackData oldData = target.back.AsReadOnlyData(); target.RestoreBack(); sb.Append(RestoredBackText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Skin color change – light, fair, olive, dark, ebony, mahogany, russet if (!Species.HUMAN.availableTones.Contains(target.body.primarySkin.tone) && Utils.Rand(5) == 0) { target.body.ChangeAllSkin(Utils.RandomChoice(Species.HUMAN.availableTones)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Change skin to normal if (target.body.type != BodyType.HUMANOID && (target.ears.type == EarType.HUMAN || target.ears.type == EarType.ELFIN) && Utils.Rand(4) == 0) { BodyData oldData = target.body.AsReadOnlyData(); target.RestoreBody(); sb.Append(RestoredBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Restore arms to become human arms again if (Utils.Rand(4) == 0) { ArmData oldData = target.arms.AsReadOnlyData(); target.RestoreArms(); sb.Append(RestoredArmsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //----------------------- // MINOR TRANSFORMATIONS //----------------------- //-Human face if (target.face.type != FaceType.HUMAN && Utils.Rand(4) == 0) { FaceData oldData = target.face.AsReadOnlyData(); target.RestoreFace(); sb.Append(RestoreFaceText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Human tongue if (target.tongue.type != TongueType.HUMAN && Utils.Rand(4) == 0) { TongueData oldData = target.tongue.AsReadOnlyData(); target.RestoreTongue(); sb.Append(RestoreTongueText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove odd eyes if (Utils.Rand(5) == 0 && target.eyes.type != EyeType.HUMAN) { EyeData oldData = target.eyes.AsReadOnlyData(); target.RestoreEyes(); sb.Append(RestoredEyesText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Gain human ears (If you have human face) if (target.ears.type != EarType.HUMAN && target.face.type == FaceType.HUMAN && Utils.Rand(4) == 0) { EarData oldData = target.ears.AsReadOnlyData(); target.RestoreEar(); sb.Append(RestoreEarsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Removes gills if (Utils.Rand(4) == 0 && !target.gills.isDefault) { GillData oldData = target.gills.AsReadOnlyData(); target.RestoreGills(); sb.Append(RestoredGillsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Nipples Turn Back: if (target.genitals.hasBlackNipples && Utils.Rand(3) == 0) { target.genitals.SetBlackNipples(false); } //Remove extra nipples if (target.genitals.hasQuadNipples && Utils.Rand(3) == 0) { target.genitals.SetQuadNipples(false); } //Hair turns normal //Restart hair growth, if hair's normal but growth isn't on. Or just over turning hair normal. The power of rng. if ((target.hair.type != HairType.NORMAL || target.hair.growthArtificallyDisabled) && Utils.Rand(3) == 0) { target.UpdateHair(HairType.NORMAL); if (target.hair.growthArtificallyDisabled) { target.hair.SetHairGrowthStatus(true); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //----------------------- // EXTRA PARTS REMOVAL //----------------------- //Removes antennae if (target.antennae.type != AntennaeType.NONE && Utils.Rand(3) == 0) { AntennaeData oldData = target.antennae.AsReadOnlyData(); target.RestoreAntennae(); sb.Append(RestoredAntennaeText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Removes horns if ((target.horns.type != HornType.NONE) && Utils.Rand(5) == 0) { HornData oldData = target.horns.AsReadOnlyData(); target.RestoreHorns(); sb.Append(RestoredHornsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Removes wings if (target.wings.type != WingType.NONE && Utils.Rand(5) == 0) { WingData oldData = target.wings.AsReadOnlyData(); target.RestoreWings(); sb.Append(RestoredWingsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Removes tail if (target.tail.type != TailType.NONE && Utils.Rand(5) == 0) { TailData oldData = target.tail.AsReadOnlyData(); target.RestoreTail(); sb.Append(RestoredTailText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Increase height up to 4ft 10in. if (Utils.Rand(2) == 0 && target.build.heightInInches < 58) { int temp = Utils.Rand(5) + 3; //Flavor texts. Flavored like 1950's cigarettes. Yum. target.build.IncreaseHeight((byte)temp); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Decrease height down to a maximum of 6ft 2in. if (Utils.Rand(2) == 0 && target.build.heightInInches > 74) { target.build.DecreaseHeight((byte)(3 + Utils.Rand(5))); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //----------------------- // SEXUAL TRANSFORMATIONS //----------------------- //Remove additional cocks if (target.cocks.Count > 1 && Utils.Rand(3) == 0) { target.RemoveCock(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove additional balls/remove uniball if (target.balls.hasBalls && (target.balls.count != 2 || target.balls.uniBall) && Utils.Rand(3) == 0) { if (target.balls.size > 2) { if (target.balls.size > 5) { target.balls.ShrinkBalls((byte)(1 + Utils.Rand(3))); } target.balls.ShrinkBalls(1); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } else if (target.balls.count > 2) { target.balls.RemoveExtraBalls(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } else //if (target.balls.count == 1 || target.balls.uniBall) { target.balls.MakeStandard(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } } //remove second v****a. if (target.vaginas.Count > 1 && Utils.Rand(3) == 0) { target.genitals.RemoveExtraVaginas(); } //Change c**k back to normal if (target.hasCock && !target.genitals.OnlyHasCocksOfType(CockType.HUMAN) && Utils.Rand(3) == 0) { //Select first non-human c**k C**k firstNonHuman = target.cocks.First(x => x.type != CockType.HUMAN); target.genitals.UpdateCock(firstNonHuman, CockType.HUMAN); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } C**k longest = target.genitals.LongestCock(); double targetSize = Math.Max(7, target.genitals.minimumCockLength); //Shrink oversized cocks if (target.hasCock && longest.length > targetSize && Utils.Rand(3) == 0) { longest.DecreaseLength((Utils.Rand(10) + 2) / 10.0); if (longest.girth > 1) { longest.DecreaseThickness((Utils.Rand(4) + 1) / 10.0); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove additional breasts if (target.breasts.Count > 1 && Utils.Rand(3) == 0) { target.RemoveExtraBreastRows(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } Breasts biggestCup = target.genitals.LargestBreast(); CupSize targetCup = EnumHelper.Max(CupSize.D, target.genitals.smallestPossibleFemaleCupSize); //Shrink t**s! if (Utils.Rand(3) == 0 && biggestCup.cupSize > targetCup) { foreach (Breasts t**s in target.breasts) { t**s.ShrinkBreasts(); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Change v****a back to normal if (Utils.Rand(3) == 0 && target.hasVagina && !target.genitals.OnlyHasVaginasOfType(VaginaType.defaultValue)) { foreach (V****a vag in target.vaginas) { target.genitals.RestoreVagina(vag); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } VaginalWetness targetWetness = EnumHelper.Max(VaginalWetness.WET, target.genitals.minVaginalWetness); //Reduce wetness down to a minimum of 2 if (Utils.Rand(3) == 0 && target.hasVagina && target.genitals.LargestVaginalWetness() > targetWetness) { foreach (V****a vag in target.vaginas) { if (vag.wetness > targetWetness) { vag.DecreaseWetness(); } } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Fertility Decrease: if (target.hasVagina && target.fertility.baseFertility > 10 && Utils.Rand(3) == 0) { //High fertility: //Average fertility: target.fertility.DecreaseFertility((byte)(1 + Utils.Rand(3))); if (target.fertility.baseFertility < 10) { target.fertility.SetFertility(10); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Cum Multiplier Decrease: if (target.hasCock && target.genitals.cumMultiplier > 5 && Utils.Rand(3) == 0) { target.genitals.DecreaseCumMultiplier(1 + (Utils.Rand(20) / 10.0)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Anal wetness decrease if (target.ass.wetness > 0 && Utils.Rand(3) == 0) { target.ass.DecreaseWetness(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //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(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); }
private void CheckVaginalWetnessChanged(VaginalWetness oldValue) { source.genitals.perkData.ValidateVaginalWetness(); }
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, 4 }); int remainingChanges = changeCount; 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. if (remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } //Any transformation related changes go here. these typically cost 1 change. these can be anything from body parts to gender (which technically also changes body parts, //but w/e). You are required to make sure you return as soon as you've applied changeCount changes, but a single line of code can be applied at the end of a change to do //this for you. //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); #warning fix me int ngPlus(int value) => value; if (target.speed < ngPlus(100) && Utils.Rand(3) == 0) { //+3 spe if less than 50 if (target.speed < ngPlus(50)) { target.ChangeSpeed(1); } //+2 spe if less than 75 if (target.speed < ngPlus(75)) { target.ChangeSpeed(1); } //+1 if above 75. target.ChangeSpeed(1); } if (target.toughness > ngPlus(80) && Utils.Rand(4) == 0) { target.ChangeToughness(-1); } //-Reduces sensitivity. if (target.sensitivity > 20 && Utils.Rand(3) == 0) { target.ChangeSensitivity(-1); } //Raises libido greatly to 50, then somewhat to 75, then slowly to 100. if (target.libido < 100 && Utils.Rand(3) == 0) { //+3 lib if less than 50 if (target.libido < 50) { target.ChangeLibido(1); } //+2 lib if less than 75 if (target.libido < 75) { target.ChangeLibido(1); } //+1 if above 75. target.ChangeLibido(1); } //Sexual changes //-Lactation stoppage. if (target.genitals.isLactating && Utils.Rand(4) == 0) { if (target.HasPerk <Feeder>()) { target.RemovePerk <Feeder>(); } target.genitals.SetLactationTo(LactationStatus.NOT_LACTATING); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Nipples reduction to 1 per tit. if (target.genitals.hasQuadNipples && Utils.Rand(4) == 0) { target.genitals.SetQuadNipples(false); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Remove extra breast rows if (target.breasts.Count > 1 && Utils.Rand(3) == 0 && !hyperHappy) { target.RemoveExtraBreastRows(); } //-Butt > 5 - decrease butt size if (target.butt.size > 5 && Utils.Rand(4) == 0) { if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } target.butt.ShrinkButt(); } if (target.gender.HasFlag(Gender.FEMALE)) { CupSize minCup = EnumHelper.Max(CupSize.D, target.genitals.smallestPossibleFemaleCupSize); //Breasts > D cup - Decrease breast size by up to 3 cups //MOD NOTE: Now respects minimum cup size from perks. if (target.gender.HasFlag(Gender.FEMALE) && target.genitals.BiggestCupSize() > minCup && Utils.Rand(3) == 0) { foreach (Breasts breast in target.breasts) { if (breast.cupSize > CupSize.D) { breast.ShrinkBreasts((byte)(1 + Utils.Rand(3))); } } target.IncreaseSpeed(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Breasts < B cup - Increase breast size by 1 cup if (target.gender.HasFlag(Gender.FEMALE) && target.genitals.SmallestCupSize() < CupSize.B && Utils.Rand(3) == 0) { for (int i = 0; i < target.breasts.Count; i++) { if (target.breasts[i].cupSize < CupSize.B) { target.breasts[i].GrowBreasts(); } } target.ChangeLibido(1); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Hips > 12 - decrease hip size by 1-3 sizes if (target.hips.size > 12 && Utils.Rand(3) == 0) { target.hips.ShrinkHips((byte)(1 + Utils.Rand(3))); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Hips < 6 - increase hip size by 1-3 sizes if (target.hips.size < 6 && Utils.Rand(3) == 0) { target.hips.GrowHips((byte)(1 + Utils.Rand(3))); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } if (target.genitals.nippleLength > 1 && Utils.Rand(3) == 0) { target.genitals.SetNippleLength(target.genitals.nippleLength / 2); } VaginalWetness desiredWetness = EnumHelper.Min(target.genitals.maxVaginalWetness, VaginalWetness.SLICK); //MOD NOTE: now respects all vaginas, and the maximum wetness allowed by perks (if applicable) if (target.hasVagina && target.genitals.SmallestVaginalWetness() < desiredWetness && Utils.Rand(4) == 0) { foreach (V****a vag in target.vaginas) { if (vag.wetness < desiredWetness) { vag.IncreaseWetness(); } } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Increase tone (up to 65) if (target.build.muscleTone < 65 && Utils.Rand(3) == 0) { target.build.ChangeMuscleToneToward(65, 2); } //Decrease thickness (down to 35) if (target.build.thickness > 35 && Utils.Rand(3) == 0) { target.build.ChangeThicknessToward(35, 5); } //Grant oviposition. if (target.womb.canObtainOviposition && Species.COCKATRICE.Score(target) > 3 && Utils.Rand(5) == 0) { target.womb.GrantOviposition(); sb.Append(GrantOvipositionText(target)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } } if (target.gender == Gender.MALE) { //Breasts > B cup - decrease by 1 cup size if (target.genitals.BiggestCupSize() > CupSize.B && Utils.Rand(3) == 0) { for (int i = 0; i < target.breasts.Count; i++) { if (target.breasts[i].cupSize > CupSize.B) { target.breasts[i].ShrinkBreasts(); } } target.IncreaseSpeed(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } if (target.genitals.nippleLength > 1 && Utils.Rand(3) == 0) { target.genitals.SetNippleLength(target.genitals.nippleLength / 2); } //Hips > 10 - decrease hip size by 1-3 sizes if (target.hips.size > 10 && Utils.Rand(3) == 0) { target.hips.ShrinkHips((byte)(1 + Utils.Rand(3))); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Hips < 2 - increase hip size by 1-3 sizes if (target.hips.size < 2 && Utils.Rand(3) == 0) { target.hips.GrowHips((byte)(1 + Utils.Rand(3))); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Increase tone (up to 70) if (target.build.muscleTone < 70 && Utils.Rand(3) == 0) { target.build.ChangeMuscleToneToward(70, 2); } //Decrease thickness (down to 35) if (target.build.thickness > 35 && Utils.Rand(3) == 0) { target.build.ChangeThicknessToward(35, 5); } } if (target.gender.HasFlag(Gender.MALE)) { //C**k < 6 inches - increase by 1-2 inches C**k shortest = target.genitals.ShortestCock(); if (shortest.length < 6 && Utils.Rand(3) == 0) { double increment = shortest.IncreaseLength(1 + Utils.Rand(2)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } C**k longest = target.genitals.LongestCock(); //Shrink oversized cocks if (longest.length > 16 && Utils.Rand(3) == 0) { longest.DecreaseLength((Utils.Rand(10) + 5) / 10.0); if (longest.girth > 3) { longest.DecreaseThickness((Utils.Rand(4) + 1) / 10.0); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } C**k thinnest = target.genitals.ThinnestCock(); //C**k thickness <2 - Increase c**k thickness if (thinnest.girth < 2 && Utils.Rand(3) == 0) { thinnest.IncreaseThickness(1.5); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } } int lizardCocks = target.genitals.CountCocksOfType(CockType.LIZARD); if (target.hasCock && target.cocks.Count > lizardCocks && Utils.Rand(4) == 0) { //-Lizard dick - first one if (lizardCocks == 0) { //Actually xform it nau if (target.genitals.hasSheath) { target.genitals.UpdateCock(0, CockType.LIZARD); } else { target.genitals.UpdateCock(0, CockType.LIZARD); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } target.DeltaCreatureStats(lib: 3, lus: 10); } //(CHANGE OTHER DICK) //Requires 1 lizard c**k, multiple cocks else //if (target.cocks.Count > 1 && target.cocks.Count > lizardCocks) { C**k firstNonLizard = target.cocks.First(x => x.type != CockType.LIZARD); target.genitals.UpdateCock(firstNonLizard, CockType.LIZARD); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } target.DeltaCreatureStats(lib: 3, lus: 10); } } //MOD NOTE: Worms are being removed??? from the game due to that absolutely shitty license that prevents me from porting any content 'created' by //its creator (forget the name at this time). it's a bad license because it takes credit from other content creators that use its content. that's like saying //the creator of the rubber tire gets credit for all modern car designs. that's bullshit. of course cars require tires, and the original copyright required users //to pay a licensing fee for their use. that didn't grant the copyright holder for rubber tires the credit for the cars that used them. If anyone wants to get ahold //of the og worms creator and get him/her to relax that requirement to make it reasonable (and future content-change/port friendly), we'll see. until then, this is //removed. //For the record, that would grant him creator's credit on this document. which he/she had no input on. that's not right. and, by extension, the inventory system, since //this item is in use in the inventory system. and the time engine, because worms regen over time. I am the content creator for both of those, and i refuse to allow him/her //any credit for either of those. those took time and effort and were difficult - i'm not freely handing credit to him/her because that license would require me to. Either //his/her license changes, or the offending content is removed, or the entire game engine goes. Right now i think it's better go with the game engine because it make all of //this shit work. - JSG. ////--Worms leave if 100% lizard dicks? ////Require mammals? //if (target.genitals.CountCocksOfType(CockType.LIZARD) == target.cocks.Count && target.hasStatusEffect(StatusEffects.Infested)) //{ // if (target.balls.count > 1) // target.removeStatusEffect(StatusEffects.Infested); // if (--remainingChanges <= 0) return ApplyChangesAndReturn(target, sb, changeCount - remainingChanges); //} //Increase height up to 5ft 7in. if (target.build.heightInInches < 67 && Utils.Rand(5) == 0) { target.build.IncreaseHeight((byte)(Utils.Rand(3) + 1)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Decrease height down to a maximum of 6ft 8in. if (target.build.heightInInches > 80 && Utils.Rand(5) == 0) { target.build.DecreaseHeight((byte)(Utils.Rand(3) + 1)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Physical changes: //Removes other antennae if (target.antennae.type != AntennaeType.COCKATRICE && !target.antennae.isDefault && Utils.Rand(3) == 0) { target.RestoreAntennae(); } //Gain antennae like feathers if (target.antennae.type == AntennaeType.NONE && target.face.type == FaceType.COCKATRICE && target.ears.type == EarType.COCKATRICE && Utils.Rand(3) == 0) { // Other antennae types are handled above! (Stadler76) AntennaeData oldData = target.antennae.AsReadOnlyData(); target.UpdateAntennae(AntennaeType.COCKATRICE); sb.Append(UpdateAntennaeText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Removes horns if (target.horns.type != HornType.NONE && Utils.Rand(5) == 0) { HornData oldData = target.horns.AsReadOnlyData(); target.RestoreHorns(); sb.Append(RestoredHornsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Face TF if (target.face.type != FaceType.COCKATRICE && target.arms.type == ArmType.COCKATRICE && target.lowerBody.type == LowerBodyType.COCKATRICE && Utils.Rand(3) == 0) { FaceData oldData = target.face.AsReadOnlyData(); target.UpdateFace(FaceType.COCKATRICE); sb.Append(UpdateFaceText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Hair TF if (target.hair.type != HairType.FEATHER && Utils.Rand(4) == 0) { HairData oldData = target.hair.AsReadOnlyData(); target.UpdateHair(HairType.FEATHER); sb.Append(UpdateHairText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Eye TF if (target.eyes.type != EyeType.COCKATRICE && target.face.type == FaceType.COCKATRICE && target.body.type == BodyType.COCKATRICE && target.ears.type == EarType.COCKATRICE && Utils.Rand(3) == 0) { EyeData oldData = target.eyes.AsReadOnlyData(); target.UpdateEyes(EyeType.COCKATRICE); sb.Append(UpdateEyesText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Lizard tongue TF if (target.tongue.type != TongueType.LIZARD && target.face.type == FaceType.COCKATRICE && Utils.Rand(3) == 0) { TongueData oldData = target.tongue.AsReadOnlyData(); target.UpdateTongue(TongueType.LIZARD); sb.Append(UpdateTongueText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Ears TF if (target.ears.type != EarType.COCKATRICE && target.face.type == FaceType.COCKATRICE && Utils.Rand(3) == 0) { EarData oldData = target.ears.AsReadOnlyData(); target.UpdateEars(EarType.COCKATRICE); sb.Append(UpdateEarsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Arm TF if (target.arms.type != ArmType.COCKATRICE && Utils.Rand(4) == 0) { ArmData oldData = target.arms.AsReadOnlyData(); target.UpdateArms(ArmType.COCKATRICE); sb.Append(UpdateArmsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Neck loss, if not cockatrice neck if (target.neck.type != NeckType.COCKATRICE && Utils.Rand(4) == 0) { NeckData oldData = target.neck.AsReadOnlyData(); target.RestoreNeck(); sb.Append(RestoredNeckText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Rear body restore if (target.back.type != BackType.NORMAL && Utils.Rand(5) == 0) { BackData oldData = target.back.AsReadOnlyData(); target.RestoreBack(); sb.Append(RestoredBackText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Body TF if (target.body.type != BodyType.COCKATRICE && target.face.type == FaceType.COCKATRICE && Utils.Rand(3) == 0) { Species.COCKATRICE.GetRandomCockatriceColors(out FurColor feathers, out Tones scales); target.UpdateBody(BodyType.COCKATRICE, feathers, scales); NeckData oldData = target.neck.AsReadOnlyData(); target.UpdateNeck(NeckType.COCKATRICE, feathers.primaryColor); sb.Append(UpdateNeckText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Neck TF, if not already TFed from Body TF above if (target.neck.type != NeckType.COCKATRICE && target.body.type == BodyType.COCKATRICE && target.face.type == FaceType.COCKATRICE && Utils.Rand(3) == 0) { NeckData oldData = target.neck.AsReadOnlyData(); target.UpdateNeck(NeckType.COCKATRICE, Utils.RandomChoice(Species.COCKATRICE.availablePrimaryFeatherColors)); sb.Append(UpdateNeckText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Leg TF if (target.lowerBody.type != LowerBodyType.COCKATRICE && Utils.Rand(4) == 0) { LowerBodyData oldData = target.lowerBody.AsReadOnlyData(); target.UpdateLowerBody(LowerBodyType.COCKATRICE); sb.Append(UpdateLowerBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Tail TF if (target.tail.type != TailType.COCKATRICE && Utils.Rand(4) == 0) { TailData oldData = target.tail.AsReadOnlyData(); target.UpdateTail(TailType.COCKATRICE); sb.Append(UpdateTailText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Wings TF //feathered wings and not large and a target? that shouldn't happen. silently make them large if (target.wings.type == WingType.FEATHERED && !target.wings.isLarge && target is Player) { target.wings.GrowLarge(); } else if (target.wings.type != WingType.FEATHERED && target.arms.type == ArmType.COCKATRICE && Utils.Rand(4) == 0) { HairFurColors wingColor = !target.body.activeFur.isEmpty ? target.body.activeFur.fur.primaryColor : target.hair.hairColor; WingData oldData = target.wings.AsReadOnlyData(); target.UpdateWings(WingType.FEATHERED); sb.Append(UpdateWingsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //FAILSAFE CHANGE if (remainingChanges == changeCount) { if (target is CombatCreature failSafe) { failSafe.AddHP(50); } target.ChangeLust(3); } //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(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); }
public VaginaCreator(double?clitLengthInInches = null, VaginalWetness vaginalWetness = VaginalWetness.NORMAL, VaginalLooseness vaginalLooseness = VaginalLooseness.TIGHT, bool omnibusClit = false, bool isVirgin = true, Dictionary <ClitPiercingLocation, PiercingJewelry> clitJewelry = null, Dictionary <LabiaPiercingLocation, PiercingJewelry> labiaJewelry = null) : this(VaginaType.HUMAN, clitLengthInInches, vaginalWetness, vaginalLooseness, omnibusClit, isVirgin, clitJewelry, labiaJewelry) { }
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 }); int remainingChanges = changeCount; 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. //STATS CHANGURYUUUUU //Boost speed (max 80!) if (Utils.Rand(3) == 0 && target.relativeSpeed < 80) { target.DeltaCreatureStats(spe: target.relativeSpeed < 35 ? 2 : 1); } //Boost libido if (Utils.Rand(5) == 0) { target.DeltaCreatureStats(lib: 1, lus: (5 + target.libido / 7)); if (target.relativeLibido < 30) { target.ChangeLibido(1); } if (target.relativeLibido < 40) { target.ChangeLibido(1); } if (target.relativeLibido < 60) { target.ChangeLibido(1); } //Lower ones are gender specific for some reason } //BIG sensitivity gains to 60. if (target.relativeSensitivity < 60 && Utils.Rand(3) == 0) { //(low) if (Utils.Rand(3) != 2) { target.ChangeSensitivity(5); } //(BIG boost 1/3 chance) else { target.ChangeSensitivity(15); } } //this will handle the edge case where the change count starts out as 0. if (remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } //Any transformation related changes go here. these typically cost 1 change. these can be anything from body parts to gender (which technically also changes body parts, //but w/e). You are required to make sure you return as soon as you've applied changeCount changes, but a single line of code can be applied at the end of a change to do //this for you. //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); //Makes girls very girl(90), guys somewhat girly (61). if (Utils.Rand(2) == 0) { short res = target.femininity.ChangeFemininityToward((byte)(target.gender.HasFlag(Gender.FEMALE) ? 90 : 61), 4); if (res != 0) { if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } } //De-wettification of c**t (down to 3?)! VaginalWetness targetWetness = EnumHelper.Max(target.genitals.minVaginalWetness, VaginalWetness.SLICK); if (target.hasVagina && target.genitals.SmallestVaginalWetness() > targetWetness && Utils.Rand(3) == 0) { //Just to be safe foreach (V****a vag in target.vaginas) { vag.DecreaseWetness(); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Fertility boost! if (Utils.Rand(4) == 0 && target.fertility.totalFertility < 50 && target.hasVagina) { target.fertility.IncreaseFertility((byte)(2 + Utils.Rand(5))); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-VAGs //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 (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Rear body restore if (!target.back.isDefault && Utils.Rand(5) == 0) { BackData oldData = target.back.AsReadOnlyData(); target.RestoreBack(); sb.Append(RestoredBackText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //MOD: Bunny eggs and oviposition are now one and the same. the idea of removing oviposition and adding bunny eggs - that's just dumb. if (target.womb.canObtainOviposition && Utils.Rand(4) == 0) { target.womb.GrantOviposition(); sb.Append(GrantOvipositionText(target)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Shrink Balls! if (target.balls.count > 0 && target.balls.size > 5 && Utils.Rand(3) == 0) { if (target.balls.size < 10) { target.balls.ShrinkBalls(); } else if (target.balls.size < 25) { target.balls.ShrinkBalls((byte)(2 + Utils.Rand(3))); } else { target.balls.ShrinkBalls((byte)(6 + Utils.Rand(3))); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Get rid of extra balls if (target.balls.count > 2 && Utils.Rand(3) == 0) { target.balls.RemoveExtraBalls(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Boost cum production if ((target.balls.count > 0 || target.hasCock) && target.genitals.totalCum < 3000 && Utils.Rand(3) == 0) { target.genitals.IncreaseCumMultiplier(3 + Utils.Rand(7)); if (target.genitals.totalCum >= 250) { target.ChangeLust(3); } else if (target.genitals.totalCum >= 750) { target.ChangeLust(4); } else if (target.genitals.totalCum >= 2000) { target.ChangeLust(5); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Bunny feet! - requirez earz if (target.lowerBody.type != LowerBodyType.BUNNY && Utils.Rand(5) == 0 && target.ears.type == EarType.BUNNY) { LowerBodyData oldData = target.lowerBody.AsReadOnlyData(); target.UpdateLowerBody(LowerBodyType.BUNNY); sb.Append(UpdateLowerBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //BUN FACE! REQUIREZ EARZ if (target.ears.type == EarType.BUNNY && target.face.type != FaceType.BUNNY && Utils.Rand(3) == 0) { FaceData oldData = target.face.AsReadOnlyData(); target.UpdateFace(FaceType.BUNNY); sb.Append(UpdateFaceText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } else if (target.ears.type == EarType.BUNNY && target.face.type == FaceType.BUNNY && !target.face.isFullMorph && Utils.Rand(3) == 0) { target.face.StrengthenFacialMorph(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //DAH BUNBUN EARZ - requires poofbutt! if (target.ears.type != EarType.BUNNY && Utils.Rand(3) == 0 && target.tail.type == TailType.RABBIT) { EarData oldData = target.ears.AsReadOnlyData(); target.UpdateEars(EarType.BUNNY); sb.Append(UpdateEarsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //DAH BUNBUNTAILZ if (target.tail.type != TailType.RABBIT && Utils.Rand(2) == 0) { TailData oldData = target.tail.AsReadOnlyData(); target.UpdateTail(TailType.RABBIT); sb.Append(UpdateTailText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } // Remove gills if (Utils.Rand(4) == 0 && !target.gills.isDefault) { target.RestoreGills(); } // Remove antennae if (target.antennae.type != AntennaeType.NONE && Utils.Rand(3) == 0) { AntennaeData oldData = target.antennae.AsReadOnlyData(); target.RestoreAntennae(); sb.Append(RestoredAntennaeText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } // Remove wings if ((target.wings.type != WingType.NONE || target.back.type == BackType.SHARK_FIN) && Utils.Rand(4) == 0) { target.RestoreWings(); BackData oldData = target.back.AsReadOnlyData(); target.RestoreBack(); sb.Append(RestoredBackText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Bunny Breeder Perk? //FAILSAAAAFE if (remainingChanges == changeCount) { if (target.relativeLibido < 100) { if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } target.DeltaCreatureStats(lib: 1, lus: (5 + target.libido / 7)); if (target.relativeLibido < 30) { target.ChangeLibido(1); } if (target.relativeLibido < 40) { target.ChangeLibido(1); } if (target.relativeLibido < 60) { target.ChangeLibido(1); } } //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(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); }