protected override void OnEquip(Creature wearer) { if (!wearer.HasPerk <BloodMage>()) { wearer.AddPerk <BloodMage>(); } }
protected override void OnEquip(Creature wearer) { if (!Ceraph.isSlave) { if (wearer.HasPerk <CeraphFetishesPerk>()) { CeraphFetishesPerk ceraph = wearer.GetPerkData <CeraphFetishesPerk>(); if (!ceraph.hasBondageFetish) { ceraph.SetStacks(2); } } else { wearer.AddPerk(new CeraphFetishesPerk(2)); } oldPiercings = wearer.breasts[0].nipplePiercings.AsReadOnlyData(); //give them horizontal nipple piercings on the first row (both sides), piercing them first if needed. Replace any existing piercings. wearer.breasts[0].nipplePiercings.EquipOrPierceAndEquip(NipplePiercingLocation.LEFT_HORIZONTAL, new CeraphNipplePiercings(), true); wearer.breasts[0].nipplePiercings.EquipOrPierceAndEquip(NipplePiercingLocation.RIGHT_HORIZONTAL, new CeraphNipplePiercings(), true); } //then silently remove the armor. wearer.RemoveArmorManual(out _); }
protected override string OnConsumeAttempt(Creature consumer, out bool consumeItem, out bool isBadEnd) { isBadEnd = false; consumeItem = true; //gives you unnaturally smooth skin. if (consumer.body.type != BodyType.HUMANOID || (consumer.body.primarySkin.skinTexture != SkinTexture.NONDESCRIPT && consumer.body.primarySkin.skinTexture != SkinTexture.SMOOTH)) { BodyData oldBodyData = consumer.body.AsReadOnlyData(); if (consumer.body.type != BodyType.HUMANOID) { consumer.UpdateBody(BodyType.HUMANOID, SkinTexture.SMOOTH); return(RestoredBodyText(consumer, oldBodyData)); } else { consumer.body.ChangeAllSkin(SkinTexture.SMOOTH); return(SkinBecameSmoothText(consumer, oldBodyData)); } } else if ((isLarge || Utils.Rand(3) == 0) && !consumer.HasPerk <RubberySkin>()) { consumer.AddPerk <RubberySkin>(); bool knewAboutBlackEggs = false; if (consumer is IExtendedCreature extended) { knewAboutBlackEggs = extended.extendedData.knowsAboutBlackEggs; extended.extendedData.knowsAboutBlackEggs = true; } consumer.DeltaCreatureStats(sens: 8, lus: 10, corr: 2); return(GainedRubberySkinPerk(consumer, knewAboutBlackEggs)); } else if (isLarge && consumer.StackPerk <RubberySkin>()) { return(StackedRubberySkinText(consumer.GetPerkData <RubberySkin>())); } else { return(NothingHappenedText(consumer.HasPerk <RubberySkin>())); } }
//MOD NOTE: this has been changed to work like bimbo liqueur - it will remove all vaginas and restore breasts to manly defaults if //the futa perk is not active. protected override string OnConsumeAttempt(Creature consumer, out bool consumeItem, out bool isBadEnd) { isBadEnd = false; StringBuilder sb = new StringBuilder(); //get our common bimbo/bro/futa perk store. Note that it may be null (if we don't have it). BimBro bimbro = consumer.GetPerkData <BimBro>(); //intro text. //first check: we don't have any bro/futa/bimbo perks, because it's not in our perk list. do the standard faire. sb.Append(Intro(consumer, bimbro)); if (bimbro?.hasBroEffect == true) { (consumer as CombatCreature)?.RecoverFatigue(33); (consumer as CombatCreature)?.AddHPPercent(1); } VaginaCollectionData oldVaginaCollection = consumer.genitals.allVaginas.AsReadOnlyData(); //get taller. only occurs if the player does not already have the bro perk in any form. if ((bimbro is null || !bimbro.broBody) && consumer.build.heightInInches < 77) { short delta = consumer.build.SetHeight(77); sb.Append(GrewTaller(consumer, delta)); } //(T**s b' gone) //Does not affect creature if they already have bimbo or futa perks. if (bimbro is null || bimbro.broBody) { //Note: minimum cup size respects current gender. we'll need to make the creature male (or genderless) first. consumer.RemoveAllVaginas(); if (consumer.genitals.BiggestCupSize() >= consumer.genitals.smallestPossibleMaleCupSize) { BreastCollectionData oldRows = consumer.genitals.allBreasts.AsReadOnlyData(); consumer.RemovePerk <Feeder>(); bool stoppedLactation = consumer.genitals.SetLactationTo(LactationStatus.NOT_LACTATING); sb.Append(ChangedBreastsText(consumer, bimbro, oldRows, stoppedLactation)); } } //Body tone Flavor text. No effect on stats (yet) sb.Append(BecomeRippedFlavorText(consumer, bimbro)); //Dick&balls growth. Affects all. //(has dick less than 10 inches) if (consumer.hasCock) { bool grewBalls = !consumer.hasBalls; bool lengthenedCock = false; if (consumer.cocks[0].length < 10) { lengthenedCock = true; consumer.cocks[0].SetLength(10); if (consumer.cocks[0].girth < 2.75) { consumer.cocks[0].SetGirth(2.75); } } if (!consumer.hasBalls) { consumer.balls.GrowBalls(2, 3); } sb.Append(LengthenedCock(consumer, bimbro, lengthenedCock, grewBalls)); } //(No dick) else { consumer.AddCock(CockType.defaultValue, 12, 2.75); bool grewBalls = false; if (!consumer.balls.hasBalls) { grewBalls = true; consumer.balls.GrowBalls(2, 3); } sb.Append(GrewCock(consumer, bimbro, grewBalls)); } //(Pussy b gone) //Note: only applies if consumer does not have bimbo or futa perks. also note that we already silently removed them so the breasts would resize correctly. //so all this does is print out the data. if ((bimbro is null || bimbro.broBody) && oldVaginaCollection.hasVagina) { sb.Append(RemovedAllVaginas(consumer, oldVaginaCollection)); } //(below max masculinity) if ((bimbro is null || bimbro.broBody) && consumer.femininity > 0) { FemininityData oldFem = consumer.femininity.AsReadOnlyData(); sb.Append(consumer.ModifyFemininity(0, 100)); sb.Append(Masculinize(consumer, bimbro is null, oldFem)); } //max tone. Thickness + 50 //both are silent. consumer.build.ChangeMuscleToneToward(100, 100); consumer.build.ChangeThicknessToward(100, 50); if (consumer.intelligence > 21) { consumer.SetIntelligence((byte)Math.Floor(Math.Max(consumer.intelligenceTrue / 5.0, 21))); } consumer.DeltaCreatureStats(str: 33, tou: 33, inte: -1, lib: 4, lus: 40); sb.Append(Outro(consumer, bimbro, consumer.perks.HasPerk <Feeder>())); //apply the perks. this will also correct any silent data we missed. if (bimbro is null) { consumer.AddPerk(new BimBro(Gender.MALE)); } else { bimbro.Broify(); } ////Bonus cum production! //sb.Append("<b>(Bro Body - Perk Gained!)" + Environment.NewLine); //sb.Append("(Bro Brains - Perk Gained!)</b>" + Environment.NewLine);//int to 20. max int 50) //if (consumer.HasPerk<Feeder>()) //{ // sb.Append("<b>(Perk Lost - Feeder!)</b>" + Environment.NewLine); // consumer.RemovePerk<Feeder>(); //} consumeItem = true; return(sb.ToString()); }
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. //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); //NOTE: THIS DOESN'T CALL GENERIC CHANGE COUNT, IDK. //libido up to 80 if (target.relativeLibido < 80) { target.DeltaCreatureStats(lib: .5 + (90 - target.libido) / 10, lus: target.libidoTrue / 2); } //sensitivity moves towards 50 if (target.relativeSensitivity < 50) { target.ChangeSensitivity(1); } else if (target.relativeSensitivity > 50) { target.ChangeSensitivity(-1); } //Cosmetic changes based on 'goopyness' //Neck restore if (target.neck.type != NeckType.HUMANOID && Utils.Rand(4) == 0) { target.RestoreNeck(); } //Rear body restore if (!target.back.isDefault && Utils.Rand(5) == 0) { target.RestoreBack(); } //Ovi perk loss 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 wings and shark fin if (target.wings.type != WingType.NONE || target.back.type == BackType.SHARK_FIN) { if (target.back.type == BackType.SHARK_FIN) { target.RestoreBack(); } WingData oldData = target.wings.AsReadOnlyData(); target.RestoreWings(); sb.Append(RestoredWingsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } if (target.hair.type != HairType.GOO) { target.UpdateHair(HairType.GOO); //if bald if (target.hair.length <= 0) { target.hair.SetHairLength(5); } if (!Species.GOO.availableHairColors.Contains(target.hair.hairColor)) { target.hair.SetHairColor(Species.GOO.GetRandomHairColor(), true); } target.ChangeLust(10); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //1.Goopy skin if (target.hair.type == HairType.GOO && target.body.type != BodyType.GOO) { if (target.arms.type != ArmType.GOO) { target.UpdateArms(ArmType.GOO); } if (!Species.GOO.availableTones.Contains(target.body.primarySkin.tone)) { target.UpdateBody(BodyType.GOO, Utils.RandomChoice(Species.GOO.availableTones)); } else { target.UpdateBody(BodyType.GOO); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } ////1a.Make alterations to dick/vaginal/nippular descriptors to match //DONE EXCEPT FOR T**S & MULTIDICKS (UNFINISHED KINDA) //2.Goo legs if (target.body.type == BodyType.GOO && target.lowerBody.type != LowerBodyType.GOO) { target.build.DecreaseHeight((byte)(3 + Utils.Rand(2))); if (target.build.heightInInches < 36) { target.build.SetHeight(36); } LowerBodyData oldData = target.lowerBody.AsReadOnlyData(); target.UpdateLowerBody(LowerBodyType.GOO); sb.Append(UpdateLowerBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //3a. Grow v****a if none if (!target.hasVagina) { target.genitals.AddVagina(VaginaType.defaultValue, 0.4, VaginalLooseness.GAPING, VaginalWetness.DROOLING); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //3b.Infinite V****a else if (!target.HasPerk <ElasticInnards>()) { target.AddPerk <ElasticInnards>(); } else if (target.build.heightInInches < 100 && Utils.Rand(3) <= 1) { target.build.IncreaseHeight(2); target.DeltaCreatureStats(str: 1, tou: 1); } //Big slime girl else if (!target.HasPerk <SlimeCraving>()) { target.AddPerk <SlimeCraving>(); } //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)); }