public string FullDescription(HairData hair, bool alternateFormat = false) { if (this == NO_HAIR || hair.length == 0) { return(NO_HAIR.LongDescription(hair, alternateFormat)); } else { byte creatureHeight = CreatureStore.GetCreatureClean(hair.creatureID)?.build.heightInInches ?? Build.DEFAULT_HEIGHT; StringBuilder sb = new StringBuilder(LengthText(hair.length, creatureHeight) + hair.hairColor.AsString()); if (hair.style != HairStyle.NO_STYLE) { sb.Append(", "); } else { sb.Append(" "); } sb.Append(StyleStr(hair.style)); sb.Append(ShortDescription()); sb.Append(HighlightStr(hair.highlightColor)); return(sb.ToString()); } }
// Make a copy of item public Item(Item other) { Id = other.Id; InventoryTab = other.InventoryTab; ItemSlot = other.ItemSlot; GemSlot = other.GemSlot; Rarity = other.Rarity; SlotMax = other.SlotMax; PlayCount = other.PlayCount; Content = other.Content; Uid = other.Uid; Slot = other.Slot; Amount = other.Amount; CreationTime = other.CreationTime; ExpiryTime = other.ExpiryTime; TimesAttributesChanged = other.TimesAttributesChanged; IsLocked = other.IsLocked; UnlockTime = other.UnlockTime; RemainingGlamorForges = other.RemainingGlamorForges; Enchants = other.Enchants; EnchantExp = other.EnchantExp; CanRepackage = other.CanRepackage; Charges = other.Charges; TransferFlag = other.TransferFlag; RemainingTrades = other.RemainingTrades; PairedCharacterId = other.PairedCharacterId; PairedCharacterName = other.PairedCharacterName; Owner = other.Owner; Color = other.Color; HairD = other.HairD; AppearanceFlag = other.AppearanceFlag; Stats = new ItemStats(other.Stats); }
protected override string RemovedBasiliskHair(Creature target, HairData oldData) { StringBuilder sb = new StringBuilder(); if (oldData.type == HairType.BASILISK_PLUME) { // TF blurb derived from losing feathery hair //(long): if (oldData.length >= 5) { sb.Append(GlobalStrings.NewParagraph() + "A lock of your feathery plume droops over your eye. Before you can blow the offending down away, " + " you realize the feather is collapsing in on itself." + " It continues to curl inward until all that remains is a normal strand of hair."); } //(short) else { sb.Append(GlobalStrings.NewParagraph() + "You run your fingers through your feathery plume while you await the effects of the item you just ingested." + " While your hand is up there, it detects a change in the texture of your feathers.They're completely disappearing," + " merging down into strands of regular hair."); } sb.Append(GlobalStrings.NewParagraph() + "<b>Your hair is no longer feathery!</b>"); } else { sb.Append(GlobalStrings.NewParagraph() + "You feel a tingling on your scalp. You reach up to your basilisk spines to find out what is happening.The moment" + " your hand touches a spine, it comes loose and falls in front of you. One after another the other spines fall out, " + " until all the spines that once decorated your head now lay around you, leaving you with a bald head."); sb.Append(GlobalStrings.NewParagraph() + "<b>You realize that you'll grow normal human hair again!</b>"); } return(sb.ToString()); }
private void Start() { if (hairData == null) { hairData = new HairData(); if (string.IsNullOrEmpty(hairData.id)) { hairData.id = System.DateTime.Now.ToLongDateString() + System.DateTime.Now.ToLongDateString() + Random.Range(0, int.MaxValue).ToString(); } } hairData.MaterialName = Data.PropMaterial(idleMaterial.name); switch (GetComponent <MeshFilter>().mesh.name.Substring(0, 4)) { case "Cube": hairData.meshType = PrimitiveType.Cube; break; case "Sphe": hairData.meshType = PrimitiveType.Sphere; break; case "Cyli": hairData.meshType = PrimitiveType.Cylinder; break; } oldPos = transform.position; collissions = new List <Collision>(); }
public string DescriptionWithColor(HairData hair, bool alternateFormat = false) { if (this == NO_HAIR || hair.length == 0) { return(BaldHeadText(alternateFormat)); } else { return(SemiTransparentString(hair.isSemiTransparent) + hair.hairColor.AsString() + " " + hair.ShortDescription()); } }
public string DescriptionWithColorAndStyle(HairData hair, bool alternateFormat = false) { if (this == NO_HAIR || hair.length == 0) { return(BaldHeadText(alternateFormat)); } else { //style str properly spaces itself if needed. so does semi transparent str. return(StyleStr(hair.style) + SemiTransparentString(hair.isSemiTransparent) + hair.hairColor.AsString() + " " + hair.ShortDescription()); } }
// Make a copy of item public Item(Item other) { Id = other.Id; Name = other.Name; Level = other.Level; Gender = other.Gender; InventoryTab = other.InventoryTab; ItemSlot = other.ItemSlot; GemSlot = other.GemSlot; Rarity = other.Rarity; StackLimit = other.StackLimit; EnableBreak = other.EnableBreak; IsTwoHand = other.IsTwoHand; IsDress = other.IsDress; IsTemplate = other.IsTemplate; IsCustomScore = other.IsCustomScore; PlayCount = other.PlayCount; FileName = other.FileName; Function = other.Function; Uid = other.Uid; Slot = other.Slot; Amount = other.Amount; CreationTime = other.CreationTime; ExpiryTime = other.ExpiryTime; TimesAttributesChanged = other.TimesAttributesChanged; IsLocked = other.IsLocked; UnlockTime = other.UnlockTime; RemainingGlamorForges = other.RemainingGlamorForges; GachaDismantleId = other.GachaDismantleId; Enchants = other.Enchants; EnchantExp = other.EnchantExp; RepackageCount = other.RepackageCount; Charges = other.Charges; TransferFlag = other.TransferFlag; RemainingTrades = other.RemainingTrades; PairedCharacterId = other.PairedCharacterId; PairedCharacterName = other.PairedCharacterName; PetSkinBadgeId = other.PetSkinBadgeId; RecommendJobs = other.RecommendJobs; OwnerCharacterId = other.OwnerCharacterId; OwnerCharacterName = other.OwnerCharacterName; InventoryId = other.InventoryId; BankInventoryId = other.BankInventoryId; BlackMarketCategory = other.BlackMarketCategory; Category = other.Category; HomeId = other.HomeId; Color = other.Color; HairData = other.HairData; HatData = other.HatData; Score = new(); Stats = new(other.Stats); UGC = other.UGC; }
//long has length, color, and highlights. protected static string GenericLongDesc(HairData hair, bool alternateFormat, string desc) { if (hair.type == NO_HAIR || hair.length == 0) { return(NO_HAIR.LongDescription(hair, alternateFormat)); } else { byte creatureHeight = CreatureStore.GetCreatureClean(hair.creatureID)?.build.heightInInches ?? Build.DEFAULT_HEIGHT; return(LengthText(hair.length, creatureHeight) + " " + hair.hairColor.AsString() + desc + HighlightStr(hair.highlightColor)); } }
public string DescriptionWithColorLengthAndStyle(HairData hair, bool alternateFormat = false) { if (this == NO_HAIR || hair.length == 0) { return(BaldHeadText(alternateFormat)); } else { byte creatureHeight = CreatureStore.GetCreatureClean(hair.creatureID)?.build.heightInInches ?? Build.DEFAULT_HEIGHT; return(LengthText(hair.length, creatureHeight) + hair.hairColor.AsString() + " " + hair.ShortDescription()); } }
protected bool ChangeHair(Creature target, StringBuilder sb) { HairData oldHair = target.hair.AsReadOnlyData(); if (target.UpdateHair(HairType.LEAF)) { //silently start hair growth again. target.hair.ResumeNaturalGrowth(); sb.Append(ChangedHairText(target, oldHair)); return(true); } return(false); }
public CharacterStyle() { Gender = 0; Parents = new ParentData(0, 0, 1.0f, 1.0f); for (int i = 0; i < Features.Length; i++) { Features[i] = 0f; } for (int i = 0; i < Appearance.Length; i++) { Appearance[i] = new AppearanceItem(255, 1.0f); } Hair = new HairData(0, 0, 0); }
public void LoadHair(string directory = "/saves", string fileName = "testHairSave.hair") { foreach (HairObject child in GetComponentsInChildren <HairObject>()) { Destroy(child.gameObject); } HeadData.current = (HeadData)Data.LoadHair(directory, fileName); List <Transform> tempTransforms = new List <Transform>(); for (int i = 0; i < HeadData.current.hairObjects.Count; i++) { HairData data = HeadData.current.hairObjects[i]; HairObject obj; if (data.MaterialName != "" && data.MaterialName != null) { obj = Instantiate(GetProp(data.MaterialName)).AddComponent <HairObject>(); obj.ToggleRigidBody(false); } else { obj = GameObject.CreatePrimitive(data.meshType).AddComponent <HairObject>(); } obj.GetComponent <MeshRenderer>().material.color = data.color; if (data.parentIndex == -1) { obj.transform.parent = head.transform; } else { obj.transform.parent = tempTransforms[data.parentIndex]; } obj.gameObject.tag = Tags.GRABABLE; obj.hairData = data; obj.transform.localScale = data.scale; obj.transform.localPosition = data.localposition; obj.transform.localRotation = data.rotation; tempTransforms.Add(obj.transform); } tempTransforms.Clear(); }
// MALE ITEMS public static Item HairMale() { return(new Item(10200003) { Uid = 2867972925711604442, CreationTime = 1565575851, Color = EquipColor.Custom( Maple2Storage.Types.Color.Argb(0xFF, 0x4C, 0x69, 0xB5), Maple2Storage.Types.Color.Argb(0xFF, 0x4C, 0x85, 0xDB), Maple2Storage.Types.Color.Argb(0xFF, 0x48, 0x5E, 0xA8), 4 ), HairD = HairData.hairData(0.3f, 0.3f, new byte[24], new byte[24]), AppearanceFlag = 2, Stats = new ItemStats(), }); }
// Make a copy of item public Item(Item other) { Id = other.Id; InventoryTab = other.InventoryTab; ItemSlot = other.ItemSlot; GemSlot = other.GemSlot; Rarity = other.Rarity; StackLimit = other.StackLimit; EnableBreak = other.EnableBreak; IsTwoHand = other.IsTwoHand; IsDress = other.IsDress; IsTemplate = other.IsTemplate; IsCustomScore = other.IsCustomScore; PlayCount = other.PlayCount; FileName = other.FileName; Content = other.Content; Function = other.Function; AdBalloon = other.AdBalloon; Uid = other.Uid; Slot = other.Slot; Amount = other.Amount; CreationTime = other.CreationTime; ExpiryTime = other.ExpiryTime; TimesAttributesChanged = other.TimesAttributesChanged; IsLocked = other.IsLocked; UnlockTime = other.UnlockTime; RemainingGlamorForges = other.RemainingGlamorForges; GachaDismantleId = other.GachaDismantleId; Enchants = other.Enchants; EnchantExp = other.EnchantExp; CanRepackage = other.CanRepackage; Charges = other.Charges; TransferFlag = other.TransferFlag; RemainingTrades = other.RemainingTrades; PairedCharacterId = other.PairedCharacterId; PairedCharacterName = other.PairedCharacterName; PetSkinBadgeId = other.PetSkinBadgeId; Owner = other.Owner; Color = other.Color; HairData = other.HairData; HatData = other.HatData; Score = new MusicScore(); Stats = new ItemStats(other.Stats); }
// Make a copy of item public Item(Item other) { Id = other.Id; InventoryTab = other.InventoryTab; ItemSlot = other.ItemSlot; GemSlot = other.GemSlot; Rarity = other.Rarity; StackLimit = other.StackLimit; EnableBreak = other.EnableBreak; IsTwoHand = other.IsTwoHand; IsDress = other.IsDress; IsTemplate = other.IsTemplate; PlayCount = other.PlayCount; FileName = other.FileName; Content = other.Content; FunctionName = other.FunctionName; FunctionId = other.FunctionId; FunctionDuration = other.FunctionDuration; FunctionFieldId = other.FunctionFieldId; FunctionCapacity = other.FunctionCapacity; FunctionTargetLevel = other.FunctionTargetLevel; Uid = other.Uid; Slot = other.Slot; Amount = other.Amount; CreationTime = other.CreationTime; ExpiryTime = other.ExpiryTime; TimesAttributesChanged = other.TimesAttributesChanged; IsLocked = other.IsLocked; UnlockTime = other.UnlockTime; RemainingGlamorForges = other.RemainingGlamorForges; Enchants = other.Enchants; EnchantExp = other.EnchantExp; CanRepackage = other.CanRepackage; Charges = other.Charges; TransferFlag = other.TransferFlag; RemainingTrades = other.RemainingTrades; PairedCharacterId = other.PairedCharacterId; PairedCharacterName = other.PairedCharacterName; Owner = other.Owner; Color = other.Color; HairD = other.HairD; AppearanceFlag = other.AppearanceFlag; Stats = new ItemStats(other.Stats); }
protected override string RemovedFeatheryHairText(Creature target, HairData oldHair) { return(RemovedFeatheryHairTextGeneric(target, true)); }
private static string WoolLongDesc(HairData hair, bool alternateFormat) { return(GenericLongDesc(hair, alternateFormat, Utils.RandomChoice("woolen hair", "poofy hair", "soft wool-hair"))); }
public void HandleCreate(LoginSession session, PacketReader packet) { byte gender = packet.ReadByte(); //packet.ReadShort(); // const? // var jobCode = (Job)packet.ReadShort(); int jobCode = packet.ReadShort(); string name = packet.ReadUnicodeString(); var skinColor = packet.Read <SkinColor>(); //packet.ReadShort(); // const? packet.Skip(2); var Equips = new Dictionary <ItemSlot, Item>(); logger.Info($"Creating character: {name}, gender: {gender}, skinColor: {skinColor}, job: {jobCode}"); int equipCount = packet.ReadByte(); for (int i = 0; i < equipCount; i++) { uint id = packet.ReadUInt(); string typeStr = packet.ReadUnicodeString(); if (!Enum.TryParse(typeStr, out ItemSlot type)) { throw new ArgumentException($"Unknown equip type: {typeStr}"); } var equipColor = packet.Read <EquipColor>(); int colorIndex = packet.ReadInt(); switch (type) { case ItemSlot.HR: // Hair // Hair Length/Position float backLength = BitConverter.ToSingle(packet.Read(4), 0); byte[] backPositionArray = packet.Read(24); float frontLength = BitConverter.ToSingle(packet.Read(4), 0); byte[] frontPositionArray = packet.Read(24); Equips.Add(ItemSlot.HR, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, HairD = HairData.hairData(backLength, frontLength, backPositionArray, frontPositionArray), Stats = new ItemStats(), IsTemplate = false, }); break; case ItemSlot.FA: // Face Equips.Add(ItemSlot.FA, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, Stats = new ItemStats(), IsTemplate = false, }); break; case ItemSlot.FD: // Face Decoration byte[] faceDecoration = packet.Read(16); // Face decoration position Equips.Add(ItemSlot.FD, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, FaceDecorationD = faceDecoration, Stats = new ItemStats(), IsTemplate = false, }); break; case ItemSlot.CL: // Clothes Equips.Add(ItemSlot.CL, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, Stats = new ItemStats(), IsTemplate = false, }); break; case ItemSlot.PA: // Pants Equips.Add(ItemSlot.PA, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, Stats = new ItemStats(), IsTemplate = false, }); break; case ItemSlot.SH: // Shoes Equips.Add(ItemSlot.SH, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, Stats = new ItemStats(), IsTemplate = false, }); break; case ItemSlot.ER: // Ear // Assign ER Equips.Add(ItemSlot.ER, new Item(Convert.ToInt32(id)) { CreationTime = 1565575851, Color = equipColor, Stats = new ItemStats(), IsTemplate = false, }); break; } logger.Info($" > {type} - id: {id}, color: {equipColor}, colorIndex: {colorIndex}"); } packet.ReadInt(); // const? (4) // Check if name is in use (currently just on local account) bool taken = false; foreach (var character in AccountStorage.Characters.Values) { if (character.Name.ToLower().Equals(name.ToLower())) { taken = true; } } if (taken) { session.Send(ResponseCharCreatePacket.NameTaken()); return; } // Create new player object Player newCharacter = Player.NewCharacter(gender, jobCode, name, skinColor, Equips); // Add player object to account storage AccountStorage.AddCharacter(newCharacter); // Send updated CHAR_MAX_COUNT session.Send(CharacterListPacket.SetMax(4, 6)); // Send CHARACTER_LIST for new character only (append) session.Send(CharacterListPacket.AppendEntry(newCharacter)); }
private static string WoolTransformStr(HairData hair, PlayerBase player) { throw new InDevelopmentExceptionThatBreaksOnRelease(); }
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); //Corruption reduction if (isPure) { //Special honey will also reduce corruption, but uses different text and is handled separately target.ChangeCorruption(-(1 + (target.corruptionTrue / 20))); //Libido Reduction if (target.corruption > 0 && Utils.Rand(3) < 2 && target.relativeLibido > 40) { target.DeltaCreatureStats(lib: -3, lus: -20); } } //Intelligence Boost if (Utils.Rand(2) == 0 && target.relativeIntelligence < 80) { target.IncreaseIntelligence(0.1 * (80 - target.relativeIntelligence)); } //bee item corollary: if (target.hair.type == HairType.ANEMONE && Utils.Rand(2) == 0) { HairData oldData = target.hair.AsReadOnlyData(); target.RestoreHair(); sb.Append(RestoredHairText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Sexual Stuff //No idears //Appearance Stuff //Hair Color if (target.hair.hairColor != HairFurColors.BLACK && target.hair.length > 10 && Utils.Rand(5) == 0) { if (Utils.Rand(9) == 0) { target.hair.SetBothHairColors(HairFurColors.BLACK, HairFurColors.YELLOW); } else { target.hair.SetHairColor(HairFurColors.BLACK); } if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Hair Length if (target.hair.length < 25 && target.hair.type.canLengthen && Utils.Rand(3) == 0) { target.hair.GrowHair(Utils.Rand(4) + 1); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Remove extra breast rows if (target.breasts.Count > 2 && Utils.Rand(3) == 0 && !hyperHappy) { target.genitals.RemoveBreastRows(); } //Antennae if (target.antennae.type == AntennaeType.NONE && target.horns.numHorns == 0 && Utils.Rand(3) == 0) { AntennaeData oldData = target.antennae.AsReadOnlyData(); target.UpdateAntennae(AntennaeType.BEE); sb.Append(UpdateAntennaeText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Horns if (!target.horns.isDefault && Utils.Rand(3) == 0) { HornData oldData = target.horns.AsReadOnlyData(); target.RestoreHorns(); sb.Append(RestoredHornsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Bee Legs if (target.lowerBody.type != LowerBodyType.BEE && Utils.Rand(4) == 0) { LowerBodyData oldData = target.lowerBody.AsReadOnlyData(); target.UpdateLowerBody(LowerBodyType.BEE); sb.Append(UpdateLowerBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //(Arms to carapace-covered arms) if (target.arms.type != ArmType.BEE && Utils.Rand(4) == 0) { ArmData oldData = target.arms.AsReadOnlyData(); target.UpdateArms(ArmType.BEE); sb.Append(UpdateArmsText(target, oldData)); 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)); } } //Neck restore if (!target.neck.isDefault && 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)); } } //Lose reptile oviposition! if (target.womb.canRemoveOviposition && Utils.Rand(5) == 0) { target.womb.ClearOviposition(); sb.Append(ClearOvipositionText(target)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Gain bee ovipositor! if (target.tail.type == TailType.BEE_STINGER && !target.tail.hasOvipositor && Utils.Rand(2) == 0) { target.tail.GrantOvipositor(); } //Bee butt - 66% lower chance if already has a tail if (target.tail.type != TailType.BEE_STINGER && (target.tail.type == TailType.NONE || Utils.Rand(3) < 2) && Utils.Rand(4) == 0) { target.UpdateTail(TailType.BEE_STINGER); target.tail.UpdateResources((short)(10 - target.tail.resources), (short)(2 - target.tail.regenRate)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Venom Increase if (target.tail.type == TailType.BEE_STINGER && target.tail.regenRate < 15 && Utils.Rand(2) == 0) { short additionalRegen = 1; if (target.tail.regenRate < 5) { additionalRegen = 3; } else if (target.tail.regenRate < 10) { additionalRegen = 2; } target.tail.UpdateResources(50, additionalRegen); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Wings //Grow bigger bee wings! if (target.wings.type == WingType.BEE_LIKE && !target.wings.isLarge && Utils.Rand(4) == 0) { target.wings.GrowLarge(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Grow new bee wings if target has none. if (target.wings.type == WingType.NONE && Utils.Rand(4) == 0) { if (target.back.type == BackType.SHARK_FIN) { target.RestoreBack(); } WingData oldData = target.wings.AsReadOnlyData(); target.UpdateWings(WingType.BEE_LIKE); sb.Append(UpdateWingsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Melt demon wings! if (target.wings.type == WingType.BAT_LIKE) { WingData oldData = target.wings.AsReadOnlyData(); target.RestoreWings(); sb.Append(RestoredWingsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove 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)); } } //All the speical honey effects occur after any normal bee transformations (if the target wasn't a full bee morph) if (isSpecial) { //if no c**k: grow one. if (!target.hasCock) { target.genitals.AddCock(CockType.defaultValue, Utils.Rand(3) + 8, 2); target.HaveGenericCockOrgasm(0, false, true); target.ChangeSensitivity(10); } //if multiple cocks, remove the largest c**k by area. combine its length/girth into the first c**k. else if (target.cocks.Count > 1) { //find the biggest c**k that isn't the first one. C**k biggest = target.cocks.Skip(1).MaxItem(x => x.area); double delta = (double)(5 * Math.Sqrt(0.2 * biggest.area)); target.cocks[0].DeltaLengthAndGirth(delta, delta); target.HaveGenericCockOrgasm(0, false, true); } //one c**k. grow it to 100 area total or larger else if (target.cocks[0].area < 100) { target.cocks[0].DeltaLengthAndGirth(Utils.Rand(3) + 4, 0.1 * Utils.Rand(5) + 0.5); } // else { double baseLengthChange; double baseGirthChange; if (target.cocks[0].type != CockType.BEE && Species.CurrentSpecies(target) == Species.BEE) { target.genitals.UpdateCock(0, CockType.BEE); target.ChangeSensitivity(15); baseLengthChange = 5; baseGirthChange = 1; } else { baseLengthChange = 0.1 * Utils.Rand(10) + 1; baseGirthChange = 0.1 * Utils.Rand(2) + 1; } double mult; C**k c**k = target.cocks[0]; if (c**k.area >= 400) { mult = 0; //C**k stops growing at that point. } else if (c**k.area >= 300) { mult = 0.1; } if (c**k.area > 100) { int offset = (((int)c**k.area) - 100) / 40; mult = 1 - 0.2 * offset; } else { mult = 1; } double deltaLength = (double)(mult * baseLengthChange); double deltaGirth = (double)(mult * baseGirthChange); target.cocks[0].DeltaLengthAndGirth(deltaLength, deltaGirth); } if (target.corruption >= 5) { double corrLoss = Math.Min(0.1 * target.corruptionTrue + 5, target.corruptionTrue); target.DeltaCreatureStats(corr: -corrLoss, lib: corrLoss); //Lose corruption and gains that much libido } else { target.ChangeLibido(5); } if (target.femininity >= 60 || target.femininity <= 40) { if (target.femininity >= 60) { target.femininity.IncreaseMasculinity(3); } else { target.femininity.IncreaseFemininity(3); } } target.ChangeLust(0.2 * target.libidoTrue + 5); } //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)); }
protected virtual string RestoredHairText(Creature target, HairData oldData) { return(target.hair.RestoredText(oldData)); }
protected abstract string RemovedFeatheryHairText(Creature target, HairData oldHair);
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)); }
private static string VineLongDesc(HairData hair, bool alternateFormat) { return(GenericLongDesc(hair, alternateFormat, Utils.RandomChoice("leafy hair", "grassy hair", "pine needle hair", "hair-like vines", "leafy vines for hair"))); }
private static string VineRestoreStr(HairData hair, PlayerBase player) { throw new InDevelopmentExceptionThatBreaksOnRelease(); }
protected internal override string DoTransformation(Creature target, out bool isBadEnd) { isBadEnd = false; int changeCount = GenerateChangeCount(target, new int[] { 2, 2, 3, 4 }); int remainingChanges = changeCount; StringBuilder sb = new StringBuilder(); #warning fix me int ngPlus(int value) => value; int currentChanges() => changeCount - remainingChanges; //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); //clear screen //Statistical changes: //-Reduces speed down to 50. if (target.speed > ngPlus(50) && Utils.Rand(4) == 0) { target.ChangeSpeed(-1); } //-Raises toughness to 70 //(+3 to 40, +2 to 55, +1 to 70) if (target.toughness < ngPlus(70) && Utils.Rand(3) == 0) { //(+3) if (target.toughness < ngPlus(40)) { target.ChangeToughness(3); } //(+2) else if (target.toughness < ngPlus(55)) { target.ChangeToughness(2); } //(+1) else { target.ChangeToughness(1); } } //-Reduces sensitivity. if (target.relativeSensitivity > 20 && Utils.Rand(3) == 0) { target.ChangeSensitivity(-1); } //Raises libido greatly to 50, then somewhat to 75, then slowly to 100. if (target.relativeLibido < 100 && Utils.Rand(3) == 0) { //+3 lib if less than 50 if (target.relativeLibido < 50) { target.ChangeLibido(1); } //+2 lib if less than 75 if (target.relativeLibido < 75) { target.ChangeLibido(1); } //+1 if above 75. target.ChangeLibido(1); } //Sexual Changes: //-Lizard dick - first one if (target.cocks.Any(x => x.type != CockType.LIZARD) && target.cocks.Count > 0 && ScalingChance(2, currentChanges(), 4)) { //Find the first non-lizzy dick C**k firstNonLizard = target.cocks.First(x => x.type != CockType.LIZARD); //Actually xform it nau target.genitals.UpdateCock(firstNonLizard, CockType.LIZARD); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } target.DeltaCreatureStats(lib: 3, lus: 10); } //(CHANGE OTHER DICK) int lizardCocks = target.genitals.CountCocksOfType(CockType.LIZARD); //Requires 1 lizard c**k, multiple cocks if (target.hasCock && (lizardCocks != target.cocks.Count || target.cocks.Count == 1) && ScalingChance(2, currentChanges(), 4)) { if (target.cocks.Count > 1) { C**k nonLizard = target.cocks.First(x => x.type != CockType.LIZARD); target.genitals.UpdateCock(nonLizard, CockType.LIZARD); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } target.DeltaCreatureStats(lib: 3, lus: 10); } else { target.genitals.AddCock(CockType.LIZARD, target.cocks[0].length, target.cocks[0].girth); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } target.DeltaCreatureStats(lib: 3, lus: 10); } } //MOD NOTE: REMOVED. SEE RANT IN SALAMANDER TRANSFORMATIONS //--Worms leave if 100% lizard dicks? //Require mammals? //if (target.genitals.CountCocksOfType(CockType.LIZARD) == target.cocks.Count && target.hasStatusEffect(StatusEffects.Infested)) //{ // target.removeStatusEffect(StatusEffects.Infested); // if (--remainingChanges <= 0) // { // return ApplyChangesAndReturn(target, sb, changeCount - remainingChanges); // } //} //-Breasts vanish to 0 rating if male if (target.genitals.BiggestCupSize() > target.genitals.smallestPossibleMaleCupSize && target.gender == Gender.MALE && ScalingChance(2, currentChanges(), 3)) { //(HUEG) foreach (Breasts breast in target.breasts) { if (breast.cupSize > CupSize.E_BIG) { breast.ShrinkBreasts(((byte)breast.cupSize).div(2)); } else { breast.SetCupSize(target.genitals.smallestPossibleMaleCupSize); } } //(+2 speed) target.IncreaseSpeed(2); target.ChangeLibido(2); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Lactation stoppage. if (target.genitals.isLactating && ScalingChance(2, currentChanges(), 4)) { 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 && ScalingChance(2, currentChanges(), 4)) { target.genitals.SetQuadNipples(false); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Remove extra breast rows if (target.breasts.Count > 1 && ScalingChance(2, currentChanges(), 3) && !hyperHappy) { target.RemoveExtraBreastRows(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-VAGs if (target.hasVagina && target.womb.canObtainOviposition && Species.LIZARD.Score(target) > 3 && ScalingChance(3, currentChanges(), 5)) { target.womb.GrantOviposition(); sb.Append(GrantOvipositionText(target)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Physical changes: //-Existing horns become draconic, max of 4, max length of 1' if (target.horns.type != HornType.DRACONIC && ScalingChance(3, currentChanges(), 5)) { HornData oldData = target.horns.AsReadOnlyData(); target.UpdateHorns(HornType.DRACONIC); sb.Append(UpdateHornsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Neck restore if (target.neck.type != NeckType.HUMANOID && ScalingChance(2, currentChanges(), 4)) { 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 && ScalingChance(3, currentChanges(), 5)) { BackData oldData = target.back.AsReadOnlyData(); target.RestoreBack(); sb.Append(RestoredBackText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Hair changes if (ScalingChance(2, currentChanges(), 4)) { if (target.eyes.type == EyeType.BASILISK) { if (target.corruption > 65 && target.face.IsReptilian() && target.body.type == BodyType.REPTILE && target.hair.type != HairType.BASILISK_SPINES) { HairData oldData = target.hair.AsReadOnlyData(); target.UpdateHair(HairType.BASILISK_SPINES); sb.Append(UpdateHairText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } else if (target.corruption < 15 && target.gender.HasFlag(Gender.FEMALE) && target.hair.type != HairType.BASILISK_PLUME) { target.hair.ResumeNaturalGrowth(); HairData oldData = target.hair.AsReadOnlyData(); target.UpdateHair(HairType.BASILISK_PLUME); sb.Append(UpdateHairText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } } else { target.hair.StopNaturalGrowth(); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } } //Remove beard! #warning BEARDS NOT YET IMPLEMENTED //Mod note: Nords are so serious about beards. ... Mai'q thinks they wish they had GLORIOUS pubes like Khajiit. //if (target.hasBeard() && ScalingChance(2, currentChanges(), 3)) //{ // target.beard.length = 0; // target.beard.style = 0; //} //Big physical changes: //-Legs – Draconic, clawed feet if (target.lowerBody.type != LowerBodyType.LIZARD && ScalingChance(3, currentChanges(), 5)) { //Hooves - //TAURS - //feet types - //Else – LowerBodyData oldData = target.lowerBody.AsReadOnlyData(); target.UpdateLowerBody(LowerBodyType.LIZARD); sb.Append(UpdateLowerBodyText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } // <mod name="Predator arms" author="Stadler76"> //Gain predator arms //Claw transition //MOD OF MOD (LOL): predator arms are a collection of arm types now, not a single type. thus, we can combine the claw and type checks. //now, you get the arms (and thus, the claws) if they aren't a predator type and have lizard legs, or switch to lizard arms from any other predator type. if ((target.arms.IsPredatorArms() || target.lowerBody.type == LowerBodyType.LIZARD) && target.body.type == BodyType.REPTILE && ScalingChance(2, currentChanges(), 3)) { ArmData oldData = target.arms.AsReadOnlyData(); target.UpdateArms(ArmType.LIZARD); sb.Append(UpdateArmsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } // </mod> //-Tail – sinuous lizard tail if (target.tail.type != TailType.LIZARD && target.lowerBody.type == LowerBodyType.LIZARD && ScalingChance(3, currentChanges(), 5)) { //No tail //Yes tail TailData oldData = target.tail.AsReadOnlyData(); target.UpdateTail(TailType.LIZARD); sb.Append(UpdateTailText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //Remove odd eyes if (ScalingChance(3, currentChanges(), 5) && target.eyes.type != EyeType.HUMAN && !target.eyes.isReptilian) { EyeData oldData = target.eyes.AsReadOnlyData(); target.RestoreEyes(); sb.Append(RestoredEyesText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Ears become smaller nub-like openings? if (target.ears.type != EarType.LIZARD && target.tail.type == TailType.LIZARD && target.lowerBody.type == LowerBodyType.LIZARD && ScalingChance(3, currentChanges(), 5)) { EarData oldData = target.ears.AsReadOnlyData(); target.UpdateEars(EarType.LIZARD); sb.Append(UpdateEarsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Scales – color changes to red, green, white, blue, or black. Rarely: purple or silver. if (target.body.type != BodyType.REPTILE && target.ears.type == EarType.LIZARD && target.tail.type == TailType.LIZARD && target.lowerBody.type == LowerBodyType.LIZARD && ScalingChance(3, currentChanges(), 5)) { Species.LIZARD.GetRandomSkinTone(out Tones primary, out Tones underbody); target.UpdateBody(BodyType.REPTILE, primary, underbody); //kGAMECLASS.rathazul.addMixologyXP(20); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Lizard-like face. if (target.face.type != FaceType.LIZARD && target.body.type == BodyType.REPTILE && target.ears.type == EarType.LIZARD && target.tail.type == TailType.LIZARD && target.lowerBody.type == LowerBodyType.LIZARD && ScalingChance(3, currentChanges(), 5)) { FaceData oldData = target.face.AsReadOnlyData(); target.UpdateFace(FaceType.LIZARD); sb.Append(UpdateFaceText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Lizard tongue if (target.tongue.type == TongueType.SNAKE && Utils.Rand(10) < 6) { // Higher (60%) chance to be 'fixed' if old variant TongueData oldData = target.tongue.AsReadOnlyData(); target.UpdateTongue(TongueType.LIZARD); sb.Append(UpdateTongueText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } if (target.tongue.type != TongueType.LIZARD && target.tongue.type != TongueType.SNAKE && target.face.IsReptilian() && ScalingChance(2, currentChanges(), 3)) { TongueData oldData = target.tongue.AsReadOnlyData(); target.UpdateTongue(TongueType.LIZARD); sb.Append(UpdateTongueText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //-Remove Gills if (ScalingChance(2, currentChanges(), 4) && !target.gills.isDefault) { GillData oldData = target.gills.AsReadOnlyData(); target.RestoreGills(); sb.Append(RestoredGillsText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //<mod name="Reptile eyes" author="Stadler76"> //-Lizard eyes if (target.eyes.type != EyeType.LIZARD && target.face.type == FaceType.LIZARD && target.body.type == BodyType.REPTILE && target.ears.type == EarType.LIZARD && ScalingChance(2, currentChanges(), 4)) { EyeData oldData = target.eyes.AsReadOnlyData(); target.UpdateEyes(EyeType.LIZARD); sb.Append(UpdateEyesText(target, oldData)); if (--remainingChanges <= 0) { return(ApplyChangesAndReturn(target, sb, changeCount - remainingChanges)); } } //</mod> //FAILSAFE CHANGE if (remainingChanges == changeCount) { (target as CombatCreature)?.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)); }
protected virtual string UpdateHairText(Creature target, HairData oldData) { return(target.hair.TransformFromText(oldData)); }
private void loadCharacterCustomization() { charCustomData = JsonMapper.ToObject(File.ReadAllText(Application.dataPath + "/StreamingAssets/PlayerCustomization.json")); BodyPartsSprite bps = GameManager.instance.playerMovement.bodyPartsSprite; BodyTypeData bodyType = CharCustomManager.instance.GetBodyTypeDataById(charCustomData["bodyTypeId"].ToString()); EyebrowsData eyebrows = CharCustomManager.instance.GetEyebrowsDataById(charCustomData["eyebrowsId"].ToString()); EyesData eyes = CharCustomManager.instance.GetEyesDataById(charCustomData["eyesId"].ToString()); HairData hair = CharCustomManager.instance.GetHairDataById(charCustomData["hairId"].ToString()); MouthData mouth = CharCustomManager.instance.GetMouthDataById(charCustomData["mouthId"].ToString()); PantsData pants = CharCustomManager.instance.GetPantsDataById(charCustomData["pantsId"].ToString()); ShirtData shirt = CharCustomManager.instance.GetShirtDataById(charCustomData["shirtId"].ToString()); ShoesData shoes = CharCustomManager.instance.GetShoesDataById(charCustomData["shoesId"].ToString()); bps.southHead.sprite = bodyType.frontHead; bps.southHair.sprite = hair.frontHair; bps.southLeftEye.sprite = eyes.frontEye; bps.southRightEye.sprite = eyes.frontEye; bps.southLeftEyebrow.sprite = eyebrows.eyebrow; bps.southRightEyebrow.sprite = eyebrows.eyebrow; bps.southMouth.sprite = mouth.frontMouth; bps.southLeftLeg.sprite = bodyType.leg; bps.southLeftPants.sprite = pants.pants; bps.southLeftShoes.sprite = shoes.frontShoes; bps.southRightLeg.sprite = bodyType.leg; bps.southRightPants.sprite = pants.pants; bps.southRightShoes.sprite = shoes.frontShoes; bps.southChest.sprite = bodyType.frontChest; bps.southShirt.sprite = shirt.frontShirt; bps.southLeftArm.sprite = bodyType.arm; bps.southLeftSleeve.sprite = shirt.frontSleeve; bps.southRightArm.sprite = bodyType.arm; bps.southRightSleeve.sprite = shirt.frontSleeve; bps.northHead.sprite = bodyType.frontHead; bps.northHair.sprite = hair.backHair; bps.northLeftLeg.sprite = bodyType.leg; bps.northLeftPants.sprite = pants.pants; bps.northLeftShoes.sprite = shoes.backShoes; bps.northRightLeg.sprite = bodyType.leg; bps.northRightPants.sprite = pants.pants; bps.northRightShoes.sprite = shoes.backShoes; bps.northChest.sprite = bodyType.frontChest; bps.northShirt.sprite = shirt.backShirt; bps.northLeftArm.sprite = bodyType.arm; bps.northLeftSleeve.sprite = shirt.frontSleeve; bps.northRightArm.sprite = bodyType.arm; bps.northRightSleeve.sprite = shirt.frontSleeve; bps.eastHead.sprite = bodyType.sideHead; bps.eastHair.sprite = hair.sideHair; bps.eastEye.sprite = eyes.sideEye; bps.eastEyebrow.sprite = eyebrows.eyebrow; bps.eastMouth.sprite = mouth.sideMouth; bps.eastLeftLeg.sprite = bodyType.leg; bps.eastLeftPants.sprite = pants.pants; bps.eastLeftShoes.sprite = shoes.sideShoes; bps.eastRightLeg.sprite = bodyType.leg; bps.eastRightPants.sprite = pants.pants; bps.eastRightShoes.sprite = shoes.sideShoes; bps.eastChest.sprite = bodyType.sideChest; bps.eastShirt.sprite = shirt.sideShirt; bps.eastLeftArm.sprite = bodyType.arm; bps.eastLeftSleeve.sprite = shirt.sideSleeve; bps.eastRightArm.sprite = bodyType.arm; bps.eastRightSleeve.sprite = shirt.sideSleeve; bps.westHead.sprite = bodyType.sideHead; bps.westHair.sprite = hair.sideHair; bps.westEye.sprite = eyes.sideEye; bps.westEyebrow.sprite = eyebrows.eyebrow; bps.westMouth.sprite = mouth.sideMouth; bps.westLeftLeg.sprite = bodyType.leg; bps.westLeftPants.sprite = pants.pants; bps.westLeftShoes.sprite = shoes.sideShoes; bps.westRightLeg.sprite = bodyType.leg; bps.westRightPants.sprite = pants.pants; bps.westRightShoes.sprite = shoes.sideShoes; bps.westChest.sprite = bodyType.sideChest; bps.westShirt.sprite = shirt.sideShirt; bps.westLeftArm.sprite = bodyType.arm; bps.westLeftSleeve.sprite = shirt.sideSleeve; bps.westRightArm.sprite = bodyType.arm; bps.westRightSleeve.sprite = shirt.sideSleeve; }
private static string HairChangedText(Creature target, HairData oldHairData) { return(GlobalStrings.NewParagraph() + "Your hair suddenly begins to shed, rapidly falling down around you before it's all completely gone. " + "Just when you think things are over, more hair sprouts from your head, slightly curled and colored differently." + SafelyFormattedString.FormattedText("You now have " + (oldHairData.type != HairType.NORMAL ? "normal, " : "") + target.hair.LongDescription() + "!", StringFormats.BOLD)); }
protected override string ChangedHairText(Creature target, HairData oldHair) { return("Much to your shock, your hair begins falling out in tuffs onto the ground. Moments later, " + "your scalp sprouts vines all about that extend down and bloom into leafy hair."); }