diff --git a/README.md b/README.md index ea1b5f5..dda15f4 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ The Original Author is u/Primeval_Titmouse, who has long since deleted his reddi - u/BabyKunoichi - u/abdlnikki - u/FurryDestiny +- u/Proximitron ### Thanks to alpha testers: - u/zombiekarasu @@ -29,6 +30,7 @@ Follow instructions provided by the individual prerequisite mods and programs. - Stardew Valley (version 1.6.14) - [SMAPI](https://smapi.io/) (version 4.1.8) - [Content Patcher](https://www.nexusmods.com/stardewvalley/mods/1915?tab=files) (version 2.4.4) +- [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098?tab=files) Highly recommended: (Allowes ingame configuration of the mod) ### Installation 1) Download the [latest release](https://github.com/zippity21/Stardew_Valley_Regression_Mod/releases). Be careful that you don't download the source code. The release is the one that contains Regression.dll. @@ -48,17 +50,13 @@ Follow instructions provided by the individual prerequisite mods and programs. - F5: Check State of Underwear - F6: Check State of Pants - F7: Check State of Potty Training -- F9: Toggle Debug Mode +- F8: Check Potty Feeling - Left Shift + F1: Pull down pants and attempt to pee. - Left Shift + F2: Pull down pants and attempt to poop. - Left Shift + Left Click: Drink when near water source or holding watering can. - Note, the following locations have toilets (use you imagination, there is no icon/sprite). Pulling down your pants anywhere else will result in you going on the floor (*gross*). - House - - Hospital - - Club - - Joja-Mart - - Movie Theater - - Saloon + - Island House - Bathhouse Locker-room ### In Debug diff --git a/Regression.sln b/Regression.sln index f1877ae..0e26671 100644 --- a/Regression.sln +++ b/Regression.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34728.123 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Regression", "Regression\Regression.csproj", "{65F7FD12-03C5-440C-9F47-2A86A25362DA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Regression", "Regression\Regression.csproj", "{65F7FD12-03C5-440C-9F47-2A86A25362DA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Regression/Assets/peePoop.xcf b/Regression/Assets/peePoop.xcf new file mode 100644 index 0000000..88ff949 Binary files /dev/null and b/Regression/Assets/peePoop.xcf differ diff --git a/Regression/Assets/peePoop_s.xcf b/Regression/Assets/peePoop_s.xcf new file mode 100644 index 0000000..8c14c0a Binary files /dev/null and b/Regression/Assets/peePoop_s.xcf differ diff --git a/Regression/Assets/pee_poop.png b/Regression/Assets/pee_poop.png new file mode 100644 index 0000000..f6c1d7f Binary files /dev/null and b/Regression/Assets/pee_poop.png differ diff --git a/Regression/PrimevalTitmouse/Animations.cs b/Regression/PrimevalTitmouse/Animations.cs index 65d6979..b1b6d3a 100644 --- a/Regression/PrimevalTitmouse/Animations.cs +++ b/Regression/PrimevalTitmouse/Animations.cs @@ -3,14 +3,17 @@ using StardewModdingAPI; using StardewValley; using StardewValley.Characters; +using StardewValley.GameData.Characters; using StardewValley.Menus; using StardewValley.TerrainFeatures; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; +using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; namespace PrimevalTitmouse @@ -29,46 +32,44 @@ public enum FullnessType internal static class Animations { // Adding Leo here as a quick fix to a softlock issue due to not having ABDL dialogue written - private static readonly List NPC_LIST = new List { "Linus", "Krobus", "Dwarf", "Leo" }; + //private static readonly List NPC_LIST = new List { "Linus", "Krobus", "Dwarf", "Leo" }; public static readonly int poopAnimationTime = 2000; //ms public static readonly int peeAnimationTime = 2000; //ms //Magic Constants public const string SPRITES = "Assets/sprites.png"; + public const string PEE_POOP_ICON = "Assets/pee_poop.png"; public const int PAUSE_TIME = 20000; public const float DRINK_ANIMATION_INTERVAL = 80f; public const int DRINK_ANIMATION_FRAMES = 8; public const int LARGE_SPRITE_DIM = 64; public const int SMALL_SPRITE_DIM = 16; - public const int DIAPER_HUD_DIM = 64; + public const int DIAPER_HUD_DIM = 64; enum FaceDirection : int { - Down = 2, - Left = 1, + Down = 2, + Left = 1, Right = 3, - Up = 0 + Up = 0 }; - public static Texture2D sprites; - private static Data t; - private static Farmer who; - - //Static Accessor Methods. Ensure that variables are initialized. - public static Data GetData() - { - t ??= Regression.t; - return t; - } - public static Texture2D GetSprites() - { - sprites ??= Regression.help.ModContent.Load(SPRITES); - return sprites; + private static Texture2D _sprites; + public static Texture2D sprites { + get { + _sprites ??= Regression.help.ModContent.Load(SPRITES); + return _sprites; + } } - - public static Farmer GetWho() + private static Texture2D _peepoopSprites; + public static Texture2D peepoopSprites { - Animations.who ??= Game1.player; - return who; + get + { + _peepoopSprites ??= Regression.help.ModContent.Load(PEE_POOP_ICON); + return _peepoopSprites; + } } + public static Data Data => Regression.t; + public static Farmer player => Game1.player; public static float ZoomScale() { @@ -78,42 +79,42 @@ public static float ZoomScale() public static void AnimateDrinking(bool waterSource = false) { //If we aren't facing downward, turn - if (Animations.GetWho().getFacingDirection() != (int)FaceDirection.Down) - Animations.GetWho().faceDirection((int)FaceDirection.Down); + if (player.getFacingDirection() != (int)FaceDirection.Down) + player.faceDirection((int)FaceDirection.Down); + //Stop doing anything that would prevent us from moving //Essentially take control of the variable - Animations.GetWho().forceCanMove(); + player.forceCanMove(); + //Stop any form of animation - Animations.GetWho().completelyStopAnimatingOrDoingAction(); + player.completelyStopAnimatingOrDoingAction(); + // ISSUE: method pointer //Start Drinking animation. While drinking pause time and don't allow movement. - Animations.GetWho().FarmerSprite.animateOnce(StardewValley.FarmerSprite.drink, DRINK_ANIMATION_INTERVAL, DRINK_ANIMATION_FRAMES, new AnimatedSprite.endOfAnimationBehavior(EndDrinking)); - Animations.GetWho().freezePause = PAUSE_TIME; - Animations.GetWho().canMove = false; + player.FarmerSprite.animateOnce(FarmerSprite.drink, DRINK_ANIMATION_INTERVAL, DRINK_ANIMATION_FRAMES, new AnimatedSprite.endOfAnimationBehavior(EndDrinking)); + player.freezePause = PAUSE_TIME; + player.canMove = false; //If we drink from the watering can, don't say anything if (!waterSource) return; //Otherwise say something about it - Say(Animations.GetData().Drink_Water_Source, null); + Say(Data.Drink_Water_Source, null); } //Not really an animation. Just say the bedding's current state. public static void AnimateDryingBedding(Body b) { - Write(Animations.GetData().Bedding_Still_Wet, b); + Write(Data.Bedding_Still_Wet, b); } public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) { - - if (b.IsFishing() || !Animations.GetWho().canMove) return; - if (b.underwear.removable || inUnderwear) Game1.playSound("slosh"); @@ -122,271 +123,403 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) if (!(b.underwear.removable || inUnderwear)) { - Animations.Say(Animations.GetData().Cant_Remove, b); + Say(Data.Cant_Remove, b); return; } if (!inUnderwear) { if (b.InToilet(inUnderwear)) - Say(Animations.GetData().Poop_Toilet, b); + Say(Data.Poop_Toilet, b); else - Say(Animations.GetData().Poop_Voluntary, b); + Say(Data.Poop_Voluntary, b); } else if (voluntary) - Say(Animations.GetData().Mess_Voluntary, b); + Say(Data.Mess_Voluntary, b); else - Say(Animations.GetData().Mess_Accident, b); + Say(Data.Mess_Accident, b); + + + player.doEmote(12, false); + if (Body.IsFishing() || !player.canMove) return; // We skip the actual animations if nessesary - //Animations.GetWho().forceCanMove(); - //Animations.GetWho().completelyStopAnimatingOrDoingAction(); - Animations.GetWho().jitterStrength = 1.0f; - Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("TileSheets\\animations", new Microsoft.Xna.Framework.Rectangle(192, 1152, Game1.tileSize, Game1.tileSize), 50f, 4, 0, Animations.GetWho().position.Value - new Vector2(((Character)Animations.GetWho()).facingDirection.Value == 1 ? 0.0f : (float)-Game1.tileSize, (float)(Game1.tileSize * 2)), false, ((Character)Animations.GetWho()).facingDirection.Value == 1, (float)((Character)Animations.GetWho()).StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); + player.jitterStrength = 1.0f; + Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("TileSheets\\animations", new Microsoft.Xna.Framework.Rectangle(192, 1152, Game1.tileSize, Game1.tileSize), 50f, 4, 0, player.position.Value - new Vector2(((Character)player).facingDirection.Value == 1 ? 0.0f : (float)-Game1.tileSize, (float)(Game1.tileSize * 2)), false, ((Character)player).facingDirection.Value == 1, (float)((Character)player).StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); - Animations.GetWho().freezePause = poopAnimationTime; - Animations.GetWho().canMove = false; - Animations.GetWho().doEmote(12, false); + player.freezePause = poopAnimationTime; + player.canMove = false; } - public static void AnimateMessingEnd(Body b) + public static void AnimateMessingEnd(Character target) { - if (b.IsFishing()) return; + if (Body.IsFishing()) return; Game1.playSound("coin"); - Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("TileSheets\\animations", new Microsoft.Xna.Framework.Rectangle(192, 1152, Game1.tileSize, Game1.tileSize), 50f, 4, 0, Animations.GetWho().position.Value - new Vector2(Animations.GetWho().facingDirection.Value == 1 ? 0.0f : -Game1.tileSize, Game1.tileSize * 2), false, Animations.GetWho().facingDirection.Value == 1, Animations.GetWho().StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); + Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("TileSheets\\animations", new Microsoft.Xna.Framework.Rectangle(192, 1152, Game1.tileSize, Game1.tileSize), 50f, 4, 0, target.position.Value - new Vector2(target.facingDirection.Value == 1 ? 0.0f : -Game1.tileSize, Game1.tileSize * 2), false, target.facingDirection.Value == 1, target.StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); + } + public static void AnimateMessingMinor(Body b) + { + Say(Data.Bowels_Leak, b); + ((Character)player).doEmote(12, false); } public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) { - if (b.IsFishing() || !Animations.GetWho().canMove) return; - - if(b.underwear.removable || inUnderwear) - Game1.playSound("wateringCan"); + if (b.underwear.removable || inUnderwear) + Game1.playSound("wateringCan"); if (b.isSleeping || !voluntary && !Regression.config.AlwaysNoticeAccidents && (double)b.bladderContinence + 0.200000002980232 <= Regression.rnd.NextDouble()) return; if (!(b.underwear.removable || inUnderwear)) { - Animations.Say(Animations.GetData().Cant_Remove, b); + Say(Data.Cant_Remove, b); return; } - if (!inUnderwear) + if (!inUnderwear) { if (b.InToilet(inUnderwear)) - Animations.Say(Animations.GetData().Pee_Toilet, b); + Say(Data.Pee_Toilet, b); else - Animations.Say(Animations.GetData().Pee_Voluntary, b); + Say(Data.Pee_Voluntary, b); - ((GameLocation)Animations.GetWho().currentLocation).temporarySprites.Add(new TemporaryAnimatedSprite(13, (Vector2)((Character)Game1.player).position.Value, Microsoft.Xna.Framework.Color.White, 10, ((Random)Game1.random).NextDouble() < 0.5, 70f, 0, (int)Game1.tileSize, 0.05f, -1, 0)); + ((GameLocation)player.currentLocation).temporarySprites.Add(new TemporaryAnimatedSprite(13, (Vector2)((Character)Game1.player).position.Value, Microsoft.Xna.Framework.Color.White, 10, ((Random)Game1.random).NextDouble() < 0.5, 70f, 0, (int)Game1.tileSize, 0.05f, -1, 0)); HoeDirt terrainFeature; - if (Animations.GetWho().currentLocation.terrainFeatures.ContainsKey(((Character)Animations.GetWho()).Tile) && (terrainFeature = Animations.GetWho().currentLocation.terrainFeatures[((Character)Animations.GetWho()).Tile] as HoeDirt) != null) + if (player.currentLocation.terrainFeatures.ContainsKey(((Character)player).Tile) && (terrainFeature = player.currentLocation.terrainFeatures[((Character)player).Tile] as HoeDirt) != null) terrainFeature.state.Value = 1; } else if (voluntary) - Animations.Say(Animations.GetData().Wet_Voluntary, b); + Say(Data.Wet_Voluntary, b); else - Animations.Say(Animations.GetData().Wet_Accident, b); + Say(Data.Wet_Accident, b); + + // We skip the actual animations if nessesary + if (Body.IsFishing() || !player.canMove) return; - //Animations.GetWho().forceCanMove(); - //Animations.GetWho().completelyStopAnimatingOrDoingAction(); - Animations.GetWho().jitterStrength = 0.5f; - Animations.GetWho().freezePause = peeAnimationTime; //milliseconds - Animations.GetWho().canMove = false; - ((Character)Animations.GetWho()).doEmote(28, false); + player.jitterStrength = 0.5f; + player.freezePause = peeAnimationTime; //milliseconds + player.canMove = false; + ((Character)player).doEmote(28, false); + } + public static void AnimateWettingMinor(Body b) + { + Say(Data.Bladder_Leak, b); + ((Character)player).doEmote(28, false); } + public static void AnimateWettingEnd(Body b) { - if (b.IsFishing()) return; + if (Body.IsFishing()) return; if ((double)b.pants.wetness > (double)b.pants.absorbency) { - ((GameLocation)Animations.GetWho().currentLocation).temporarySprites.Add(new TemporaryAnimatedSprite(13, (Vector2)((Character)Game1.player).position.Value, Microsoft.Xna.Framework.Color.White, 10, ((Random)Game1.random).NextDouble() < 0.5, 70f, 0, (int)Game1.tileSize, 0.05f, -1, 0)); + ((GameLocation)player.currentLocation).temporarySprites.Add(new TemporaryAnimatedSprite(13, (Vector2)((Character)Game1.player).position.Value, Microsoft.Xna.Framework.Color.White, 10, ((Random)Game1.random).NextDouble() < 0.5, 70f, 0, (int)Game1.tileSize, 0.05f, -1, 0)); HoeDirt terrainFeature; - if (Animations.GetWho().currentLocation.terrainFeatures.ContainsKey(((Character)Animations.GetWho()).Tile) && (terrainFeature = Animations.GetWho().currentLocation.terrainFeatures[((Character)Animations.GetWho()).Tile] as HoeDirt) != null) + if (player.currentLocation.terrainFeatures.ContainsKey(((Character)player).Tile) && (terrainFeature = player.currentLocation.terrainFeatures[((Character)player).Tile] as HoeDirt) != null) terrainFeature.state.Value = 1; } } public static void AnimateMorning(Body b) { - bool flag = (double)b.pants.wetness > 0.0; - bool second = (double)b.pants.messiness > 0.0; - string msg = "" + Strings.RandString(Animations.GetData().Wake_Up_Underwear_State); + bool flag = (double)b.bed.wetness > 0.0; + bool second = (double)b.bed.messiness > 0.0; + string msg = "" + Strings.RandString(Data.Wake_Up_Underwear_State); if (second) { - msg = msg + " " + Strings.ReplaceOptional(Strings.RandString(Animations.GetData().Messed_Bed), flag); + msg = msg + " " + Strings.ReplaceOptional(Strings.RandString(Data.Messed_Bed), flag); if (!Regression.config.Easymode) - msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Animations.GetData().Washing_Bedding), flag, second, "&"); + msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Data.Washing_Bedding), flag, second, "&"); } else if (flag) { - msg = msg + " " + Strings.RandString(Animations.GetData().Wet_Bed); + msg = msg + " " + Strings.RandString(Data.Wet_Bed); if (!Regression.config.Easymode) - msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Animations.GetData().Spot_Washing_Bedding), flag, second, "&"); + msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Data.Spot_Washing_Bedding), flag, second, "&"); } - Animations.Write(msg, b); + Write(msg, b); } - + private static string GetNumericTranslationMultiple(int amount) + { + switch (amount) + { + case 1: + return ""; + default: + return "multiple times "; + } + } + private static string GetNumericTranslationOnceTwice(int amount) + { + switch (amount) + { + case 1: + return "once"; + case 2: + return "twice"; + default: + return $"{amount} times"; + } + } + private static string GetNumericTranslationTimes(int amount) + { + switch (amount) + { + case 1: + return "one time"; + case 2: + return "two times"; + case 3: + return "three times"; + case 4: + return "four times"; + case 5: + return "five times"; + default: + return $"{amount} times"; + } + } + // Function to make the first character of the input string upper case + public static string FirstCharToUpper(this string input) => + input switch + { + null => throw new ArgumentNullException(nameof(input)), + "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)), + _ => string.Concat(input[0].ToString().ToUpper(), input.AsSpan(1)) + }; public static void AnimateNight(Body b) { bool first = b.numPottyPeeAtNight > 0; bool second = b.numPottyPooAtNight > 0; - if (!(first | second) || !Regression.config.Wetting && !Regression.config.Messing) - return; - string toiletMsg = Strings.ReplaceAndOr(Strings.RandString(Animations.GetData().Toilet_Night), first, second, "&"); + if (!b.IsAllowedResource(IncidentType.PEE) && !b.IsAllowedResource(IncidentType.POOP)) + return; + + var list = Data.Night; + // assumtion: if we wake up to pee/poop, we do that togehter if possible. So if we wake up 2 times for pee and 1 time for poop, it is likely we only got up twice, not 3 times + int gotUpAtNight = Math.Max(b.numPottyPeeAtNight, b.numPottyPooAtNight); + string toiletMsg = ""; + + if (gotUpAtNight > 0) + { + toiletMsg = Strings.ReplaceAndOr(Strings.RandString(list["Toilet_Night"]), first, second, "&"); + } + else + { + toiletMsg = Strings.RandString(list["Sleep_All_Night"]); + } + toiletMsg = FirstCharToUpper(toiletMsg); if (b.numAccidentPooAtNight == 0 && b.numAccidentPeeAtNight == 0) - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", "."); + toiletMsg += "."; else { - if (!b.underwear.removable) + var butPlaceholder = false; + if (gotUpAtNight > 0) { - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", ", but couldn't get your $UNDERWEAR_NAME$ off!$HOW_MANY_TIMES"); - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", " So you still woke up$HOW_MANY_TIMES"); - } else - { - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", ", but you still woke up$HOW_MANY_TIMES"); + butPlaceholder = true; + if (!b.underwear.removable) + { + toiletMsg += " " + Strings.RandString(list["Underwear_Stuck"]); + butPlaceholder = false; + } } - if (b.numAccidentPeeAtNight > 0) - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", " wet$HOW_MANY_TIMES"); - if (b.numAccidentPooAtNight > 0) - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", " and messy$HOW_MANY_TIMES"); - if (b.numAccidentPooAtNight > 0 || b.numAccidentPeeAtNight > 0) - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", "! Looks like someone really does need to be in their diapers at night$HOW_MANY_TIMES"); - } - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", "."); + toiletMsg += "."; + + var accidentReport = Strings.ReplaceOptional(Strings.ReplaceAndOr(Strings.RandString(list["Accident_At_Night"]), b.numAccidentPeeAtNight > 0, b.numAccidentPooAtNight > 0), butPlaceholder); + accidentReport = FirstCharToUpper(accidentReport); + + toiletMsg += " " + accidentReport + "."; + } + toiletMsg = Strings.InsertVariable(toiletMsg, "$TOILET_ONCE_TWICE_TOTAL", GetNumericTranslationOnceTwice(gotUpAtNight)); + toiletMsg = Strings.InsertVariable(toiletMsg, "$TOILET_TIMES_TOTAL", GetNumericTranslationTimes(gotUpAtNight)); + toiletMsg = Strings.InsertVariable(toiletMsg, "$ACCIDENT_ONCE_TWICE_TOTAL", GetNumericTranslationOnceTwice(Math.Max(b.numAccidentPeeAtNight,b.numAccidentPooAtNight))); + toiletMsg = Strings.InsertVariable(toiletMsg, "$ACCIDENT_TIMES_TOTAL", GetNumericTranslationTimes(Math.Max(b.numAccidentPeeAtNight,b.numAccidentPooAtNight))); + toiletMsg = Strings.InsertVariable(toiletMsg, "$ACCIDENT_TIMES_MULTIPLE_TOTAL", GetNumericTranslationMultiple(Math.Max(b.numAccidentPeeAtNight, b.numAccidentPooAtNight))); Write(toiletMsg, b); } public static void AnimatePeeAttempt(Body b, bool inUnderwear) { - if (b.IsFishing()) return; + if (Body.IsFishing()) return; if (inUnderwear) - Say(Animations.GetData().Wet_Attempt, b); + Say(Data.Wet_Attempt, b); else if (b.InToilet(inUnderwear)) - Say(Animations.GetData().Pee_Toilet_Attempt, b); + Say(Data.Pee_Toilet_Attempt, b); else - Say(Animations.GetData().Pee_Attempt, b); + Say(Data.Pee_Attempt, b); } public static void AnimatePoopAttempt(Body b, bool inUnderwear) { - if (b.IsFishing()) return; + if (Body.IsFishing()) return; if (inUnderwear) - Animations.Say(Animations.GetData().Mess_Attempt, b); + Say(Data.Mess_Attempt, b); else if (b.InToilet(inUnderwear)) - Animations.Say(Animations.GetData().Poop_Toilet_Attempt, b); + Say(Data.Poop_Toilet_Attempt, b); else - Animations.Say(Animations.GetData().Poop_Attempt, b); + Say(Data.Poop_Attempt, b); } public static void AnimateStillSoiled(Body b) { - Animations.Say(Strings.ReplaceAndOr(Strings.RandString(Animations.GetData().Still_Soiled), (double)b.underwear.wetness > 0.0, (double)b.underwear.messiness > 0.0, "&"), b); + string baseString = Strings.RandString(Data.Still_Soiled); + + baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); + Say(baseString, b); } + public static void AnimateShouldChange(Body b) + { + string baseString = Strings.RandString(Data.Should_Change); + baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); + Say(baseString, b); + } public static void AnimateWashingUnderwear(Container c) { if (c.MarkedForDestroy()) { - Animations.Write(Strings.InsertVariables(Animations.GetData().Overwashed_Underwear[0], (Body)null, c), (Body)null); + Write(Strings.InsertVariables(Data.Overwashed_Underwear[0], (Body)null, c), (Body)null); Game1.player.reduceActiveItemByOne(); } else { - Animations.Write(Strings.InsertVariables(Strings.RandString(Animations.GetData().Washing_Underwear), (Body)null, c), (Body)null); + Write(Strings.InsertVariables(Strings.RandString(Data.Washing_Underwear), (Body)null, c), (Body)null); } } public static void CheckPants(Body b) { - StardewValley.Objects.Clothing pants = b.GetPantsStardew(); - b.pants.name = pants.displayName; - b.pants.description = pants.displayName; - b.pants.plural = true; - Animations.Say(Animations.GetData().LookPants[0] + " " + Strings.DescribeUnderwear(b.pants, null) + ".", b); + Say(Data.LookPants[0] + " " + Strings.DescribeUnderwear(b.pants) + ".", b); } + public static bool WarnCurrentThreshold(float[] thresholds, string[][] messages, float currentValue, bool greaterAs = false) + { + var curr = GetCurrentThreshold(thresholds,messages,currentValue,greaterAs); + if(curr != null) + { + Warn(curr); + return true; + } + return false; + } + public static string[] GetCurrentThreshold(float[] thresholds, string[][] messages, float currentValue, bool greaterAs = false) + { + var index = GetCurrentTresholdIndex(thresholds, messages, currentValue, greaterAs); + if(index >= 0) return messages[index]; + return null; + } + public static int GetCurrentTresholdIndex(float[] thresholds, string[][] messages, float currentValue, bool greaterAs = false) + { + for (int index = thresholds.Length - 1; index >= 0; index--) + { + if (thresholds[index] > currentValue && !greaterAs) continue; + if (thresholds[index] <= currentValue && greaterAs) continue; + + return index; + } + return -1; + } + public static void CheckContinence(Body b) { - if (Regression.config.Wetting) + if (b.IsAllowedResource(IncidentType.PEE)) { - for (int index = Body.BLADDER_CONTINENCE_THRESHOLDS.Length - 1; index > 0; index--) - { - if(Body.BLADDER_CONTINENCE_THRESHOLDS[index] <= b.bladderContinence) - { - Animations.Say(Body.BLADDER_CONTINENCE_MESSAGES[index]); - break; - } - } + WarnCurrentThreshold(Body.BLADDER_CONTINENCE_THRESHOLDS, Body.BLADDER_CONTINENCE_MESSAGES, b.bladderContinence); } - if (Regression.config.Messing) + if (b.IsAllowedResource(IncidentType.POOP)) { - for (int index = Body.BOWEL_CONTINENCE_THRESHOLDS.Length -1; index > 0; index--) - { - if (Body.BOWEL_CONTINENCE_THRESHOLDS[index] <= b.bowelContinence) - { - Animations.Say(Body.BOWEL_CONTINENCE_MESSAGES[index]); - break; - } - } + WarnCurrentThreshold(Body.BOWEL_CONTINENCE_THRESHOLDS, Body.BOWEL_CONTINENCE_MESSAGES, b.bowelContinence); + } + } + public static void CheckPottyFeeling(Body b) + { + Warn((b.IsAllowedResource(IncidentType.PEE) ? Strings.RandString(GetPottyFeeling(b, IncidentType.PEE)) + " " : "") + (b.IsAllowedResource(IncidentType.POOP) ? Strings.RandString(GetPottyFeeling(b, IncidentType.POOP)) : "")); + } + + public static string[] GetPottyFeeling(Body b, IncidentType type) + { + float newFullness = b.GetFullness(type) / b.GetCapacity(type); + string[] pottyMessages = null; + if (newFullness > (1 - b.GetContinence(type))) + { + pottyMessages = GetCurrentThreshold(type == IncidentType.PEE ? Body.WETTING_THRESHOLDS : Body.MESSING_THRESHOLDS, type == IncidentType.PEE ? Body.WETTING_MESSAGES : Body.MESSING_MESSAGES, newFullness, false); } + if (pottyMessages != null) return pottyMessages; + return type == IncidentType.PEE ? Body.WETTING_MESSAGE_GREEN : Body.MESSING_MESSAGE_GREEN; } public static void CheckUnderwear(Body b) { - Say(Animations.GetData().PeekWaistband[0] + " " + Strings.DescribeUnderwear(b.underwear, (string)null) + ".", b); + Say(Data.PeekWaistband[0] + " " + Strings.DescribeUnderwear(b.underwear) + ".", b); } public static void DrawUnderwearIcon(Container c, int x, int y) { Microsoft.Xna.Framework.Color defaultColor = Microsoft.Xna.Framework.Color.White; - Texture2D underwearSprites = Animations.GetSprites(); - Microsoft.Xna.Framework.Rectangle srcBoxCurrent = Animations.UnderwearRectangle(c, FullnessType.None, LARGE_SPRITE_DIM); + Texture2D underwearSprites = sprites; + Microsoft.Xna.Framework.Rectangle srcBoxCurrent = UnderwearRectangle(c, FullnessType.None, LARGE_SPRITE_DIM); Microsoft.Xna.Framework.Rectangle destBoxCurrent = new Microsoft.Xna.Framework.Rectangle(x, y, DIAPER_HUD_DIM, DIAPER_HUD_DIM); ((SpriteBatch)Game1.spriteBatch).Draw(underwearSprites, destBoxCurrent, srcBoxCurrent, defaultColor); if (Game1.getMouseX() >= x && Game1.getMouseX() <= x + DIAPER_HUD_DIM && Game1.getMouseY() >= y && Game1.getMouseY() <= y + DIAPER_HUD_DIM) - { - string source = Strings.DescribeUnderwear(c, (string)null); - string str = source.First().ToString().ToUpper() + source.Substring(1); - int num = Game1.tileSize * 6 + Game1.tileSize / 6; - IClickableMenu.drawHoverText((SpriteBatch)Game1.spriteBatch, Game1.parseText(str, (SpriteFont)Game1.tinyFont, num), (SpriteFont)Game1.smallFont, 0, 0, -1, (string)null, -1, (string[])null, (Item)null, 0, null, -1, -1, -1, 1f, (CraftingRecipe)null); - } + { + string source = Strings.DescribeUnderwear(c, (string)null); + string str = source.First().ToString().ToUpper() + source.Substring(1); + int num = Game1.tileSize * 6 + Game1.tileSize / 6; + IClickableMenu.drawHoverText((SpriteBatch)Game1.spriteBatch, Game1.parseText(str, (SpriteFont)Game1.tinyFont, num), (SpriteFont)Game1.smallFont, 0, 0, -1, null, -1, null, null, 0, null, -1, x - (DIAPER_HUD_DIM * 5), y); + } + } + public static void DrawStateIcon(Body b, IncidentType type, int x, int y) + { + float newFullness = b.GetFullness(type) / b.GetCapacity(type); + + if (newFullness < Body.trainingThreshold || newFullness < (1 - b.GetContinence(type))) return; + + int topOffset = LARGE_SPRITE_DIM - (int)Math.Ceiling(newFullness * LARGE_SPRITE_DIM); + Microsoft.Xna.Framework.Color defaultColor = Microsoft.Xna.Framework.Color.White; + + Texture2D peeOrPoopIcon = peepoopSprites; + if (peeOrPoopIcon == null) return; + Microsoft.Xna.Framework.Rectangle emptyIcon = StatusRectangle(b, type,false, LARGE_SPRITE_DIM); + Microsoft.Xna.Framework.Rectangle filledIcon = StatusRectangle(b, type, true, LARGE_SPRITE_DIM, topOffset); + + Microsoft.Xna.Framework.Rectangle emptyBoxCurrent = new Microsoft.Xna.Framework.Rectangle(x, y, DIAPER_HUD_DIM, DIAPER_HUD_DIM); + Microsoft.Xna.Framework.Rectangle fullBoxCurrent = new Microsoft.Xna.Framework.Rectangle(x, y+ topOffset, DIAPER_HUD_DIM, DIAPER_HUD_DIM- topOffset); + + ((SpriteBatch)Game1.spriteBatch).Draw(peeOrPoopIcon, emptyBoxCurrent, emptyIcon, defaultColor); + ((SpriteBatch)Game1.spriteBatch).Draw(peeOrPoopIcon, fullBoxCurrent, filledIcon, defaultColor); + if (Game1.getMouseX() >= x && Game1.getMouseX() <= x + DIAPER_HUD_DIM && Game1.getMouseY() >= y && Game1.getMouseY() <= y + DIAPER_HUD_DIM) + { + string source = GetPottyFeeling(b, type)[0]; + string str = source.First().ToString().ToUpper() + source.Substring(1); + int num = Game1.tileSize * 6 + Game1.tileSize / 6; + IClickableMenu.drawHoverText((SpriteBatch)Game1.spriteBatch, Game1.parseText(str, (SpriteFont)Game1.tinyFont, num), (SpriteFont)Game1.smallFont, 0, 0,-1,null,-1,null,null,0,null,-1,x -(DIAPER_HUD_DIM * 5),y); + } } private static void EndDrinking(Farmer who) { - Animations.GetWho().completelyStopAnimatingOrDoingAction(); - Animations.GetWho().forceCanMove(); + player.completelyStopAnimatingOrDoingAction(); + player.forceCanMove(); } public static void HandlePasserby() { - if (Utility.isThereAFarmerOrCharacterWithinDistance(Animations.GetWho().Tile, 3, (GameLocation)Game1.currentLocation) is not NPC npc || NPC_LIST.Contains(npc.Name)) + if (Utility.isThereAFarmerOrCharacterWithinDistance(player.Tile, 3, (GameLocation)Game1.currentLocation) is not NPC npc) return; npc.CurrentDialogue.Push(new Dialogue(npc, null, "Oh wow, your diaper is all wet!")); } - - public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool overflow, bool attempt = false) + private static List NearbyVillager(Body b, bool mess, bool inUnderwear, bool overflow, bool attempt = false) { - int baseFriendshipLoss = (mess ? Regression.config.FriendshipPenaltyBowelMultiplier : Regression.config.FriendshipPenaltyBladderMultiplier); - int radius = 3; - bool someoneNoticed = true; - float actualLoss = -(baseFriendshipLoss/100); - //If we are messing, increase the radius of noticeability (stinky) - // OLD: Double how much friendship we lose (mess is gross) if (mess) { radius *= 2; - //actualLoss *= 2f; Unnessesary. Its now defined over config already as such. } //If we pulled down our pants, quadruple the radius (not contained and visible!) @@ -394,35 +527,72 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over if (!inUnderwear) { radius *= 4; - actualLoss *= 2f; } - //Did we try, but not actually succeed? (not full enough) - if (attempt) - actualLoss /= 2f; - //Double noticeability is we had a blow-out/leak (people can see) if (overflow) radius *= 2; - //Get NPC in radius - // This needs to be reworked to get a list of NPCs - if (Utility.isThereAFarmerOrCharacterWithinDistance(((Character)Animations.GetWho()).Tile, radius, (GameLocation)Game1.currentLocation) is not NPC npc || NPC_LIST.Contains(npc.Name)) - return false; + return NearbyVillager(radius); + } - //Reduce the loss if the person likes you (more forgiving) - int heartLevelForNpc = Animations.GetWho().getFriendshipHeartLevelForNPC(npc.getName()); + public static List NearbyVillager(int radius) + { + var list = Utility.GetNpcsWithinDistance(((Character)player).Tile, radius, (GameLocation)Game1.currentLocation); + + var newList = new List(); + foreach (var npcEntry in list) + { + newList.Add(npcEntry); + } + return newList; + } + + public static Dictionary FriendshipLossOnAccident(Body b, bool mess, bool inUnderwear, bool overflow, bool attempt = false) + { + var list = new Dictionary(); + + //Get NPC in radius + var nearby = NearbyVillager(b, mess, inUnderwear, overflow, attempt); + + foreach (var npc in nearby) + { + int finalLossValue = FriendshipLossOnAccident(npc, mess,inUnderwear,overflow,attempt); + list[npc.getName().ToLower()] = finalLossValue; + } + return list; + } + public static int FriendshipLossOnAccident(NPC npc, bool mess, bool inUnderwear, bool overflow, bool attempt = false) + { + int heartLevelForNpc = player.getFriendshipHeartLevelForNPC(npc.getName().ToLower()); + int baseFriendshipLoss = (mess ? Regression.config.FriendshipPenaltyBowelMultiplier : Regression.config.FriendshipPenaltyBladderMultiplier); //Does this leave the possibility of friendship gain if we have enough hearts already? Maybe because they find the vulnerability endearing? - float friendshipLoss = actualLoss + (heartLevelForNpc - 2) / 2 * (baseFriendshipLoss / 5); + float friendshipLoss = -1 + (heartLevelForNpc - 2) / 2; + + var modifiers = Data.Villager_Friendship_Modifier; + var modifierKey = modifierForIncident(npc, mess, inUnderwear, overflow, attempt); + + float finalModifier = 1.0f; + foreach (string key2 in npcTypeList(npc)) + { + float floatOut; + Dictionary dictionary; + if (modifiers.TryGetValue(key2, out dictionary) && dictionary.TryGetValue(modifierKey, out floatOut)) + { + finalModifier = floatOut; + } + } - //Make a list based on who saw us. + return (int)Math.Floor((baseFriendshipLoss / 100 / 5) * friendshipLoss * finalModifier); + } + public static List npcTypeList(NPC npc) + { List npcType = new List(); - string npcName = ""; + if (npc is Horse || npc is Pet) { npcType.Add("animal"); - npcName += string.Format("{0}: ", npc.Name); } else { @@ -440,65 +610,126 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over } npcType.Add(npc.getName().ToLower()); } + return npcType; + } - //What did we do? Use to figure out the response. - string responseKey = ""; + public static string modifierForIncident(NPC npc, bool mess, bool inUnderwear, bool overflow, bool attempt = false) + { if (!inUnderwear) { //If we weren't wearing underwear, we tried on the ground. //But did we succeed or just try to go? - responseKey = attempt ? "ground_attempt" : "ground"; + return attempt ? "ground_attempt" : "ground"; } else { //Otherwise, we are soiling ourselves - responseKey += "soiled"; + return "soiled"; + } + } + public static string responseKeyAdditionForState(NPC npc, bool isDirty = false) + { + var body = new NpcBody(npc); + if (!isDirty && body.canGetGiveChangeNpc) + { + return "_offer_change"; + } + else if (isDirty && body.canGiveDirtyChangeNpc) + { + return "_offer_change"; + } + return ""; + + } + public static string responseKeyAdditionForIncident(NPC npc, bool inUnderwear, int friendshipLoss) + { + // we only have special responses for soiling our underwear + if (inUnderwear) + { //Animals only have a "nice" response - if (npcType.Contains("animal")) - { - responseKey += "_nice"; - friendshipLoss = 0; - } - //If we have a really high relationship with the NPC, they're very nice about our accident - else if (heartLevelForNpc >= 8) + if (npcTypeList(npc).Contains("animal")) { - responseKey += "_verynice"; - friendshipLoss = 0; + return "_nice"; } else + { + int heartLevelForNpc = player.getFriendshipHeartLevelForNPC(npc.getName()); + //If we have a really high relationship with the NPC, they're very nice about our accident + if (heartLevelForNpc >= 8) + { + return "_verynice"; + } //Otherwise they'll be mean or nice depending on how much friendship we're losing - responseKey = friendshipLoss < 0 ? responseKey + "_mean" : responseKey + "_nice"; - - //Why are Abigail and Jodi special? - if (npc.getName() == "Abigail" || npc.getName() == "Jodi") - friendshipLoss = 0; + if (friendshipLoss < 0) return "_nice"; + return "_mean"; + } } + return ""; + } + public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool overflow, bool attempt = false) + { + bool someoneNoticed = false; - int finalLossValue = (int)Math.Round(friendshipLoss); - //If we're in debug mode, notify how the relationship was effected - if (Regression.config.Debug) - Animations.Say(string.Format("{0} ({1}) changed friendship from {2} by {3}.", npc.Name, npc.Age, heartLevelForNpc, finalLossValue), (Body)null); + //Get NPC in radius + var nearby = NearbyVillager(b, mess, inUnderwear, overflow, attempt); + foreach (var npc in nearby) + { + if (npc.Age == 2 && !Regression.ChildrenAndDiapers) continue; + someoneNoticed = true; - - //If we didn't lose any friendship, or we disabled friendship penalties (by adjusting it to 0), then don't adjust the value - if (finalLossValue < 0) - Animations.GetWho().changeFriendship(finalLossValue, npc); + //Make a list based on who saw us. + var npcType = npcTypeList(npc); + string npcName = ""; + if (npc is Horse || npc is Pet) + { + npcName += string.Format("{0}: ", npc.Name); + } - List stringList3 = new List(); - foreach (string key2 in npcType) - { - Dictionary dictionary; - string[] strArray; - if (Animations.GetData().Villager_Reactions.TryGetValue(key2, out dictionary) && dictionary.TryGetValue(responseKey, out strArray)) - stringList3.AddRange((IEnumerable)strArray); + //What did we do? Use to figure out the response. + string modifierKey = modifierForIncident(npc,mess,inUnderwear,overflow,attempt); + int finalLossValue = FriendshipLossOnAccident(npc,mess,inUnderwear,overflow,attempt); + + //If we're in debug mode, notify how the relationship was effected + if (Regression.config.Debug && finalLossValue < 0) + Say(string.Format("{0} ({1}) changed friendship from {2} by {3}.", npc.Name, npc.Age, player.getFriendshipHeartLevelForNPC(npc.getName()), finalLossValue), (Body)null); + + + //If we didn't lose any friendship, or we disabled friendship penalties (by adjusting it to 0), then don't adjust the value + if (finalLossValue < 0) + player.changeFriendship(finalLossValue, npc); + + string responseKey = modifierKey + responseKeyAdditionForIncident(npc,inUnderwear, finalLossValue); + List stringList3 = new List(); + foreach (string key2 in npcType) + { + Dictionary dictionary; + string[] strArray; + if (Data.Villager_Reactions.TryGetValue(key2, out dictionary) && dictionary.TryGetValue(responseKey, out strArray)) + { + stringList3 = new List(); // We could remove this line again, but the general texts are more meant as fallback, they often don't fit well if custom texts are defined + stringList3.AddRange((IEnumerable)strArray); + } + + } + + if (stringList3.Count <= 0) continue; + + //Construct and say Statement + string npcStatement = npcName + Strings.InsertVariables(Strings.ReplaceAndOr(Strings.RandString(stringList3.ToArray()), !mess, mess, "&"), b, (Container)null); + + Regression.QueueAction(() => + { + if (b.underwear.used || attempt || !inUnderwear) + { + npcStatement = Strings.InsertVariables(npcStatement, npc); + npc.setNewDialogue(new Dialogue(npc, null, npcStatement), true, true); + Game1.drawDialogue(npc); + } + }); } - //Construct and say Statement - string npcStatement = npcName + Strings.InsertVariables(Strings.ReplaceAndOr(Strings.RandString(stringList3.ToArray()), !mess, mess, "&"), b, (Container)null); - npc.setNewDialogue(new Dialogue(npc, null, npcStatement), true, true); - Game1.drawDialogue(npc); return someoneNoticed; } @@ -509,12 +740,15 @@ public static Texture2D LoadTexture(string file) public static void Say(string msg, Body b = null) { - Game1.showGlobalMessage(Strings.InsertVariables(msg, b, (Container)null)); + Regression.QueueAction(() => + { + Game1.showGlobalMessage(Strings.InsertVariables(msg, b, (Container)null)); + }); } public static void Say(string[] msgs, Body b = null) { - Animations.Say(Strings.RandString(msgs), b); + Say(Strings.RandString(msgs), b); } public static Microsoft.Xna.Framework.Rectangle UnderwearRectangle(Container c, FullnessType type = FullnessType.None, int height = LARGE_SPRITE_DIM) @@ -561,7 +795,7 @@ public static Microsoft.Xna.Framework.Rectangle UnderwearRectangle(Container c, } else { - if (!c.IsDrying()) + if (!c.drying) { if ((double)c.messiness <= .0f) { @@ -585,25 +819,39 @@ public static Microsoft.Xna.Framework.Rectangle UnderwearRectangle(Container c, } return new Microsoft.Xna.Framework.Rectangle(c.spriteIndex * LARGE_SPRITE_DIM, num + (LARGE_SPRITE_DIM - height), LARGE_SPRITE_DIM, height); } + public static Microsoft.Xna.Framework.Rectangle StatusRectangle(Body b, IncidentType type, bool isFilledPicture, int height = LARGE_SPRITE_DIM, int topOffset = 0) + { + return new Microsoft.Xna.Framework.Rectangle( (int)type * LARGE_SPRITE_DIM, (isFilledPicture ? LARGE_SPRITE_DIM : 0) + topOffset + (LARGE_SPRITE_DIM - height), LARGE_SPRITE_DIM, height - topOffset); + } - public static void Warn(string msg, Body b = null) + public static void Warn(string msg, Body b = null, Container c = null) { - Game1.addHUDMessage(new HUDMessage(Strings.InsertVariables(msg, b, (Container)null), 2)); + msg = Strings.InsertVariables(msg, b, c); + Regression.QueueAction(() => + { + Game1.addHUDMessage(new HUDMessage(msg, 2)); + }); + } - public static void Warn(string[] msgs, Body b = null) + public static void Warn(string[] msgs, Body b = null, Container c = null) { - Animations.Warn(Strings.RandString(msgs), b); + Warn(Strings.RandString(msgs), b, c); } - public static void Write(string msg, Body b = null, int delay = 0) + public static void Write(string msg, Body b = null, Container c = null,int delay = 0) { - DelayedAction.showDialogueAfterDelay(Strings.InsertVariables(msg, b, (Container)null), delay); + msg = Strings.InsertVariables(msg, b, c); + Regression.QueueAction(() => + { + DelayedAction.showDialogueAfterDelay(msg, 10); + },delay); + } - public static void Write(string[] msgs, Body b = null, int delay = 0) + public static void Write(string[] msgs, Body b = null, Container c = null, int delay = 0) { - Animations.Write(Strings.RandString(msgs), b, delay); + Write(Strings.RandString(msgs), b, c, delay); } } } diff --git a/Regression/PrimevalTitmouse/Body.cs b/Regression/PrimevalTitmouse/Body.cs index 0a29af3..cb6c84e 100644 --- a/Regression/PrimevalTitmouse/Body.cs +++ b/Regression/PrimevalTitmouse/Body.cs @@ -3,40 +3,57 @@ using StardewValley; using StardewValley.Buffs; using StardewValley.Locations; +using StardewValley.Minigames; +using StardewValley.Mods; using StardewValley.Tools; using System; using System.Reflection; +using System.Text.Json.Serialization; +using static PrimevalTitmouse.Container; namespace PrimevalTitmouse { // A lot of bladder and bowel stuff is processed similarly. Consider refactor with arrays and Function pointers. public class Body { + // Floximo: In general you need to go to the toilet (in reality) about every 3-4 hours on average, lets go with 4 and assume 500mL and 16 waking hours a day (and we assume you healthy, not waking up at night) its around 2500mL of pee a day. + // For Pee the gameplay aligns pretty good, considering the values this is based on are wildly out of propotions. But i guess if only 20% of the water you drink is peed out, and the rest sweat, this might be possible. + // Poop is usually once a day on average. The values set balanced out to you needing to poop every 4 hours at least. That is a lot if you don't want to only pay potty simulator. Gets worse with bad potty training. + // Balancing poop with the given values "foodToBowelConversion" and "requiredCaloriesPerDay" is challanging, as the bowel capacity is linear to this 2 values. + //Lets think of Food in Calories, and water in mL - //For a day Laborer (like a farmer) that should be ~3500 Cal, and 14000 mL + //For a day Laborer (like a farmer) that should be ~3500 Cal, and 14000 mL - NOTE: (Floximo) you mean 1400 mL probably. Up to 3000 mL is considered healthy //Of course this is dependent on amount of work, but let's go one step at a time private static readonly float requiredCaloriesPerDay = 3500f; - private static readonly float requiredWaterPerDay = 8000f; //8oz glasses: every 20min for 8 hours + every 40 min for 8 hour - //private static readonly float maxWaterInCan = 4000f; //How much water does the watering can hold? Max is 40, so *100 + public float hungerMeterMax + { + get => requiredCaloriesPerDay * 2; + } + + private static readonly float requiredWaterPerDay = 8000f; //8oz glasses: every 20min for 8 hours (5455mL) + every 40 min for 8 hour (2727mL) Floximo: That is rough. Possible in extrem heat but rough to drink. //Average # of Pees per day is ~3 - public static readonly float maxBladderCapacity = 600; //about 600mL - private static readonly float minBladderCapacity = maxBladderCapacity * 0.20f; - private static readonly float waterToBladderConversion = 0.225f;//Only ~1/4 water becomes pee, rest is sweat etc. + public static float maxBladderCapacity => Regression.config.MaxBladderCapacity; //about 600mL => changed to 800mL as player will start with lower bladder by default + public static readonly float minBladderContinence = 0.4f; // Also describes capacity as changes are linear + private static readonly float waterToBladderConversion = 0.2f;//Only ~1/4 (0.225f) water becomes pee, rest is sweat etc. => changed to 0.2f (1/5) for game balance reasons (too intrusive) //Average # of poops per day varies wildly. Let's say about 1.5 per day. - private static readonly float foodToBowelConversion = 0.67f; - private static readonly float maxBowelCapacity = (requiredCaloriesPerDay*foodToBowelConversion) / 2f; - private static readonly float minBowelCapacity = maxBowelCapacity * 0.20f; + private static readonly float foodToBowelConversion = 0.4f; // lowered from 0.67f to 0.4f to make the numbers smaller (too much poop) and bowel capacity / 1.4f (1000f in total) + private static float maxBowelCapacity => (requiredCaloriesPerDay*foodToBowelConversion) / 1.4f / 1000f * Regression.config.MaxBowelCapacity; // The last 2 numbers usually end up as / 1200 * 1200 (cancle eachother out) to make configuration easier to understand + public static readonly float minBowelContinence = 0.4f; // Also describes capacity as changes are linear //Setup Thresholds and messages - private static readonly float[] WETTING_THRESHOLDS = { 0.15f, 0.4f, 0.6f }; - private static readonly string[][] WETTING_MESSAGES = { Regression.t.Bladder_Red, Regression.t.Bladder_Orange, Regression.t.Bladder_Yellow }; - private static readonly float[] MESSING_THRESHOLDS = { 0.15f, 0.4f, 0.6f }; - private static readonly string[][] MESSING_MESSAGES = { Regression.t.Bowels_Red, Regression.t.Bowels_Orange, Regression.t.Bowels_Yellow }; - public static readonly float[] BLADDER_CONTINENCE_THRESHOLDS = { 0.2f, 0.5f, 0.6f, 0.8f, 1.0f }; + public static readonly float trainingThreshold = 0.5f; // we set a threshold that allowes for potty training, so that should also be the warning level, for the player to understand whats going on + private static readonly float lastWarningThreshold = 0.8f; // with a minimum continence of 0.3, 0.8 is still warned about, as it would warn up to 0.7, while 0.69 is out of range (means only 1 warning) + public static readonly float[] WETTING_THRESHOLDS = { trainingThreshold + 0.05f, 0.69f, lastWarningThreshold }; + public static readonly string[][] WETTING_MESSAGES = { Regression.t.Bladder_Yellow, Regression.t.Bladder_Orange, Regression.t.Bladder_Red}; + public static readonly string[] WETTING_MESSAGE_GREEN = Regression.t.Bladder_Green; + public static readonly float[] MESSING_THRESHOLDS = { trainingThreshold + 0.05f, 0.69f, lastWarningThreshold }; + public static readonly string[][] MESSING_MESSAGES = { Regression.t.Bowels_Yellow, Regression.t.Bowels_Orange, Regression.t.Bowels_Red}; + public static readonly string[] MESSING_MESSAGE_GREEN = Regression.t.Bowels_Green; + public static readonly float[] BLADDER_CONTINENCE_THRESHOLDS = { minBladderContinence, 0.55f, 0.65f, 0.8f, 1.0f }; public static readonly string[][] BLADDER_CONTINENCE_MESSAGES = { Regression.t.Bladder_Continence_Min, Regression.t.Bladder_Continence_Red, Regression.t.Bladder_Continence_Orange, Regression.t.Bladder_Continence_Yellow, Regression.t.Bladder_Continence_Green}; - public static readonly float[] BOWEL_CONTINENCE_THRESHOLDS = { 0.2f, 0.5f, 0.6f, 0.8f, 1.0f }; + public static readonly float[] BOWEL_CONTINENCE_THRESHOLDS = { minBowelContinence, 0.55f, 0.65f, 0.8f, 1.0f }; public static readonly string[][] BOWEL_CONTINENCE_MESSAGES = { Regression.t.Bowel_Continence_Min, Regression.t.Bowel_Continence_Red, Regression.t.Bowel_Continence_Orange, Regression.t.Bowel_Continence_Yellow, Regression.t.Bowel_Continence_Green }; private static readonly float[] HUNGER_THRESHOLDS = { 0.0f, 0.25f }; private static readonly string[][] HUNGER_MESSAGES = { Regression.t.Food_None, Regression.t.Food_Low }; @@ -44,59 +61,335 @@ public class Body private static readonly string[][] THIRST_MESSAGES = { Regression.t.Water_None, Regression.t.Water_Low }; private static readonly string MESSY_DEBUFF = "Regression.Messy"; private static readonly string WET_DEBUFF = "Regression.Wet"; - private static readonly int wakeUpPenalty = 4; + private static readonly int wakeUpPenalty = 8; + public static readonly string modDataPrefix = "PrimevalTitmouse/Body"; + private void save(string name, int val) + { + Game1.player.modData[BuildKeyFor(name)] = val.ToString(); + } + private void save(string name, float val) + { + Game1.player.modData[BuildKeyFor(name)] = val.ToString(); + } + private void save(string name, bool val) + { + Game1.player.modData[BuildKeyFor(name)] = val.ToString(); + } + private static int LoadInt(string name, int defaultVal) + { + if (!Game1.player.modData.ContainsKey(BuildKeyFor(name))) return defaultVal; + return int.Parse(Game1.player.modData[BuildKeyFor(name)]); + } + private static float LoadFloat(string name, float defaultVal) + { + if (!Game1.player.modData.ContainsKey(BuildKeyFor(name))) return defaultVal; + return float.Parse(Game1.player.modData[BuildKeyFor(name)]); + } + private static bool LoadBool(string name, bool defaultVal) + { + if (!Game1.player.modData.ContainsKey(BuildKeyFor(name))) return defaultVal; + return bool.Parse(Game1.player.modData[BuildKeyFor(name)]); + } + private static string BuildKeyFor(string varName) + { + return $"{modDataPrefix}/{varName}"; + } + private bool HasKeyFor(string varName) + { + return Game1.player.modData != null && Game1.player.modData.ContainsKey(BuildKeyFor(varName)); + } //Things that describe an individual - public int bedtime = 0; - public float bladderCapacity = maxBladderCapacity; - public float bladderContinence = 1f; - public float bladderFullness = 0f; - public float bowelCapacity = maxBowelCapacity; - public float bowelContinence = 1f; - public float bowelFullness = 0f; - public float hunger = 0f; - public float thirst = 0f; - public bool isSleeping = false; - public Container bed; - public Container pants; - public Container underwear; - public int numPottyPooAtNight = 0; - public int numPottyPeeAtNight = 0; - public int numAccidentPooAtNight = 0; - public int numAccidentPeeAtNight = 0; + public int bedtime + { + get => LoadInt("bedtime", 0); + set => save("bedtime", value); + } + + public float bladderContinence + { + get => LoadFloat("bladderContinence", Math.Min(1f, Math.Max(minBowelContinence, Regression.config.StartBladderContinence / 100f))); + set => save("bladderContinence", value); + } + + public float bladderFullness + { + get => LoadFloat("bladderFullness", 0f); + set => save("bladderFullness", value); + } + + public float bowelContinence + { + get => LoadFloat("bowelContinence", Math.Min(1f, Math.Max(minBowelContinence, Regression.config.StartBowelContinence / 100f))); + set => save("bowelContinence", value); + } + + public float bowelFullness + { + get => LoadFloat("bowelFullness", 0f); + set => save("bowelFullness", value); + } + + public float hunger + { + get => LoadFloat("hunger", 0f); + set => save("hunger", value); + } + + public float thirst + { + get => LoadFloat("thirst", 0f); + set => save("thirst", value); + } + + public bool isSleeping + { + get => LoadBool("isSleeping", false); + set => save("isSleeping", value); + } + + public int numPottyPooAtNight + { + get => LoadInt("numPottyPooAtNight", 0); + set => save("numPottyPooAtNight", value); + } + + public int numPottyPeeAtNight + { + get => LoadInt("numPottyPeeAtNight", 0); + set => save("numPottyPeeAtNight", value); + } + + public int numAccidentPooAtNight + { + get => LoadInt("numAccidentPooAtNight", 0); + set => save("numAccidentPooAtNight", value); + } + + public int numAccidentPeeAtNight + { + get => LoadInt("numAccidentPeeAtNight", 0); + set => save("numAccidentPeeAtNight", value); + } + private float lastStamina = 0; + public float bladderCapacity + { + get + { + //Decrease our maximum capacity (bladder shrinks as we become incontinent) + return bladderContinence * maxBladderCapacity; + + //Ceiling at base value and floor at 25% base value + //return Math.Max(bladderCapacity, maxBladderCapacity * minBladderContinence); + } + } + + public float bowelCapacity + { + get + { + //Decrease our maximum capacity (bowel shrinks as we become incontinent) + return bowelContinence * maxBowelCapacity; + + //Ceiling at base value and floor at 25% base value + //return Math.Max(bowelCapacity, minBowelCapacity * minBowelContinence); + } + } + private Container _bed; + [JsonIgnore] + public Container bed { + get + { + if(_bed == null) + { + _bed = new Container(this, "bed", "bed"); + } + return _bed; + } + } + private Container _pants; + [JsonIgnore] + public Container pants + { + get + { + if (_pants == null) + { + _pants = new Container(this, "pants", "blue jeans"); + } + return _pants; + } + } + + private Container _underwear; + [JsonIgnore] + public Container underwear + { + get + { + if (_underwear == null) + { + _underwear = new Container(this, "underwear", "dinosaur undies"); + } + return _underwear; + } + } + public Body() { - bed = new("bed"); - pants = CreateNewPants(); - underwear = new("dinosaur undies"); - } + + } + + public bool IsAllowedResource(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return Regression.config.Wetting; + case IncidentType.POOP: + return Regression.config.Messing; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } public float GetBladderTrainingThreshold() { - return bladderCapacity * 0.5f; + return bladderCapacity * trainingThreshold; } public float GetBowelTrainingThreshold() { - return bowelCapacity * 0.5f; + return bowelCapacity * trainingThreshold; + } + public float GetTrainingThreshold(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return GetBladderTrainingThreshold(); + case IncidentType.POOP: + return GetBowelTrainingThreshold(); + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public float GetAttemptThreshold(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return GetBladderAttemptThreshold(); + case IncidentType.POOP: + return GetBowelAttemptThreshold(); + default: + throw new Exception("Not implemented: type " + type.ToString()); + } } - public float GetBladderAttemptThreshold() { - return bladderCapacity * 0.1f; + return bladderCapacity * 0.15f; } public float GetBowelAttemptThreshold() { - return bowelCapacity * 0.1f; + return bowelCapacity * 0.15f; + } + public float GetFullness(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return bladderFullness; + case IncidentType.POOP: + return bowelFullness; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public void SetFullness(IncidentType type, float value) + { + switch (type) + { + case IncidentType.PEE: + bladderFullness = Math.Max(0f, value); + return; + case IncidentType.POOP: + bowelFullness = Math.Max(0f, value); + return; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public float GetMaxCapacity(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return maxBladderCapacity; + case IncidentType.POOP: + return maxBowelCapacity; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public float GetCapacity(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return bladderCapacity; + case IncidentType.POOP: + return bowelCapacity; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public float GetContinenceMin(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return minBladderContinence; + case IncidentType.POOP: + return minBowelContinence; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public float GetContinence(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return bladderContinence; + case IncidentType.POOP: + return bowelContinence; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + // This function sets, it doesn't substract, be aware to use a calculation that is aware of that, like GetContinence(type) + change + public void SetContinence(IncidentType type, float value) + { + switch (type) + { + case IncidentType.PEE: + bladderContinence = Math.Max(minBladderContinence,Math.Min(1f, value)); + return; + case IncidentType.POOP: + bowelContinence = Math.Max(minBowelContinence, Math.Min(1f, value)); + return; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } } - public float GetHungerPercent() { - return (requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; + return (hungerMeterMax - hunger) / hungerMeterMax; } public float GetThirstPercent() @@ -114,61 +407,48 @@ public float GetBladderPercent() return bladderFullness / bladderCapacity; } - //Change current bladder value and handle warning messages - public void AddBladder(float amount) + public void AddResource(IncidentType type, float amount) { - //If Wetting is disabled, don't do anything - if (!Regression.config.Wetting) + //If Resource (poop/pee) is disabled, don't do anything + if (!IsAllowedResource(type)) return; + var fullness = GetFullness(type); + var capacity = GetCapacity(type); //Increment the current amount //We allow bladder to go over-full, to simulate the possibility of multiple night wettings //This is determined by the amount of water you have in your system when you go to bed - float oldFullness = bladderFullness / maxBladderCapacity; - bladderFullness += amount; - float newFullness = bladderFullness / maxBladderCapacity; + float oldFullnessPercent = fullness / capacity; + + SetFullness(type, fullness + amount); + fullness = GetFullness(type); //Did we go over? Then have an accident. - if (bladderFullness >= bladderCapacity) - { - Wet(voluntary: false, inUnderwear: true); - newFullness = bladderFullness / maxBladderCapacity; - //Otherwise, calculate the new value - } else + if (fullness >= capacity) { - //If we have no room left, or randomly based on our current continence level warn about how badly we need to pee - if ((newFullness <= 0.0 ? 1.0 : bladderContinence / (4f * newFullness)) > Regression.rnd.NextDouble()) + if (!isSleeping) { - Warn(1-oldFullness, 1-newFullness, WETTING_THRESHOLDS, WETTING_MESSAGES, false); + if (MinorAccident(type)) return; } + Accident(type, voluntary: false, inUnderwear: true); } - } - - //Change current bowels value and handle warning messages - public void AddBowel(float amount) - { - //If Wetting is disabled, don't do anything - if (!Regression.config.Messing) - return; - - //Increment the current amount - //We allow bowels to go over-full, to simulate the possibility of multiple night messes - //This is determined by the amount of ffod you have in your system when you go to bed - float oldFullness = bowelFullness / maxBowelCapacity; - bowelFullness += amount; - float newFullness = bowelFullness / maxBowelCapacity; - - //Did we go over? Then have an accident. - if (bowelFullness >= bowelCapacity) + else if(!underwear.removable && oldFullnessPercent > 0.7f && !IsTryingToHoldIt(type)) { - Mess(voluntary: false, inUnderwear: true); + Accident(type, voluntary: true, inUnderwear: true); } else { //If we have no room left, or randomly based on our current continence level warn about how badly we need to pee - if ((newFullness <= 0.0 ? 1.0 : bowelContinence / (4f * newFullness)) > Regression.rnd.NextDouble()) + /*if ((newFullness <= 0.0 ? 1.0 : bladderContinence / (4f * newFullness)) > Regression.rnd.NextDouble()) + { + Warn(1-oldFullness, 1-newFullness, WETTING_THRESHOLDS, WETTING_MESSAGES, false); + }*/ + float newFullnessPercent = fullness / capacity; + // No randomness in this. We get warned later and it is more urgent immediatly, giving less time, but reliable. + if (newFullnessPercent > (1 - GetContinence(type))) { - Warn(1-oldFullness, 1-newFullness, MESSING_THRESHOLDS, MESSING_MESSAGES, false); + // old and new is inverted, because we expect a rising, not falling trend + Warn(newFullnessPercent, oldFullnessPercent, type == IncidentType.POOP ? MESSING_THRESHOLDS : WETTING_THRESHOLDS, type == IncidentType.POOP ? MESSING_MESSAGES : WETTING_MESSAGES, false); } } } @@ -179,20 +459,27 @@ public void AddBowel(float amount) public void AddFood(float amount, float conversionRatio = 1f) { //How full are we? - float oldPercent = (requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; + float oldPercent = GetHungerPercent(); hunger -= amount; - float newPercent = (requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; + float newPercent = GetHungerPercent(); //Convert food lost into poo at half rate - if (amount < 0 && hunger < requiredCaloriesPerDay) - AddBowel(amount * -1f * conversionRatio * foodToBowelConversion); + if (amount < 0) + { + if(hunger < hungerMeterMax) + AddResource(IncidentType.POOP, amount * -1f * conversionRatio * foodToBowelConversion); + else + // People do stop pooping after days not eating, but a) thats probably not the case and b) its a game. We assume a little poop is produced. + AddResource(IncidentType.POOP, amount * -0.4f * conversionRatio * foodToBowelConversion); + } + //If we go over full, add additional to bowels at half rate if (hunger < 0) { - AddBowel(hunger * -0.5f * conversionRatio * foodToBowelConversion); + AddResource(IncidentType.POOP, hunger * -0.5f * conversionRatio * foodToBowelConversion); hunger = 0f; - newPercent =(requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; + newPercent = GetHungerPercent(); } if (Regression.config.NoHungerAndThirst) @@ -202,11 +489,12 @@ public void AddFood(float amount, float conversionRatio = 1f) } //If we're starving and not eating, take a stamina hit - if (hunger > requiredCaloriesPerDay && amount < 0) + if (hunger > hungerMeterMax && amount < 0) { //Take percentage off stamina equal to percentage above max hunger - Game1.player.stamina += newPercent * Game1.player.MaxStamina; - hunger = requiredCaloriesPerDay; + // Floximo: This is now half as punishing, preventing deadlock situations where the farmer could no longer reach field or town. If intended, this is the place to edit the final values or insert config. + Game1.player.stamina += newPercent * (hungerMeterMax / requiredCaloriesPerDay) * Game1.player.MaxStamina / 2; + hunger = hungerMeterMax; newPercent = 1; } @@ -220,14 +508,20 @@ public void AddWater(float amount, float conversionRatio = 1f) thirst -= amount; float newPercent = (requiredWaterPerDay - thirst) / requiredWaterPerDay; - //Convert water lost into pee at half rate - if (amount < 0 && thirst < requiredWaterPerDay) - AddBladder(amount * -1f * conversionRatio * waterToBladderConversion); + //Convert food lost into poo at half rate + if (amount < 0) + { + if (hunger < requiredWaterPerDay) + AddResource(IncidentType.PEE, amount * -1f * conversionRatio * waterToBladderConversion); + else + // As long as we are not dead, some pee will be generated. We need to filter out toxins. + AddResource(IncidentType.POOP, amount * -0.4f * conversionRatio * waterToBladderConversion); + } //Also if we go over full, add additional to Bladder at half rate if (thirst < 0) { - AddBladder((thirst * -0.5f * conversionRatio * waterToBladderConversion)); + AddResource(IncidentType.PEE, (thirst * -0.5f * conversionRatio * waterToBladderConversion)); thirst = 0f; newPercent = (requiredWaterPerDay - thirst) / requiredWaterPerDay; } @@ -251,119 +545,62 @@ public void AddWater(float amount, float conversionRatio = 1f) Warn(oldPercent, newPercent, THIRST_THRESHOLDS, THIRST_MESSAGES, false); } - //Apply changes to the Maximum capacity of the bladder, and the rate at which it fills. - //Note that Positive percent is a LOSS of continence - public void ChangeBladderContinence(float percent = 0.01f) + //Note that a NEGATIVE percent is a LOSS of continence + public void ChangeContinence(IncidentType type, float percent = 0.01f) { - float previousContinence = bladderContinence; - - //Modify the continence factor (inversely proportional to rate at which the bladder fills) - bladderContinence -= percent; - - //Put a ceiling at 100%, and a floor at 5% - bladderContinence = Math.Max(Math.Min(bladderContinence, 1f), 0.05f); - - //Decrease our maximum capacity (bladder shrinks as we become incontinent) - bladderCapacity = bladderContinence * maxBladderCapacity; - - //Ceiling at base value and floor at 25% base value - bladderCapacity = Math.Max(bladderCapacity, minBladderCapacity); - //OLD: If we're increasing, no need to warn. (maybe we should tell people that they're regaining?) // We now only return if something has changed. Otherwise we can handle changes now in both directions (new) if (percent == 0f) return; + float previousContinence = GetContinence(type); + SetContinence(type, previousContinence + percent); - if (Regression.config.Debug) - Animations.Say(string.Format("Bladder continence changed from {0} to {1}, bladder capacity now {2}", previousContinence, bladderContinence, bladderCapacity), (Body)null); + //Change of bladder capacity is no longer nessesary. Handled by getter. + Regression.monitor.Log(string.Format("{0} continence changed by {1} to {2}, {0} capacity now {3}", type == IncidentType.POOP ? "Bowel" : "Bladder", GetContinence(type) - previousContinence, GetContinence(type), GetCapacity(type)), LogLevel.Debug); //Warn that we may be losing control - Warn(previousContinence, bladderContinence, BLADDER_CONTINENCE_THRESHOLDS, BLADDER_CONTINENCE_MESSAGES, true); - } - - //Apply changes to the Maximum capacity of the bowels, and the rate at which they fill. - public void ChangeBowelContinence(float percent = 0.01f) - { - float previousContinence = bowelContinence; - - //Modify the continence factor (inversely proportional to rate at which the bowels fills) - bowelContinence -= percent; - - //Put a ceiling at 100%, and a floor at 5% - bowelContinence = Math.Max(Math.Min(bowelContinence, 1f), 0.05f); - - //Decrease our maximum capacity (bowel shrinks as we become incontinent) - bowelCapacity = bowelContinence * maxBowelCapacity; - - //Ceiling at base value and floor at 25% base value - bowelCapacity = Math.Max(bowelCapacity, minBowelCapacity); - - //OLD: If we're increasing, no need to warn. (maybe we should tell people that they're regaining?) - // We now only return if something was changed. Otherwise we can handle changes now in both directions (new) - if (percent == 0f) - return; - - if (Regression.config.Debug) - Animations.Say(string.Format("Bowel continence changed from {0} to {1}, bowel capacity now {2}", previousContinence, bowelContinence, bowelCapacity), (Body)null); - - //Inform about major changes - Warn(previousContinence, bowelContinence, BOWEL_CONTINENCE_THRESHOLDS, BOWEL_CONTINENCE_MESSAGES, true); + if(type == IncidentType.POOP) + { + Warn(previousContinence, bowelContinence, BOWEL_CONTINENCE_THRESHOLDS, BOWEL_CONTINENCE_MESSAGES, true); + } + else + { + Warn(previousContinence, bladderContinence, BLADDER_CONTINENCE_THRESHOLDS, BLADDER_CONTINENCE_MESSAGES, true); + } } //Put on underwear and clean pants - private Container ChangeUnderwear(Container container) + private void ChangeUnderwear(Container container) { - Container oldUnderwear = this.underwear; - if (!oldUnderwear.removable) - Animations.Warn(Regression.t.Change_Destroyed, this); - this.underwear = container; - - pants = CreateNewPants(); - CleanPants(); + this.underwear.ResetToDefault(container); Animations.Say(Regression.t.Change, this); - return oldUnderwear; + } + public void ChangeUnderwear(Underwear uw) + { + ChangeUnderwear(uw.container); } public StardewValley.Objects.Clothing GetPantsStardew() { - var farmer = Animations.GetWho(); + var farmer = Animations.player; StardewValley.Objects.Clothing pants = (StardewValley.Objects.Clothing)farmer.pantsItem.Value; if (pants != null) pants.LoadData(); // YES, this is nessesary to load the data of the pants before accessing them... if there are pants (watch out for null) return pants; } - public Container CreateNewPants() + public void ResetPants() { var myPants = GetPantsStardew(); - Container newPants; - Regression.t.Underwear_Options.TryGetValue("blue jeans", out newPants); - var newObject = new Container(newPants); + Container newPants = GetTypeDefault(myPants == null ? "legs" : "blue jeans"); + + pants.ResetToDefault(newPants); + if (myPants != null) { - newObject.name = myPants.displayName; - newObject.description = myPants.description; + pants.displayName = myPants.displayName.ToLower(); + pants.description = myPants.displayName.ToLower(); } - else - { - newObject.name = "Legs"; - newObject.description = "Your two Legs"; - } - return newObject; - } - - public Container ChangeUnderwear(Underwear uw) - { - return ChangeUnderwear(new Container(uw.container.name, uw.container.wetness, uw.container.messiness, uw.container.durability)); - } - - public Container ChangeUnderwear(string type) - { - Container newPants, refPants; - Regression.t.Underwear_Options.TryGetValue("type", out refPants); - newPants = new Container(refPants); - newPants.messiness = 0; - newPants.wetness = 0; - return ChangeUnderwear(newPants); + CleanPants(); } //If we put on our pants, remove wet/messy debuffs @@ -371,6 +608,11 @@ public void CleanPants() { RemoveBuff(WET_DEBUFF); RemoveBuff(MESSY_DEBUFF); + if (Game1.player.dialogueQuestionsAnswered.Contains("dirty_change_yes")) + Game1.player.dialogueQuestionsAnswered.Remove("dirty_change_yes"); + if (Game1.player.dialogueQuestionsAnswered.Contains("dirty_change_no")) + Game1.player.dialogueQuestionsAnswered.Remove("dirty_change_no"); + } public bool HasWetOrMessyDebuff() { @@ -382,16 +624,16 @@ public void DecreaseEverything() { AddWater(requiredWaterPerDay * -0.1f, 0f); AddFood(requiredCaloriesPerDay * -0.1f, 0f); - AddBladder(maxBladderCapacity * -0.1f); - AddBowel(maxBladderCapacity * -0.1f); + AddResource(IncidentType.PEE, maxBladderCapacity * -0.1f); + AddResource(IncidentType.POOP, maxBladderCapacity * -0.1f); } public void IncreaseEverything() { AddWater(requiredWaterPerDay * 0.1f, 0f); AddFood(requiredCaloriesPerDay * 0.1f, 0f); - AddBladder(maxBladderCapacity * 0.1f); - AddBowel(maxBladderCapacity * 0.1f); + AddResource(IncidentType.PEE, maxBladderCapacity * 0.1f); + AddResource(IncidentType.POOP, maxBladderCapacity * 0.1f); } public void DrinkWateringCan() @@ -402,7 +644,7 @@ public void DrinkWateringCan() if (currentTool.WaterLeft * 200 >= thirst) { this.AddWater(thirst); - currentTool.WaterLeft -= (int)(thirst / 200f); + currentTool.WaterLeft -= (int)(thirst * 200f); Animations.AnimateDrinking(false); } else if (currentTool.WaterLeft > 0) @@ -426,191 +668,326 @@ public void DrinkWaterSource() public bool InToilet(bool inUnderwear) { - return !inUnderwear && (Game1.currentLocation is FarmHouse || Game1.currentLocation is JojaMart || Game1.currentLocation is Club || Game1.currentLocation is MovieTheater || Game1.currentLocation is IslandFarmHouse || Game1.currentLocation.Name == "Saloon" || Game1.currentLocation.Name == "Hospital" || Game1.currentLocation.Name == "BathHouse_MensLocker" || Game1.currentLocation.Name == "BathHouse_WomensLocker"); + // I understand that it is important to give a way to go potty somewhere, but thats just plays wrong. + //return !inUnderwear && (Game1.currentLocation is FarmHouse || Game1.currentLocation is JojaMart || Game1.currentLocation is Club || Game1.currentLocation is MovieTheater || Game1.currentLocation is IslandFarmHouse || Game1.currentLocation.Name == "Saloon" || Game1.currentLocation.Name == "Hospital" || Game1.currentLocation.Name == "BathHouse_MensLocker" || Game1.currentLocation.Name == "BathHouse_WomensLocker"); + return !inUnderwear && (Game1.currentLocation is FarmHouse || Game1.currentLocation is IslandFarmHouse || Game1.currentLocation.Name == "BathHouse_MensLocker" || Game1.currentLocation.Name == "BathHouse_WomensLocker"); } public bool InPlaceWithPants() { return Game1.currentLocation is FarmHouse; } + public bool NeedsChangies(IncidentType type) + { + // If the underwear was already used and the capacity remaining is smaller than the size of an accident of this type + return underwear.GetUsed(type) > 0 && underwear.GetCapacity(type) - underwear.GetUsed(type) < GetCapacity(type); + } - public void Mess(bool voluntary = false, bool inUnderwear = true) + public bool IsTryingToHoldIt(IncidentType type, float vsAmount = 0) { - numPottyPooAtNight = 0; - numAccidentPooAtNight = 0; + float capacity = underwear.GetCapacity(type); + float used = underwear.GetUsed(type); + + if (!underwear.removable) return false; // If we don't have pants or training pants, there is no point + if(used > 350) return false; // If the underwear is already heavily used, we stop trying + if(used > GetCapacity(type) / 3) return false; // If its more than 1/3 our bladder/bowel size already, we stop trying + if ((vsAmount + used) > capacity) return false; // If the underwear would be more than full, there is no point + + return true; + } + // Minor incident on very full bladder/bowel. Balances the players chances to get to the potty, even if that means minor incidents. Also obviously cute + public bool MinorAccident(IncidentType type) + { + float capacity = GetCapacity(type); + float fullness = GetFullness(type); + float fullnessPercent = fullness / capacity; + if (fullnessPercent < lastWarningThreshold) return false; // Just to make it easily readable that this is for after and inside the last warning threshold + if (fullnessPercent > 1.1f) return false; // If its too much, leaking will not do + + // We can lose maximal the amount until the last warning threshold, because we would trigger that warning again. This only happens after the last warning anyway. + float amount = Math.Min((fullnessPercent - lastWarningThreshold - 0.01f) * capacity, GetMaxCapacity(type) * 0.8f); + if (!IsTryingToHoldIt(type, amount)) return false; + + if (type == IncidentType.POOP) + { + Animations.AnimateMessingMinor(this); + } + else + { + Animations.AnimateWettingMinor(this); + } + + ChangeContinence(type, CalculateContinenceLossOrGain(type, false, true, amount / GetMaxCapacity(type))); + AddAccidentFromFullness(type, amount); + return true; + //AddMess(amountToLose); + //_ = this.pants.AddPoop(this.underwear.AddPoop(bowelFullness)); + } + public void ChangeFullness(IncidentType type, float amount) + { + // We intentionally allow fullness over max + switch (type) + { + case IncidentType.PEE: + SetFullness(type, bladderFullness + amount); + break; + case IncidentType.POOP: + SetFullness(type, bowelFullness + amount); + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public void AddAccidentFromFullness(IncidentType type, float amount) + { + ChangeFullness(type, -amount); + AddAccident(type, amount); + } + public void AddAccident(IncidentType type, float amount) + { + switch (type) + { + case IncidentType.PEE: + if (isSleeping) + { + _ = this.bed.AddPee(this.underwear.AddPee(amount)); + } + else + { + _ = this.pants.AddPee(this.underwear.AddPee(amount)); + } + break; + case IncidentType.POOP: + if (isSleeping) + { + _ = this.bed.AddPoop(this.underwear.AddPoop(amount)); + } + else + { + _ = this.pants.AddPoop(this.underwear.AddPoop(amount)); + } + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + + } + public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear = true) + { + float attemptThreshold = GetAttemptThreshold(type); + float capacity = GetCapacity(type); + float fullness = GetFullness(type); + + float maxCapacity = GetMaxCapacity(type); // yes, this is the maximum capacity a bladder/bowel can have, used for changing continence + //If we're sleeping check if we have an accident or get up to use the potty if (isSleeping) { - //When we're sleeping, our bowel fullness can exceed our capacity since we calculate for the whole night at once - //Hehehe, this may be evil, but with a smaller bladder, you'll have to pee multiple times a night + //When we're sleeping, our fullness can exceed our capacity since we calculate for the whole night at once + //Hehehe, this may be evil, but with a smaller bladder/bowel, you'll have to go multiple times a night //So roll the dice each time >:) //: Give stamina penalty every time you get up to go potty. Since you disrupted sleep. - int numMesses = (int)((bowelFullness - GetBowelAttemptThreshold()) / bowelCapacity); - float additionalAmount = bowelFullness - (numMesses * bowelCapacity); - int numAccidents = 0; + int numIncidentAmount = (int)((fullness - attemptThreshold) / capacity); + float additionalAmount = fullness - (numIncidentAmount * capacity); + int numAccident = 0; int numPotty = 0; if (additionalAmount > 0) - numMesses++; + numIncidentAmount++; - for (int i = 0; i < numMesses; i++) + for (int i = 0; i < numIncidentAmount; i++) { + float adjustedContinence = GetContinence(type) - GetContinenceMin(type); //Randomly decide if we get up. Less likely if we have lower continence - bool lclVoluntary = voluntary || Regression.rnd.NextDouble() < (double)this.bowelContinence; - StartWetting(lclVoluntary && underwear.removable, true); //Always in underwear in bed - float amountToLose = (i != numMesses - 1) ? bowelCapacity : additionalAmount; + //Up to 80% control we never have accidents and at min-continence we always have accidents + bool lclVoluntary = voluntary || GetContinence(type) > 0.8f || adjustedContinence > 0 && Regression.rnd.NextDouble() < adjustedContinence; + StartAccident(type, lclVoluntary && underwear.removable, true); //Always in underwear in bed + float amountToLose = (i != numIncidentAmount - 1) ? capacity : additionalAmount; if (!lclVoluntary) { - numAccidents++; + numAccident++; + ChangeContinence(type, CalculateContinenceLossOrGain(type, voluntary, inUnderwear, amountToLose / maxCapacity)); // maxCapacity is correct, for balancing reasons //Any overage in the container, add to the pants. Ignore overage over that. //When sleeping, the pants are actually the bed - _ = this.bed.AddPoop(this.pants.AddPoop(this.underwear.AddPoop(amountToLose))); - bowelFullness -= amountToLose; - + AddAccidentFromFullness(type, amountToLose); } else { - numPotty++; - bowelFullness -= amountToLose; + numPotty++; // we still count it as potty success to generate the message later (to know if we even tried) if (!underwear.removable) //Certain underwear can't be taken off to use the toilet (ie diapers) { - _ = this.bed.AddPoop(this.pants.AddPoop(this.underwear.AddPoop(amountToLose))); - numAccidents++; + numAccident++; + ChangeContinence(type, CalculateContinenceLossOrGain(type, voluntary, inUnderwear, amountToLose / maxCapacity)); // maxCapacity is correct, for balancing reasons + AddAccidentFromFullness(type, amountToLose); + } + else + { + ChangeFullness(type, -amountToLose); } } } - numPottyPooAtNight = numPotty; - numAccidentPooAtNight = numAccidents; + switch (type) + { + case IncidentType.PEE: + numPottyPeeAtNight = numPotty; + numAccidentPeeAtNight = numAccident; + break; + case IncidentType.POOP: + numPottyPooAtNight = numPotty; + numAccidentPooAtNight = numAccident; + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } else if (inUnderwear) { - - StartMessing(voluntary, true); //Always in underwear in bed - //Any overage in the container, add to the pants. Ignore overage over that. - - if (bowelFullness >= GetBowelAttemptThreshold()) + StartAccident(type,voluntary, true); + bool attemptOnly = fullness < attemptThreshold; + if (!attemptOnly) { - _ = this.pants.AddPoop(this.underwear.AddPoop(bowelFullness)); - this.bowelFullness = 0.0f; + ChangeContinence(type, CalculateContinenceLossOrGain(type, voluntary, inUnderwear, fullness / maxCapacity)); // yes this is correct, we do relative to max bladder to temper loss on near no control (and frequent accidents) + AddAccidentFromFullness(type, fullness); } + FinalizeAccident(type, voluntary, true, attemptOnly); // Trying in your underwear is different, people might be acting differently } else { - StartMessing(voluntary, false); + if (underwear.removable) { - if (bowelFullness >= GetBowelAttemptThreshold()) + bool attemptOnly = fullness < attemptThreshold; + StartAccident(type, voluntary, false); + if (!attemptOnly) { - this.bowelFullness = 0.0f; + ChangeContinence(type, CalculateContinenceLossOrGain(type, voluntary, inUnderwear, fullness / capacity)); // yes this is correct, its capacity as the gain (for making it) should be relative to the bladder state, not max + ChangeFullness(type, -fullness); } + FinalizeAccident(type, voluntary, true, attemptOnly); // Trying in your underwear is different, people might be acting differently } - } - } - - public void StartMessing(bool voluntary = false, bool inUnderwear = true) - { - if (!Regression.config.Messing) - return; - - if (bowelFullness < GetBowelAttemptThreshold()) - { - Animations.AnimatePoopAttempt(this, inUnderwear); - } - else - { - //If we have an accident (not voluntary), decrease continence - //If we use the potty before we REALLY have to go (we go before we reach some threshold), increase continence - //Otherwise, if it is voluntary but waited until we almost had an accident (fullness above some threshold) don't change anything - if (!voluntary) - this.ChangeBowelContinence(0.01f * Regression.config.BowelLossContinenceRate * situationMultiplier(voluntary, inUnderwear)); - else if (bowelFullness > GetBowelTrainingThreshold()) - this.ChangeBowelContinence(-0.01f * Regression.config.BowelGainContinenceRate * situationMultiplier(voluntary, inUnderwear)); - - Animations.AnimateMessingStart(this, voluntary, inUnderwear); } - - Animations.AnimateMessingEnd(this); - if (!this.InToilet(inUnderwear)) - _ = Animations.HandleVillager(this, true, inUnderwear, pants.messiness > 0.0, false); - if (pants.messiness <= 0.0 || !inUnderwear) - return; - HandlePoopOverflow(); } - - private void HandlePoopOverflow() + public void Mess(bool voluntary = false, bool inUnderwear = true) { - if (isSleeping) - return; - - Animations.Write(Regression.t.Poop_Overflow, this, Animations.poopAnimationTime); - float howMessy = pants.messiness / pants.containment; - int speedReduction = howMessy >= 0.5 ? (howMessy > 1.0 ? -3 : -2) : -1; - Buff buff = new Buff(id: MESSY_DEBUFF, displayName: "Messy", effects: new BuffEffects() { - Speed = { speedReduction } - }) - { - description = string.Format("{0} {1} Speed.", Strings.RandString(Regression.t.Debuff_Messy_Pants), (object)speedReduction), - millisecondsDuration = 1080000, - glow = Color.Brown - }; - if (Game1.player.hasBuff(MESSY_DEBUFF)) - this.RemoveBuff(MESSY_DEBUFF); - Game1.player.applyBuff(buff); + Accident(IncidentType.POOP,voluntary,inUnderwear); } - public float situationMultiplier(bool voluntary, bool inUnderwear) + public void StartAccident(IncidentType type, bool voluntary = false, bool inUnderwear = true) { - float multiplier = 1.0f; - // If we are sleeping, night time modifiers apply. As the player is no longer in charge we use other values for game balance reasons - if (isSleeping) + switch (type) { - multiplier = (voluntary ? (float)Regression.config.NighttimeGainMultiplier : (float)Regression.config.NighttimeLossMultiplier) / 100f; + case IncidentType.PEE: + if (!Regression.config.Wetting) return; + break; + case IncidentType.POOP: + if (!Regression.config.Messing) return; + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); } - // InToilet does its own checks, making sure it's a valid use of the toilet. Handled differently, usually giving a gain bonus. Loss doesn't mather as the function checks on valid attempts. - else if (InToilet(inUnderwear)) + float attemptThreshold = GetAttemptThreshold(type); + float fullness = GetFullness(type); + + if (fullness < attemptThreshold) { - multiplier = (float)Regression.config.ToiletGainMultiplier / 100f; + switch (type) + { + case IncidentType.PEE: + Animations.AnimatePeeAttempt(this, inUnderwear); + break; + case IncidentType.POOP: + Animations.AnimatePoopAttempt(this, inUnderwear); + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } } - // If we voluntary pee/poop our pants, this adds situational modifiers. Usually negates possible gains or at least reduces them. - else if(voluntary && inUnderwear) + else { - multiplier = (float)Regression.config.GoingVoluntaryInUnderwearGainMultiplier / 100f; + switch (type) + { + case IncidentType.PEE: + Animations.AnimateWettingStart(this, voluntary, inUnderwear); + break; + case IncidentType.POOP: + Animations.AnimateMessingStart(this, voluntary, inUnderwear); + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + switch (type) + { + case IncidentType.PEE: + Animations.AnimateWettingEnd(this); + break; + case IncidentType.POOP: + Animations.AnimateMessingEnd(Game1.player); + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); } - - return multiplier; } - - public void StartWetting(bool voluntary = false, bool inUnderwear = true) + // percentLost: The amount of gain or loss is dependend on how much percent of the maxBladder or maxBowel we lost + // This allowes for small gains or losses on small accidents and reduces edge cases + public float CalculateContinenceLossOrGain(IncidentType type, bool voluntary, bool inUnderwear, float percentLost) { + float fullness = GetFullness(type); - if ((double)bladderFullness < GetBladderAttemptThreshold()) + int rate; + if (voluntary && !inUnderwear) { - Animations.AnimatePeeAttempt(this, inUnderwear); + rate = type == IncidentType.POOP ? Regression.config.BowelGainContinenceRate : Regression.config.BladderGainContinenceRate; } else { - //If we have an accident (not voluntary), decrease continence - //If we use the potty before we REALLY have to go (we go before we reach some threshold), increase continence - //Otherwise, if it is voluntary but waited until we almost had an accident (fullness above some threshold) don't change anything - if (!voluntary) - this.ChangeBladderContinence(0.01f * (float)Regression.config.BladderLossContinenceRate * situationMultiplier(voluntary, inUnderwear)); - else if(bladderFullness > GetBladderTrainingThreshold()) - this.ChangeBladderContinence(-0.01f * (float)Regression.config.BladderGainContinenceRate * situationMultiplier(voluntary, inUnderwear)); - Animations.AnimateWettingStart(this, voluntary, inUnderwear); + rate = type == IncidentType.POOP ? Regression.config.BowelLossContinenceRate : Regression.config.BladderLossContinenceRate; } - Animations.AnimateWettingEnd(this); + + //If we have an accident (not voluntary) or just go in our pants, decrease continence + if (!voluntary || inUnderwear) + return -0.01f * rate * percentLost * situationMultiplier(voluntary, inUnderwear); + else if (fullness > GetTrainingThreshold(type) && InToilet(inUnderwear)) //If we REALLY hafe to go AND use toilet, increase continence + return 0.01f * rate * percentLost * situationMultiplier(voluntary, inUnderwear); + else + { + //Otherwise, if it is voluntary but just peed/pooped on the ground, don't change anything + return 0f; + } + } + private void FinalizeAccident(IncidentType type, bool voluntary = false, bool inUnderwear = true, bool attemptOnly = false) + { + var dirt = type == IncidentType.POOP ? pants.messiness : pants.wetness; if (!this.InToilet(inUnderwear)) - _ = Animations.HandleVillager(this, false, inUnderwear, pants.wetness > 0.0, false); - if ((pants.wetness <= 0.0 || !inUnderwear)) + _ = Animations.HandleVillager(this, type == IncidentType.POOP, inUnderwear, dirt > 0, false); + if (attemptOnly || dirt <= 0.0 || !inUnderwear) return; - HandlePeeOverflow(); + HandleOverflow(type); } - private void HandlePeeOverflow() + + private void HandleOverflow(IncidentType type) { if (isSleeping) return; - Animations.Write(Regression.t.Pee_Overflow, this, Animations.peeAnimationTime); + switch (type) + { + case IncidentType.PEE: + _HandlePeeOverflow(); + break; + case IncidentType.POOP: + _HandlePoopOverflow(); + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + // Overflow functions are so different that it is less confusing to keep them as-is + + private void _HandlePeeOverflow() + { + Animations.Write(Regression.t.Pee_Overflow, this,null, Animations.peeAnimationTime); int defenseReduction = -Math.Max(Math.Min((int)(pants.wetness / pants.absorbency * 10.0), 10), 1); @@ -628,103 +1005,71 @@ private void HandlePeeOverflow() Game1.player.applyBuff(buff); } - public void Wet(bool voluntary = false, bool inUnderwear = true) + private void _HandlePoopOverflow() { - if (!Regression.config.Wetting) - return; - - numPottyPeeAtNight = 0; - numAccidentPeeAtNight = 0; - //If we're sleeping check if we have an accident or get up to use the potty + Animations.Write(Regression.t.Poop_Overflow, this,null, Animations.poopAnimationTime); + float howMessy = pants.messiness / pants.containment; + int speedReduction = howMessy >= 0.5 ? (howMessy > 1.0 ? -3 : -2) : -1; + Buff buff = new Buff(id: MESSY_DEBUFF, displayName: "Messy", effects: new BuffEffects() { + Speed = { speedReduction } + }) + { + description = string.Format("{0} {1} Speed.", Strings.RandString(Regression.t.Debuff_Messy_Pants), (object)speedReduction), + millisecondsDuration = 1080000, + glow = Color.Brown + }; + if (Game1.player.hasBuff(MESSY_DEBUFF)) + this.RemoveBuff(MESSY_DEBUFF); + Game1.player.applyBuff(buff); + } + public float situationMultiplier(bool voluntary, bool inUnderwear) + { + float multiplier = 1.0f; + // If we are sleeping, night time modifiers apply. As the player is no longer in charge we use other values for game balance reasons if (isSleeping) { - //When we're sleeping, our bladder fullness can exceed our capacity since we calculate for the whole night at once - //Hehehe, this may be evil, but with a smaller bladder, you'll have to pee multiple times a night - //So roll the dice each time >:) - int numWettings = (int)((bladderFullness - GetBladderAttemptThreshold()) / bladderCapacity); - float additionalAmount = bladderFullness - (numWettings * bladderCapacity); - int numAccidents = 0; - int numPotty = 0; - - if (additionalAmount > 0) - numWettings++; - - for (int i = 0; i < numWettings; i++) - { - //Randomly decide if we get up. Less likely if we have lower continence - bool lclVoluntary = voluntary || Regression.rnd.NextDouble() < (double)this.bladderContinence; - StartWetting(lclVoluntary && underwear.removable, true); //Always in underwear in bed - float amountToLose = (i != numWettings - 1) ? bladderCapacity : additionalAmount; - if (!lclVoluntary) - { - numAccidents++; - //Any overage in the container, add to the pants. Ignore overage over that. - //When sleeping, the pants are actually the bed - _ = this.bed.AddPee(this.pants.AddPee(this.underwear.AddPee(amountToLose))); - bladderFullness -= amountToLose; - - } - else - { - numPotty++; - bladderFullness -= amountToLose; - if (!underwear.removable) //Certain underwear can't be taken off to use the toilet (ie diapers) - { - _ = this.bed.AddPee(this.pants.AddPee(this.underwear.AddPee(amountToLose))); - numAccidents++; - } - } - } - numPottyPeeAtNight = numPotty; - numAccidentPeeAtNight = numAccidents; + multiplier = (voluntary ? (float)Regression.config.NighttimeGainMultiplier : (float)Regression.config.NighttimeLossMultiplier) / 100f; } - else if (inUnderwear) - { - StartWetting(voluntary, true); - //Any overage in the container, add to the pants. Ignore overage over that. - if (bladderFullness >= GetBladderAttemptThreshold()) - { - _ = this.pants.AddPee(this.underwear.AddPee(bladderFullness)); - this.bladderFullness = 0.0f; - } - } else + else if (voluntary && inUnderwear) { - StartWetting(voluntary, false); - if (underwear.removable) { - if (bladderFullness >= GetBladderAttemptThreshold()) - { - this.bladderFullness = 0.0f; - } - } + multiplier *= (Regression.config.InUnderwearOnPurposeMultiplier / 100f); } - if (bladderFullness < 0) bladderFullness = 0; + + return multiplier; + } + public void WetAndMess(bool voluntary = false, bool inUnderwear = true) + { + Wet(voluntary, inUnderwear); + Mess(voluntary, inUnderwear); + } + public void Wet(bool voluntary = false, bool inUnderwear = true) + { + Accident(IncidentType.PEE,voluntary,inUnderwear); } public void HandleMorning() { isSleeping = false; + var dryingTime = 0; if (Regression.config.Easymode) { hunger = 0; thirst = 0; - bed.dryingTime = 0; } else { Farmer player = Game1.player; - if (bed.messiness > 0.0 || bed.wetness > 0.0) + if (bed.messiness > 0.0) { - bed.dryingTime = 1000; - player.stamina -= 20f; + dryingTime = 800; + player.stamina -= 60f; } else if (bed.wetness > 0.0) { - bed.dryingTime = 600; - player.stamina -= 10f; + dryingTime = 600; + player.stamina -= 40f; } - else - bed.dryingTime = 0; int timesUpAtNight = Math.Max(numPottyPeeAtNight, numPottyPooAtNight); player.stamina -= (timesUpAtNight * wakeUpPenalty); @@ -732,7 +1077,8 @@ public void HandleMorning() } Animations.AnimateMorning(this); - bed.Wash(); + bed.Wash(dryingTime); + ResetPants(); } public void HandleNight() @@ -746,6 +1092,13 @@ public void HandleNight() const int wakeUpTime = timeInDay + 600; const float sleepRate = 3.0f; //Let's say body functions change @ 1/3 speed while sleeping. Arbitrary. int timeSlept = wakeUpTime - bedtime; //Bedtime will never exceed passout-time of 2:00AM (2600) + + // Resets + numPottyPeeAtNight = 0; + numAccidentPeeAtNight = 0; + numPottyPooAtNight = 0; + numAccidentPooAtNight = 0; + HandleTime(timeSlept / 100.0f / sleepRate); } @@ -773,7 +1126,7 @@ public void HandleTime(float hours) this.AddFood((float)(requiredCaloriesPerDay * (double)hours / -18.67)); } - public bool IsFishing() + public static bool IsFishing() { FishingRod currentTool; return (currentTool = Game1.player.CurrentTool as FishingRod) != null && (currentTool.isCasting || currentTool.isTimingCast || (currentTool.isNibbling || currentTool.isReeling) || currentTool.castedButBobberStillInAir || currentTool.pullingOutOfWater); @@ -828,19 +1181,35 @@ public void Warn(float oldPercent, float newPercent, float[] thresholds, string[ Animations.Warn(messages, this); } - // Expand Consumables to add food. But we'd need a lot more info. For now, treat all food the same. - public void Consume(string itemName) + + public void Consume(Item item) { - Consumable item; - if(Animations.GetData().Consumables.TryGetValue(itemName, out item)) + // It seams like the worth in health recovery is twice + var foodWorth = item.staminaRecoveredOnConsumption() + item.healthRecoveredOnConsumption() * 2; + // This value ends up 25 + 22 = 47 for green beans, parsnip, potatoes and 50 + 44 = 94 for kale and is used as a messure of effective food in the game. As such a good start for our calculation. + // Cooked foods naturally have higher values, for example stir fry, having: 38 17 cave carrot + 30 13 mushroom + 50 22 kale + 25 11 oil (corn) = 143 63 ingredien worth => 200 90 as Stir Fry + // => As we double the health value this is 200 + 180 = 380 + // Having a base value, we can now freely choose a muliplier to control the difficulty of survival. If we go from Stir fry, a difficult dish that definitly should fill us up for the day (days are short), should be around 3500 kcal = 9,2 muliplier. + // We go with 10 should be more than difficult already, as that means a parsnip/potato/... has only 470 calories anyway, 940 for kale + foodWorth = foodWorth * 10; + + string itemName = item.Name; + Consumable consumable; + if (Animations.Data.Consumables.TryGetValue(itemName, out consumable)) { - this.AddFood(item.calorieContent); - this.AddWater(item.waterContent); - } else + this.AddWater(consumable.waterContent); + } + else { - this.AddFood(400); this.AddWater(10); } + + this.AddFood(foodWorth); } } + public enum IncidentType + { + PEE = 0, + POOP = 1 + } } diff --git a/Regression/PrimevalTitmouse/Config.cs b/Regression/PrimevalTitmouse/Config.cs index 37caef8..cde756c 100644 --- a/Regression/PrimevalTitmouse/Config.cs +++ b/Regression/PrimevalTitmouse/Config.cs @@ -2,23 +2,37 @@ { public class Config { - public bool AlwaysNoticeAccidents; - public bool Debug; - public bool Easymode; - public string Lang; - public bool PantsChangeRequiresHome; - public bool Messing; - public int FriendshipPenaltyBladderMultiplier; - public int FriendshipPenaltyBowelMultiplier; - public bool NoHungerAndThirst; - public bool Wetting; - public int ToiletGainMultiplier; - public int NighttimeLossMultiplier; - public int NighttimeGainMultiplier; - public int GoingVoluntaryInUnderwearGainMultiplier; - public int BladderLossContinenceRate; - public int BowelLossContinenceRate; - public int BladderGainContinenceRate; - public int BowelGainContinenceRate; + public bool AlwaysNoticeAccidents = true; + public bool Debug = false; + public bool Easymode = false; + public string Lang = "en"; + public bool PantsChangeRequiresHome = true; + public bool UnderwearChangeCauseExposure = true; + public bool Wetting = true; + public bool Messing = true; + public int FriendshipPenaltyBladderMultiplier = 100; + public int FriendshipPenaltyBowelMultiplier = 200; + public bool NoHungerAndThirst = false; + public int NighttimeLossMultiplier = 50; + public int NighttimeGainMultiplier = 50; + public int InUnderwearOnPurposeMultiplier = 50; + public int BladderLossContinenceRate = 2; + public int BowelLossContinenceRate = 4; + public int BladderGainContinenceRate = 3; + public int BowelGainContinenceRate = 4; + public int MaxBladderCapacity = 600; + public int MaxBowelCapacity = 1000; + public int StartBladderContinence = 70; + public int StartBowelContinence = 90; + public bool ReadSaveFiles = true; + public bool WriteSaveFiles = false; + + public int KeyGoInPants = 0; + public int KeyPee = 112; + public int KeyPoop = 113; + public int KeyGoInToilet = 0; + public int KeyPeeInToilet = 112; + public int KeyPoopInToilet = 113; + } } diff --git a/Regression/PrimevalTitmouse/Container.cs b/Regression/PrimevalTitmouse/Container.cs index f28625d..4ea4e7f 100644 --- a/Regression/PrimevalTitmouse/Container.cs +++ b/Regression/PrimevalTitmouse/Container.cs @@ -1,26 +1,152 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using System.Text.Json.Serialization; +using System.Threading; +using System.Xml.Serialization; +using Netcode; +using StardewModdingAPI; using StardewValley; -using static StardewValley.Minigames.MineCart.Whale; +using StardewValley.Mods; namespace PrimevalTitmouse { public class Container { - public float absorbency; - public float containment; - public string description; - public float messiness; - public string name; - public bool plural; - public int price; - public int spriteIndex; - public bool washable; - public float wetness; - public int dryingTime; - public bool removable; - public int durability; + + public static readonly string modDataAdd = "Container"; + private string modDataBaseKey; // comes from the parent + private ModDataDictionary modDataDictionary; // also comes from the parent + + private void save(string varName, string val) + { + if (modDataDictionary == null) return; + modDataDictionary[BuildKeyFor(varName)] = val; + } + private void save(string varName, int val) + { + if (modDataDictionary == null) return; + modDataDictionary[BuildKeyFor(varName)] = val.ToString(); + } + private void save(string varName, float val) + { + if (modDataDictionary == null) return; + modDataDictionary[BuildKeyFor(varName)] = val.ToString(); + } + private void save(string varName, bool val) + { + if (modDataDictionary == null) return; + modDataDictionary[BuildKeyFor(varName)] = val.ToString(); + } + private void save(string varName, Date val) + { + if (modDataDictionary == null) return; + modDataDictionary[BuildKeyFor(varName)] = serializeDryingDate(val); + } + + private string LoadString(string varName, string defaultVal) + { + if (!HasKeyFor(varName)) return defaultVal; + return modDataDictionary[BuildKeyFor(varName)]; + } + private int LoadInt(string varName, int defaultVal) + { + if (!HasKeyFor(varName)) return defaultVal; + return int.Parse(modDataDictionary[BuildKeyFor(varName)]); + } + + private float LoadFloat(string varName, float defaultVal) + { + if (!HasKeyFor(varName)) return defaultVal; + return float.Parse(modDataDictionary[BuildKeyFor(varName)]); + } + private bool LoadBool(string varName, bool defaultVal) + { + if (!HasKeyFor(varName)) return defaultVal; + return bool.Parse(modDataDictionary[BuildKeyFor(varName)]); + } + private Date LoadDate(string varName, Date defaultVal) + { + if (!HasKeyFor(varName)) return defaultVal; + return parseDryingDate(modDataDictionary[BuildKeyFor(varName)]); + } + private string BuildKeyFor(string varName) + { + return BuildKeyFor(varName, modDataBaseKey); + } + public static string BuildKeyFor(string varName, string modDataBaseKey) + { + return $"{modDataBaseKey}/{modDataAdd}/{varName}"; + } + private bool HasKeyFor(string varName) + { + return modDataDictionary != null && modDataDictionary.ContainsKey(BuildKeyFor(varName)); + } + + + // Here starts the block that contains all values we have to save + + private string _name = ""; + public string name + { + get => LoadString("name", _name); + set + { + save("name", value); + _name = value; + } + } + + private string _displayName = ""; + public string displayName + { + get => LoadString("displayName", _displayName == "" ? name : _displayName); + set + { + save("displayName", value); + _displayName = value; + } + } + private int _durability; + public int durability + { + get => LoadInt("durability", _durability); + set + { + save("durability", value); + _durability = value; + } + } + private float _messiness; + public float messiness + { + get => LoadFloat("messiness", _messiness); + set + { + save("messiness", value); + _messiness = value; + } + } + private float _wetness; + public float wetness + { + get => LoadFloat("wetness", _wetness); + set + { + save("wetness", value); + _wetness = value; + } + } + public string description { get => _innerContainer != null && _description == null ? _innerContainer.description : _description; set => _description = value; } + + public bool stackable + { + get + { + return !used && !drying && (InnerContainer == null || durability == InnerContainer.durability); + } + } public struct Date { public int time; @@ -28,19 +154,141 @@ public struct Date public int season; public int year; } + private string _timeWhenDoneDrying = ""; + public Date timeWhenDoneDrying + { + get => parseDryingDate(LoadString("timeWhenDoneDrying", _timeWhenDoneDrying)); + set + { + save("timeWhenDoneDrying", value); + _timeWhenDoneDrying = serializeDryingDate(value); + } + } + public static Date parseDryingDate(string date) + { + var dateObj = new Date(); + if (date == "") + { + dateObj.time = 0; + dateObj.day = 0; + dateObj.season = 0; + dateObj.year = 0; + return dateObj; + } + + string[] splitted = date.Split("-"); + dateObj.time = int.Parse(splitted[0]); + dateObj.day = int.Parse(splitted[1]); + dateObj.season = int.Parse(splitted[2]); + dateObj.year = int.Parse(splitted[3]); + + return dateObj; + } + public static string serializeDryingDate(Date timeWhenDoneDrying) + { + return string.Format("{0}-{1}-{2}-{3}", timeWhenDoneDrying.time, timeWhenDoneDrying.day, timeWhenDoneDrying.season, timeWhenDoneDrying.year); + } + public bool drying { + get + { + if (timeWhenDoneDrying.Equals(new Date())) return false; + Date currentDate; + currentDate.time = Game1.timeOfDay; + currentDate.day = Game1.dayOfMonth; + currentDate.season = Utility.getSeasonNumber(Game1.currentSeason); + currentDate.year = Game1.year; + + bool yearEq = currentDate.year == timeWhenDoneDrying.year; + bool seasonEq = currentDate.season == timeWhenDoneDrying.season; + bool dayEq = currentDate.day == timeWhenDoneDrying.day; + bool timeEq = currentDate.time == timeWhenDoneDrying.time; + bool yearGt = currentDate.year > timeWhenDoneDrying.year; + bool seasonGt = currentDate.season > timeWhenDoneDrying.season; + bool dayGt = currentDate.day > timeWhenDoneDrying.day; + bool timeGt = currentDate.time > timeWhenDoneDrying.time; + if ((yearGt) || (yearEq && seasonGt) || (yearEq && seasonEq && dayGt) || (yearEq && seasonEq && dayEq && (timeGt || timeEq))) + { + timeWhenDoneDrying = new Date(); + wetness = 0; + messiness = 0; + return false; + } + return true; + } + } + + + // Here starts the block that contains all values we can take from type + private string _description; + private float _absorbency; + private float _containment; + private bool _plural; + private int _price; + private int _spriteIndex; + private bool _washable; + private int _dryingTime; + private bool _removable; - public Date timeWhenDoneDrying; - private bool drying = false; + + public float absorbency { get => InnerContainer != null ? InnerContainer.absorbency : _absorbency; set => _absorbency = value; } + public float containment { get => InnerContainer != null ? InnerContainer.containment : _containment; set => _containment = value; } + public bool plural { get => InnerContainer != null ? InnerContainer.plural : _plural; set => _plural = value; } + public int price { get => InnerContainer != null ? InnerContainer.price : _price; set => _price = value; } + public int spriteIndex { get => InnerContainer != null ? InnerContainer.spriteIndex : _spriteIndex; set => _spriteIndex = value; } + public bool washable { get => InnerContainer != null ? InnerContainer.washable : _washable; set => _washable = value; } + public int dryingTime { get => InnerContainer != null ? InnerContainer.dryingTime : _dryingTime; set => _dryingTime = value; } + public bool removable { get => InnerContainer != null ? InnerContainer.removable : _removable; set => _removable = value; } + + public bool used { get => wetness > 0 || messiness > 0; } + public bool used_bad { get => wetness > (absorbency / 2f) || messiness > 0; } + private Container _innerContainer = null; + public Container InnerContainer + { + get + { + if(_innerContainer == null && modDataDictionary != null) + { + _innerContainer = GetTypeDefault(name); + } + + return _innerContainer; + } + } //This class describes anything that we could wet/mess in. Usually underwear, but it could also be something like the bed. //These functions are pretty self-explanatory public Container() { wetness = 0.0f; messiness = 0.0f; - drying = false; } - public Container(string type) + // in this case we have a parent. We keep track and update this parent for network sync purposes + public Container(Underwear underwear, string fallbackType) + { + modDataBaseKey = Underwear.modDataKey; + modDataDictionary = underwear.modData; + } + public Container(Body body,string subtype, string fallbackType) + { + modDataBaseKey = Body.modDataPrefix + "/" + subtype; + modDataDictionary = Game1.player.modData; + if(name == "") + { + // Regression.monitor.Log($"{modDataBaseKey} for body had no name, so fallback {fallbackType} was used"); + ResetToDefault(fallbackType); + } + } + public Container(NPC npc, string subtype, string fallbackType) + { + modDataBaseKey = "NPC/" + subtype; + modDataDictionary = npc.modData; + if (name == "") + { + //Regression.monitor.Log($"{modDataBaseKey} for {npc.Name} had no name, so fallback {fallbackType} was used"); + ResetToDefault(fallbackType); + } + } + /*public Container(string type) { Container c; @@ -60,9 +308,8 @@ public Container(string type, float wetness, float messiness, int durability) { this.wetness = 0.0f; this.messiness = 0.0f; - drying = false; Initialize(type, wetness, messiness, durability); - } + }*/ public string GetPrefix() { @@ -70,7 +317,7 @@ public string GetPrefix() return "a"; } - public void Wash() + public void Wash(int dryingTimeOverwrite = -1) { if (washable) { @@ -78,27 +325,28 @@ public void Wash() { durability--; } - drying = true; - timeWhenDoneDrying.time = Game1.timeOfDay + dryingTime; - timeWhenDoneDrying.day = Game1.dayOfMonth; - timeWhenDoneDrying.season = Utility.getSeasonNumber(Game1.currentSeason); - timeWhenDoneDrying.year = Game1.year; + var done = new Date(); + done.time = Game1.timeOfDay + (dryingTimeOverwrite == -1 ? dryingTime : dryingTimeOverwrite); + done.day = Game1.dayOfMonth; + done.season = Utility.getSeasonNumber(Game1.currentSeason); + done.year = Game1.year; - if(timeWhenDoneDrying.time >= 2400) + if(done.time >= 2400) { - timeWhenDoneDrying.time -= 2400; - timeWhenDoneDrying.day += 1; + done.time -= 2400; + done.day += 1; } - if(timeWhenDoneDrying.day > 28) + if(done.day > 28) { - timeWhenDoneDrying.day -= 28; - timeWhenDoneDrying.season += 1; + done.day -= 28; + done.season += 1; } - if(timeWhenDoneDrying.season > 4) + if(done.season > 4) { - timeWhenDoneDrying.season -= 4; - timeWhenDoneDrying.year += 1; + done.season -= 4; + done.year += 1; } + timeWhenDoneDrying = done; } } @@ -107,31 +355,6 @@ public bool MarkedForDestroy() return (durability == 0)&&washable; } - public bool IsDrying() - { - if (!drying) return false; - Date currentDate; - currentDate.time = Game1.timeOfDay; - currentDate.day = Game1.dayOfMonth; - currentDate.season = Utility.getSeasonNumber(Game1.currentSeason); - currentDate.year = Game1.year; - - bool yearEq = currentDate.year == timeWhenDoneDrying.year; - bool seasonEq = currentDate.season == timeWhenDoneDrying.season; - bool dayEq = currentDate.day == timeWhenDoneDrying.day; - bool timeEq = currentDate.time == timeWhenDoneDrying.time; - bool yearGt = currentDate.year > timeWhenDoneDrying.year; - bool seasonGt = currentDate.season > timeWhenDoneDrying.season; - bool dayGt = currentDate.day > timeWhenDoneDrying.day; - bool timeGt = currentDate.time > timeWhenDoneDrying.time; - if ((yearGt) || (yearEq && seasonGt) || (yearEq && seasonEq && dayGt) || (yearEq && seasonEq && dayEq && (timeGt || timeEq))) - { - drying = false; - wetness = 0; - messiness = 0; - } - return drying; - } public float AddPee(float amount) { @@ -156,58 +379,58 @@ public float AddPoop(float amount) } return 0.0f; } - - private void Initialize(Container c, float wetness, float messiness, int durability) - { - name = c.name; - description = c.description; - absorbency = c.absorbency; - containment = c.containment; - spriteIndex = c.spriteIndex; - price = c.price; - washable = c.washable; - plural = c.plural; - dryingTime = c.dryingTime; - drying = c.drying; - timeWhenDoneDrying = c.timeWhenDoneDrying; - removable = c.removable; - this.wetness = wetness; - this.messiness = messiness; - this.durability = durability; - } - - public void Initialize(string type, float wetness, float messiness, int durability) + public float GetCapacity(IncidentType type) { - Container c; - - if (!Regression.t.Underwear_Options.TryGetValue(type, out c)) - throw new Exception(string.Format("Invalid underwear choice: {0}", type)); - - Initialize(c, wetness, messiness, durability); + switch (type) + { + case IncidentType.PEE: + return absorbency; + case IncidentType.POOP: + return containment; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } } - public void parseDryingDate(string date) + public float GetUsed(IncidentType type) { - if (date == "") + switch (type) { - drying = false; - return; + case IncidentType.PEE: + return wetness; + case IncidentType.POOP: + return messiness; + default: + throw new Exception("Not implemented: type " + type.ToString()); } + } + public void ResetToDefault(Container c, float wetness = -100, float messiness = -100, int durability = -100) + { + this._innerContainer = null; + this.name = c.name; + this.timeWhenDoneDrying = c.timeWhenDoneDrying; - string[] splitted = date.Split("-"); - drying = true; + this.wetness = c.wetness; + this.messiness = c.messiness; + this.durability = c.durability; + this.displayName = c.displayName; + this.description = c.description; + if (wetness != -100) this.wetness = wetness; + if (messiness != -100) this.messiness = messiness; + if (durability != -100) this.durability = durability; + } - timeWhenDoneDrying.time = int.Parse(splitted[0]); - timeWhenDoneDrying.day = int.Parse(splitted[1]); - timeWhenDoneDrying.season = int.Parse(splitted[2]); - timeWhenDoneDrying.year = int.Parse(splitted[3]); + public void ResetToDefault(string type, float wetness = -100, float messiness = -100, int durability = -100) + { + ResetToDefault(GetTypeDefault(type), wetness, messiness, durability); } - public string serializeDryingDate() + public static Container GetTypeDefault(string type) { - if (!drying) - { - return ""; - } - return string.Format("{0}-{1}-{2}-{3}", timeWhenDoneDrying.time, timeWhenDoneDrying.day, timeWhenDoneDrying.season, timeWhenDoneDrying.year); + Container c; + + if (!Regression.t.Underwear_Options.TryGetValue(type, out c)) + throw new Exception(string.Format("Invalid underwear choice: {0}", type)); + + return c; } } } diff --git a/Regression/PrimevalTitmouse/Data.cs b/Regression/PrimevalTitmouse/Data.cs index effebf6..d5f6463 100644 --- a/Regression/PrimevalTitmouse/Data.cs +++ b/Regression/PrimevalTitmouse/Data.cs @@ -11,27 +11,37 @@ public class Data public string[] Bladder_Continence_Red; public string[] Bladder_Continence_Yellow; public string[] Bladder_Continence_Green; + public string[] Bladder_Green; + public string[] Bladder_Yellow; public string[] Bladder_Orange; public string[] Bladder_Red; - public string[] Bladder_Yellow; + public string[] Bladder_Leak; public string[] Bowel_Continence_Min; public string[] Bowel_Continence_Orange; public string[] Bowel_Continence_Red; public string[] Bowel_Continence_Yellow; public string[] Bowel_Continence_Green; + public string[] Bowels_Green; + public string[] Bowels_Yellow; public string[] Bowels_Orange; public string[] Bowels_Red; - public string[] Bowels_Yellow; + public string[] Bowels_Leak; public string[] Cant_Remove; public string[] Change; public string[] Change_Destroyed; + public string[] Change_Other_Destroyed; + public string[] Getting_Changed_Destroyed; public string[] Change_Requires_Pants; + public string[] Change_Requires_Home; + public string[] Change_At_Home; public string[] Debuff_Messy_Pants; public string[] Debuff_Wet_Pants; public string[] Drink_Water_Source; public string[] Food_Low; public string[] Food_None; public string[] LookPants; + public string[] Diaper_Change_Dialog; + public string[] Change_Other_Dialog; public string[] Mess_Accident; public string[] Mess_Attempt; public string[] Mess_Voluntary; @@ -49,13 +59,19 @@ public class Data public string[] Poop_Voluntary; public string[] Spot_Washing_Bedding; public string[] Still_Soiled; - public string[] Toilet_Night; + public string[] Should_Change; + public Dictionary Night; public string Underwear_Clean; public string Underwear_Drying; + public string EasyMode_On; + public string EasyMode_Off; public string[] Underwear_Messy; public Dictionary Underwear_Options; public string[] Underwear_Wet; + public Dictionary> Villager_Friendship_Modifier; public Dictionary> Villager_Reactions; + public Dictionary>> Villager_Underwear_Options; + public Dictionary>>> Potty_Dialogs; public string[] Wake_Up_Underwear_State; public string[] Washing_Bedding; public string[] Washing_Underwear; diff --git a/Regression/PrimevalTitmouse/DialogueParserPatches.cs b/Regression/PrimevalTitmouse/DialogueParserPatches.cs new file mode 100644 index 0000000..fadbf70 --- /dev/null +++ b/Regression/PrimevalTitmouse/DialogueParserPatches.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using System.Xml; +using StardewValley.Inventories; +using StardewValley; +using System.Collections.Generic; + +namespace PrimevalTitmouse +{ + [HarmonyPatch(typeof(Dialogue), "parseDialogueString")] + public static class Dialogue_ParseDialogueString_Patch + { + static bool Prefix(Dialogue __instance, ref string masterString, string translationKey) + { + + masterString = Strings.InsertVariables(masterString, __instance.speaker); + masterString = Strings.InsertVariables(masterString, Regression.body); + // Now it's save to call the original methode + return true; + } + } +} \ No newline at end of file diff --git a/Regression/PrimevalTitmouse/FarmerPatches.cs b/Regression/PrimevalTitmouse/FarmerPatches.cs new file mode 100644 index 0000000..98d6190 --- /dev/null +++ b/Regression/PrimevalTitmouse/FarmerPatches.cs @@ -0,0 +1,24 @@ +using HarmonyLib; +using System.Xml; +using StardewValley.Inventories; +using StardewValley; +using System.Collections.Generic; + +namespace PrimevalTitmouse +{ + [HarmonyPatch(typeof(Farmer), "doneEating")] + public static class Farmer_DoneEating_Patch + { + static bool Prefix(Farmer __instance) + { + if (__instance.mostRecentlyGrabbedItem == null || __instance.itemToEat == null || !__instance.IsLocalPlayer) + { + return true; + } + Regression.body.Consume(__instance.itemToEat); + + // We just want to do something on done eating, we let the original function proceede + return true; + } + } +} \ No newline at end of file diff --git a/Regression/PrimevalTitmouse/IGenericModConfigMenuApi.cs b/Regression/PrimevalTitmouse/IGenericModConfigMenuApi.cs new file mode 100644 index 0000000..0dca302 --- /dev/null +++ b/Regression/PrimevalTitmouse/IGenericModConfigMenuApi.cs @@ -0,0 +1,181 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; + +namespace GenericModConfigMenu +{ + /// The API which lets other mods add a config UI through Generic Mod Config Menu. + public interface IGenericModConfigMenuApi + { + /********* + ** Methods + *********/ + /**** + ** Must be called first + ****/ + /// Register a mod whose config can be edited through the UI. + /// The mod's manifest. + /// Reset the mod's config to its default values. + /// Save the mod's current config to the config.json file. + /// Whether the options can only be edited from the title screen. + /// Each mod can only be registered once, unless it's deleted via before calling this again. + void Register(IManifest mod, Action reset, Action save, bool titleScreenOnly = false); + + + /**** + ** Basic options + ****/ + /// Add a section title at the current position in the form. + /// The mod's manifest. + /// The title text shown in the form. + /// The tooltip text shown when the cursor hovers on the title, or null to disable the tooltip. + void AddSectionTitle(IManifest mod, Func text, Func tooltip = null); + + /// Add a paragraph of text at the current position in the form. + /// The mod's manifest. + /// The paragraph text to display. + void AddParagraph(IManifest mod, Func text); + + /// Add an image at the current position in the form. + /// The mod's manifest. + /// The image texture to display. + /// The pixel area within the texture to display, or null to show the entire image. + /// The zoom factor to apply to the image. + void AddImage(IManifest mod, Func texture, Rectangle? texturePixelArea = null, int scale = Game1.pixelZoom); + + /// Add a boolean option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddBoolOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + /// Add an integer option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The minimum allowed value, or null to allow any. + /// The maximum allowed value, or null to allow any. + /// The interval of values that can be selected. + /// Get the display text to show for a value, or null to show the number as-is. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddNumberOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, int? min = null, int? max = null, int? interval = null, Func formatValue = null, string fieldId = null); + + /// Add a float option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The minimum allowed value, or null to allow any. + /// The maximum allowed value, or null to allow any. + /// The interval of values that can be selected. + /// Get the display text to show for a value, or null to show the number as-is. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddNumberOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, float? min = null, float? max = null, float? interval = null, Func formatValue = null, string fieldId = null); + + /// Add a string option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The values that can be selected, or null to allow any. + /// Get the display text to show for a value from , or null to show the values as-is. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddTextOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string[] allowedValues = null, Func formatAllowedValue = null, string fieldId = null); + + /// Add a key binding at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddKeybind(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + /// Add a key binding list at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddKeybindList(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + + /**** + ** Multi-page management + ****/ + /// Start a new page in the mod's config UI, or switch to that page if it already exists. All options registered after this will be part of that page. + /// The mod's manifest. + /// The unique page ID. + /// The page title shown in its UI, or null to show the value. + /// You must also call to make the page accessible. This is only needed to set up a multi-page config UI. If you don't call this method, all options will be part of the mod's main config UI instead. + void AddPage(IManifest mod, string pageId, Func pageTitle = null); + + /// Add a link to a page added via at the current position in the form. + /// The mod's manifest. + /// The unique ID of the page to open when the link is clicked. + /// The link text shown in the form. + /// The tooltip text shown when the cursor hovers on the link, or null to disable the tooltip. + void AddPageLink(IManifest mod, string pageId, Func text, Func tooltip = null); + + + /**** + ** Advanced + ****/ + /// Add an option at the current position in the form using custom rendering logic. + /// The mod's manifest. + /// The label text to show in the form. + /// Draw the option in the config UI. This is called with the sprite batch being rendered and the pixel position at which to start drawing. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// A callback raised just before the menu containing this option is opened. + /// A callback raised before the form's current values are saved to the config (i.e. before the save callback passed to ). + /// A callback raised after the form's current values are saved to the config (i.e. after the save callback passed to ). + /// A callback raised before the form is reset to its default values (i.e. before the reset callback passed to ). + /// A callback raised after the form is reset to its default values (i.e. after the reset callback passed to ). + /// A callback raised just before the menu containing this option is closed. + /// The pixel height to allocate for the option in the form, or null for a standard input-sized option. This is called and cached each time the form is opened. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + /// The custom logic represented by the callback parameters is responsible for managing its own state if needed. For example, you can store state in a static field or use closures to use a state variable. + void AddComplexOption(IManifest mod, Func name, Action draw, Func tooltip = null, Action beforeMenuOpened = null, Action beforeSave = null, Action afterSave = null, Action beforeReset = null, Action afterReset = null, Action beforeMenuClosed = null, Func height = null, string fieldId = null); + + /// Set whether the options registered after this point can only be edited from the title screen. + /// The mod's manifest. + /// Whether the options can only be edited from the title screen. + /// This lets you have different values per-field. Most mods should just set it once in . + void SetTitleScreenOnlyForNextOptions(IManifest mod, bool titleScreenOnly); + + /// Register a method to notify when any option registered by this mod is edited through the config UI. + /// The mod's manifest. + /// The method to call with the option's unique field ID and new value. + /// Options use a randomized ID by default; you'll likely want to specify the fieldId argument when adding options if you use this. + void OnFieldChanged(IManifest mod, Action onChange); + + /// Open the config UI for a specific mod. + /// The mod's manifest. + void OpenModMenu(IManifest mod); + + /// Open the config UI for a specific mod, as a child menu if there is an existing menu. + /// The mod's manifest. + void OpenModMenuAsChildMenu(IManifest mod); + + /// Get the currently-displayed mod config menu, if any. + /// The manifest of the mod whose config menu is being shown, or null if not applicable. + /// The page ID being shown for the current config menu, or null if not applicable. This may be null even if a mod config menu is shown (e.g. because the mod doesn't have pages). + /// Returns whether a mod config menu is being shown. + bool TryGetCurrentMenu(out IManifest mod, out string page); + + /// Remove a mod from the config UI and delete all its options and pages. + /// The mod's manifest. + void Unregister(IManifest mod); + } +} diff --git a/Regression/PrimevalTitmouse/InventoryPatches.cs b/Regression/PrimevalTitmouse/InventoryPatches.cs new file mode 100644 index 0000000..257dff3 --- /dev/null +++ b/Regression/PrimevalTitmouse/InventoryPatches.cs @@ -0,0 +1,38 @@ +using HarmonyLib; +using System.Xml; +using StardewValley.Inventories; +using StardewValley; +using System.Collections.Generic; + +namespace PrimevalTitmouse +{ + [HarmonyPatch(typeof(Inventory), nameof(Inventory.WriteXml))] + public static class Inventory_WriteXml_Patch + { + static bool Prefix(Inventory __instance, XmlWriter writer) + { + // Use Harmony's AccessTools or reflection to get the Items field/prop + var itemsField = AccessTools.Field(__instance.GetType(), "Items"); + var items = (IList)itemsField.GetValue(__instance); + + // Replace your Underwear items with a known type before serialization + var replacements = PrimevalTitmouse.Regression.replaceItems(items); + + // Now it's save to call the original methode + return true; + } + } + + [HarmonyPatch(typeof(Inventory), nameof(Inventory.ReadXml))] + public static class Inventory_ReadXml_Patch + { + static void Postfix(object __instance, XmlReader reader) + { + var itemsField = AccessTools.Field(__instance.GetType(), "Items"); + var items = (IList)itemsField.GetValue(__instance); + + // Original ReadXml is done, now restore items + PrimevalTitmouse.Regression.restoreItems(items); + } + } +} \ No newline at end of file diff --git a/Regression/PrimevalTitmouse/Mail.cs b/Regression/PrimevalTitmouse/Mail.cs index afbbd9d..5406195 100644 --- a/Regression/PrimevalTitmouse/Mail.cs +++ b/Regression/PrimevalTitmouse/Mail.cs @@ -23,13 +23,17 @@ public static void CheckMail() initialSupplies = new(); letterShown = false; //Always give turnips and diapers - initialSupplies.Add(new StardewValley.Object("399", 20, false, -1, 0)); - initialSupplies.Add(new Underwear("pawprint diaper", 0.0f, 0.0f, 40)); + //initialSupplies.Add(new StardewValley.Object("399", 40, false, -1, 0)); // Spring Onion - it needs definitly a bit of food at the start + initialSupplies.Add(new StardewValley.Object("403", 20, false, -1, 0)); // Field Snacks might be a better choise + // field snacks might be better as a generic choise and are not sold + //initialSupplies.Add(new Underwear("pawprint diaper", 0.0f, 0.0f, 40)); + initialSupplies.Add(new Underwear("training pants", 5)); // training pants are washable, they might be a good start equipment and are "not that great" + initialSupplies.Add(new Underwear("joja diaper", 25)); // joja diapers are cheap and the player would want to replace them at some point, but they are a good night diaper //If we're in Hard mode, also give pull-up. - if (!Regression.config.Easymode) + /*if (!Regression.config.Easymode) { - initialSupplies.Add(new Underwear("lavender pullup", 0.0f, 0.0f, 15)); - } + initialSupplies.Add(new Underwear("training pants", 0.0f, 0.0f, 5)); // training pants are washable, they might be a good start equipment and are "not that great" + }*/ letterContents += "[#]A Little... Protection."; Game1.mailbox.Add(initialRegressionLetterTitle); Dictionary mails = Game1.content.Load>("Data\\mail"); diff --git a/Regression/PrimevalTitmouse/NpcBody.cs b/Regression/PrimevalTitmouse/NpcBody.cs new file mode 100644 index 0000000..3a815e5 --- /dev/null +++ b/Regression/PrimevalTitmouse/NpcBody.cs @@ -0,0 +1,463 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using Netcode; +using StardewModdingAPI; +using StardewValley; +using StardewValley.Network; +using StardewValley.Tools; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PrimevalTitmouse +{ + public class NpcBody + { + public NPC npc; + public NpcBody(NPC npc) + { + this.npc = npc; + } + + public static NpcBody ByName(string name, int range = 20) + { + name = name.ToLower(); + foreach (var npc in range <= 0 ? Utility.getAllCharacters() : Animations.NearbyVillager(range)) + { + if (npc.Name.ToLower() == name) + { + return new NpcBody(npc); + } + } + return null; + } + public static List ByRange(int range = 10) + { + var list = new List(); + foreach (var npc in Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, range, (GameLocation)Game1.currentLocation)) + { + list.Add(new NpcBody(npc)); + } + return list; + } + // a very simplified accident mechanic that assumes that the npc has an accident. + public void accident(IncidentType type, float accidentSize) + { + if (type == IncidentType.PEE) + { + underwear.AddPee(accidentSize); + if (isWatching) + { + npc.movementPause = 3000; + npc.doEmote(28, false); + Game1.playSound("wateringCan"); + } + Regression.monitor.Log($"{npc.Name} piddled themselfs", LogLevel.Debug); + } + else + { + accidentSize = (accidentSize * 1.3f); + underwear.AddPoop(accidentSize); + if (isWatching) + { + npc.movementPause = 3000; + npc.doEmote(12, false); + Animations.AnimateMessingEnd(npc); + } + Regression.monitor.Log($"{npc.Name} pooped themselfs", LogLevel.Debug); + } + } + public void accidentFromFullness(IncidentType type) + { + var fullness = GetFullness(type); + var accidentSize = (float)Regression.rnd.Next(300, 800); + if (type == IncidentType.PEE) + { + if (fullness < 200) fullness += 200; + } + else + { + if (fullness < 300) fullness += 300; + } + accident(type,fullness); + SetFullness(type, 0); + } + + public void change(string underwearName = null, string pantsName = null) + { + var underwear = this.underwear; + if (underwearName != null) + { + underwear.ResetToDefault(underwearName); + } + else + { + underwear.ResetToDefault(defaultUnderwear); + } + + var pants = this.pants; + pants.ResetToDefault(pants, 0, 0); + Regression.monitor.Log($"{npc.Name} got changed and is now wearing {underwear.name} and {pants.name}", LogLevel.Debug); + } + + public bool canGetGiveChangeNpc + { + get + { + int heartLevelForNpc = Game1.player.getFriendshipHeartLevelForNPC(npc.Name); + switch (npc.Name.ToLower()) + { + case "vincent": // can get changed + return Regression.ChildrenAndDiapers && heartLevelForNpc >= 6 && Game1.player.getFriendshipHeartLevelForNPC("Jodi") >= 4; + case "jas": // can get changed + return Regression.ChildrenAndDiapers && heartLevelForNpc >= 6 && Game1.player.getFriendshipHeartLevelForNPC("Marnie") >= 4; + case "sam": // can get changed AND give changes + return heartLevelForNpc >= 8 && Game1.player.dialogueQuestionsAnswered.Contains("124") || Game1.player.dialogueQuestionsAnswered.Contains("125"); + case "jodi": // can give changes + return heartLevelForNpc >= 6; + case "abigail": + return heartLevelForNpc >= 8; + case "gus": + return heartLevelForNpc >= 8; + case "maru": + return heartLevelForNpc >= 4 || Game1.currentLocation.Name == "Hospital"; + case "penny": + return heartLevelForNpc > 6; + default: + return false; + } + } + } + + public bool canGiveDirtyChangeNpc + { + get + { + int heartLevelForNpc = Game1.player.getFriendshipHeartLevelForNPC(npc.Name); + switch (npc.Name.ToLower()) + { + case "gus": + return Game1.currentLocation.Name == "Saloon"; + case "abigail": + return canGetGiveChangeNpc; + case "maru": + return canGetGiveChangeNpc || Game1.currentLocation.Name == "Hospital"; + case "penny": + return canGetGiveChangeNpc; + case "sam": // will do it in the house of his mum if required + case "jodi": // will do it if its really important in her house + return Game1.player.currentLocation == npc.getHome(); + default: + return false; + } + } + } + public float GetFullnessMax(IncidentType type) + { + switch (npc.Name.ToLower()) + { + case "vincent": + if (type == IncidentType.PEE) return 400; + return 900; + case "jas": + if (type == IncidentType.PEE) return 400; + return 800; + case "sam": + if (type == IncidentType.PEE) return 550; + return 900; + default: + if (type == IncidentType.PEE) return 700; + return 1000; + } + } + public bool GetSuccessNext(IncidentType type) + { + var key = $"Potty/{type}/Success"; + if (!npc.modData.ContainsKey(key)) return false; + return bool.Parse(npc.modData[key]); + } + public void SetSuccessNext(IncidentType type, bool value) + { + var key = $"Potty/{type}/Success"; + npc.modData[key] = value.ToString(); + } + public float GetFullness(IncidentType type) + { + var key = $"Potty/{type}/Fullness"; + if (!npc.modData.ContainsKey(key)) return 0.0f; + return float.Parse(npc.modData[key]); + } + public void SetFullness(IncidentType type, float value) + { + var key = $"Potty/{type}/Fullness"; + npc.modData[key] = value.ToString(); + } + public bool isWatching + { + get + { + if (Game1.player.currentLocation != npc.currentLocation) return false; // Forcing silent if different map + else if (Vector2.Distance(Game1.player.Tile, npc.Tile) > 30) return false; // If the distance is to far, we silence it + return true; + } + } + + public bool RandomAction(float hours) + { + if (npc == null) return false; + if (!npc.IsVillager) return false; + + // Chances per hour + float getChangedChance = 1f; + + + var underwear = this.underwear; + switch (npc.Name.ToLower()) + { + case "vincent": // is in diapers in general + if (!Regression.ChildrenAndDiapers) return false; + getChangedChance = 0.15f; // basechance getting changed (low, toddlers get only changed with a reason) + if (underwear.messiness > 0) getChangedChance = 0.4f; // chance of discovery, trying to hide it + if (underwear.messiness > (underwear.containment / 2f)) getChangedChance = 0.9f; // stinky, but still better at hiding + if (underwear.wetness > (underwear.absorbency / 2f)) getChangedChance = 0.5f; // chance that a waddle will be noticed + break; + case "jas": // is in training pants in general + if (!Regression.ChildrenAndDiapers) return false; + getChangedChance = 0.15f; // basechance getting changed (low, toddlers get only changed with a reason) + if (underwear.messiness > 0) getChangedChance = 0.5f; // chance of discovery or jas tries to ask for help + if (underwear.messiness > (underwear.containment / 2f)) getChangedChance = 1.0f; // chance of discovery or jas tries to ask rises for full diapers + if (underwear.wetness > (underwear.absorbency / 2f)) getChangedChance = 0.7f; // chance that a waddle will be noticed or she wants to be clean + break; + case "sam": // can get changed AND give changes + getChangedChance = 0.3f; // adults tend to get changed for other reasons, like getting out of slightly wet diapers, sam less so + if (underwear.messiness > 0) getChangedChance = 0.8f; + if (underwear.wetness > (underwear.absorbency / 2f)) getChangedChance = 0.7f; + break; // Always does it in secret + case "abigail": + if (Game1.player.getFriendshipHeartLevelForNPC(npc.Name) < 4) return false; + + getChangedChance = 0.4f; // adults tend to get changed for other reasons, like getting out of slightly wet diapers + if (underwear.wetness > (underwear.absorbency / 2f)) getChangedChance = 0.9f; + if (underwear.messiness > 0) getChangedChance = 1.0f; + + break; + default: + return false; + } + + + if (getChangedChance > 0 && (underwear.messiness > 0 || underwear.wetness > 0) && Regression.rnd.NextDouble() <= getChangedChance * hours) + { + if (isWatching) npc.doEmote(12, false); + change(); + return true; + } + + if (PottyChanceIncidentWorker(IncidentType.PEE)) return true; + if (PottyChanceIncidentWorker(IncidentType.POOP)) return true; + + + return false; + } + + private bool PottyChanceIncidentWorker(IncidentType incidentType) + { + var pottyChance = 1.0f; + switch (npc.Name.ToLower()) + { + case "vincent": // is in diapers in general + if (!Regression.ChildrenAndDiapers) return false; + pottyChance = 0f; + break; + case "jas": // is in training pants in general + if (!Regression.ChildrenAndDiapers) return false; + pottyChance = incidentType == IncidentType.PEE ? 0.3f : 0.45f; + break; + case "sam": // can get changed AND give changes + pottyChance = incidentType == IncidentType.PEE ? 0.2f : 0.6f; + break; // Always does it in secret + case "abigail": + if (Game1.player.getFriendshipHeartLevelForNPC(npc.Name) < 4) return false; + pottyChance = incidentType == IncidentType.PEE ? 0.3f : 0.8f; + break; + default: + return false; + } + + + var color = incidentType == IncidentType.PEE ? new Color(byte.MaxValue, 225, 56) : new Color(146, 111, 91); + var fullness = GetFullness(incidentType); + + + var max = GetFullnessMax(incidentType); + if (fullness >= max) + { + var success = GetSuccessNext(incidentType); + var dialogs = PottyDialogs(incidentType, false, success); + if (dialogs != null && dialogs.Length > 0) + { + npc.showTextAboveHead(Strings.RandString(dialogs), color, 1, 3000, 2000); + } + if (success) + { + npc.doEmote(5, false); + npc.movementPause = 3000; + SetFullness(incidentType, 0); + } + else + { + accidentFromFullness(incidentType); + } + SetSuccessNext(incidentType, Regression.rnd.NextDouble() < pottyChance); + return true; + + } + else if (fullness + 70f >= max) + { + var success = GetSuccessNext(incidentType); + var dialogs = PottyDialogs(incidentType, true, success); + if (dialogs != null && dialogs.Length > 0) + { + npc.showTextAboveHead(Strings.RandString(dialogs), color, 0, 3000, 0); + } + } + SetFullness(incidentType, fullness + 35f + (35f * (float)Regression.rnd.NextDouble())); + + return false; + } + public string[] PottyDialogs(IncidentType type,bool preStage, bool success) + { + var dialogsStorage = Animations.Data.Potty_Dialogs; + var stageStr = preStage ? "pre" : "post"; + var typeStr = type == IncidentType.PEE ? "pee" : "poop"; + var successStr = success ? "success" : "fail"; + + Dictionary>> dictionary; + Dictionary> typeDict; + Dictionary stageDict = null; + string[] successDialogs; + if (dialogsStorage.TryGetValue(npc.Name.ToLower(), out dictionary) && dictionary.TryGetValue(typeStr, out typeDict) && typeDict.TryGetValue(stageStr, out stageDict) && stageDict.TryGetValue(successStr, out successDialogs)) + { + return successDialogs; + } + return null; + } + public void RemoveDialogue(string keyRemove) + { + + // Temporary stack to hold dialogues we want to keep + Stack tempStack = new Stack(); + + // Iterate through the stack to find the dialogue to remove + while (npc.CurrentDialogue.Count > 0) + { + Dialogue current = npc.CurrentDialogue.Pop(); + + if (current.TranslationKey != keyRemove) + { + tempStack.Push(current); // Keep this dialogue if it doesn't match + } + } + + // Restore the remaining dialogues back into the original stack + while (tempStack.Count > 0) + { + npc.CurrentDialogue.Push(tempStack.Pop()); + } + } + + public string defaultUnderwear + { + get + { + switch (npc.Name.ToLower()) + { + case "vincent": + return "baby print diaper"; + case "jas": + return Regression.rnd.Next(1, 3) != 3 ? "training pants" : "lavender pullups"; // sometimes the training pants are all dirty + case "sam": + return Regression.rnd.Next(1, 4) != 4 ? "baby print diaper" : "joja diaper"; // sometimes sam tries bigger diapers + case "abigail": + return "joja diaper"; + default: + return npc.Gender == Gender.Male ? "big kid undies" : "polka dot panties"; + } + } + + } + public Container underwear + { + get + { + return new Container(npc, "underwear", defaultUnderwear); + } + } + public string npcDefaultPantsName + { + get + { + switch (npc.Name.ToLower()) + { + case "vincent": + return "toddler pants"; + case "jas": + return "purple toddler skirts"; + default: + return npc.Gender == Gender.Male ? "pants" : "skirt"; + } + } + + } + public Container pants + { + get + { + var staticType = "blue jeans"; + var defaultName = npcDefaultPantsName; + var pants = new Container(npc, "pants", staticType); + if (pants.displayName == staticType && defaultName != "" && defaultName != pants.displayName) + { + pants.displayName = defaultName; + pants.description = defaultName; + } + return pants; + } + } + + public Stack CurrentDialogue + { + get + { + return npc.CurrentDialogue; + } + } + public int Age + { + get + { + return npc.Age; + } + } + public List GetVillagerReactions(string responseKey, string fallbackKey = null) + { + var npcType = Animations.npcTypeList(npc); + List stringList3 = new List(); + foreach (string key2 in npcType) + { + Dictionary dictionary; + string[] strArray; + if (Animations.Data.Villager_Reactions.TryGetValue(key2, out dictionary) && dictionary.TryGetValue(responseKey, out strArray)) + { + stringList3 = new List(); // We could remove this line again, but the general texts are more meant as fallback, they often don't fit well if custom texts are defined + stringList3.AddRange((IEnumerable)strArray); + } + } + if (fallbackKey != null && stringList3.Count < 1) return GetVillagerReactions(fallbackKey, null); + return stringList3; + } + } +} diff --git a/Regression/PrimevalTitmouse/Regression.cs b/Regression/PrimevalTitmouse/Regression.cs index e3c24be..46788ec 100644 --- a/Regression/PrimevalTitmouse/Regression.cs +++ b/Regression/PrimevalTitmouse/Regression.cs @@ -1,38 +1,57 @@ -using Microsoft.Xna.Framework; +using GenericModConfigMenu; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Regression; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; +using StardewValley.BellsAndWhistles; +using StardewValley.Delegates; +using StardewValley.GameData.Characters; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Objects; +using StardewValley.Quests; +using StardewValley.SaveSerialization; +using StardewValley.TerrainFeatures; using StardewValley.Tools; +using StardewValley.Triggers; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; +using System.Reflection; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.CompilerServices; +using System.Xml.Serialization; using xTile.Dimensions; +using static StardewValley.Minigames.TargetGame; namespace PrimevalTitmouse { public class Regression : Mod { public static int lastTimeOfDay = 0; - public static bool morningHandled = true; public static Random rnd = new Random(); public static bool started = false; - public Body body; + public static Body body; public static Config config; public static IModHelper help; public static IMonitor monitor; public bool shiftHeld; public static Data t; public static Farmer who; - private float tickCD1 = 0; - private float tickCD2 = 0; - + public static string dirtyEventToken = "dirtyEventToken"; + public static string generalEventToken = "generalEventToken"; + public static bool SelfIsFurry = false; + public static bool WorldIsFurry = false; const float timeInTick = (1f/43f); //One second realtime ~= 1/43 hours in game + public Dictionary jsonLoaded = new(); public override void Entry(IModHelper h) { + var harmony = new HarmonyLib.Harmony("com.primevaltitmouse.regression"); + harmony.PatchAll(); + help = h; monitor = Monitor; config = Helper.ReadConfig(); @@ -41,99 +60,255 @@ public override void Entry(IModHelper h) h.Events.GameLoop.DayStarted += new EventHandler(ReceiveAfterDayStarted); h.Events.GameLoop.OneSecondUpdateTicking += new EventHandler(ReceiveUpdateTick); h.Events.GameLoop.TimeChanged += new EventHandler(ReceiveTimeOfDayChanged); + h.Events.GameLoop.GameLaunched += new EventHandler(OnGameLaunched); h.Events.Input.ButtonPressed += new EventHandler(ReceiveKeyPress); h.Events.Input.ButtonPressed += new EventHandler(ReceiveMouseChanged); h.Events.Display.MenuChanged += new EventHandler(ReceiveMenuChanged); h.Events.Display.RenderingHud += new EventHandler(ReceivePreRenderHudEvent); + + h.Events.GameLoop.UpdateTicked += new EventHandler(OnUpdateTicked); + + h.Events.Player.Warped += new EventHandler(OnWarped); + + h.ConsoleCommands.Add("dialog", "Triggers a debug dialog. Usage: dialog ", TriggerDialogCommand); + h.ConsoleCommands.Add("emote", "Sets an NPC's emote. Usage: set_emote ", SetEmoteCommand); + // A multi action manager, as the game only allowes one action to be triggered + // Example: $action ACTIONS CHANGE_DIAPER_OTHERS vincent \"baby print diaper\" ADD_DIALOG \"Thank you so much! Here!\" \"change_vincent\" GIVE_UNDERWEAR \"baby print diaper\" + TriggerActionManager.RegisterAction("ACTIONS", this.ActionManager); + + // This is about you getting your diapers changed by someone + // Example: $action DIAPER_CHANGE \"baby print diaper\" \"sams pants\" + TriggerActionManager.RegisterAction("DIAPER_CHANGE", this.StartChange); + + // This is about you changing others diapers, parameter 2 and 3 optional + // Example: $action CHANGE_DIAPER_OTHERS jas + // Example: $action CHANGE_DIAPER_OTHERS vincent "baby print diaper" "toddler pants" + TriggerActionManager.RegisterAction("CHANGE_DIAPER_OTHERS", this.StartChangeOthers); + + // This is about the player having accidents, but can also be pointed at npc. + // Example: $action DIAPER_ACCIDENT player pee + // Example: $action DIAPER_ACCIDENT vincent poop + TriggerActionManager.RegisterAction("DIAPER_ACCIDENT", this.StartAccident); + + // This is adds a dialog. Parameter 3 is optional, containing a key. If there is a message with this key already present, the message will be replaced + // Example: $action ADD_DIALOG jodi "Did you change vincent into training pants? You should know better by now!#$b#%Jodi seams to be upset with you" "change_vincent_wrong" + TriggerActionManager.RegisterAction("ADD_DIALOG", this.AddNpcMessage); + + // This adds underwear to the players inventory, usually as a gift from an npc + // Example: $action GIVE_UNDERWEAR "training pants" + TriggerActionManager.RegisterAction("GIVE_UNDERWEAR", this.GiveUnderwear); + + + GameStateQueryDelegate queryDelegate = (GameStateQueryDelegate)Delegate.CreateDelegate(typeof(GameStateQueryDelegate), this, "DIAPER_USED"); + GameStateQuery.Register("DIAPER_USED", queryDelegate); + + GameStateQueryDelegate queryDelegateBad = (GameStateQueryDelegate)Delegate.CreateDelegate(typeof(GameStateQueryDelegate), this, "DIAPER_USED_BAD"); + GameStateQuery.Register("DIAPER_USED_BAD", queryDelegateBad); + + WorldIsFurry = Helper.ModRegistry.IsLoaded("sion9000.AnthroCharactersContinued"); + SelfIsFurry = Helper.ModRegistry.IsLoaded("krystedez.FurryFarmer"); } + private void SetEmoteCommand(string command, string[] args) + { + if (args.Length < 2) + { + Monitor.Log("Usage: set_emote ", LogLevel.Error); + return; + } - public void DrawStatusBars() + string npcName = args[0]; + if (!int.TryParse(args[1], out int emoteId)) + { + Monitor.Log("EmoteID must be an integer.", LogLevel.Error); + return; + } + + NPC npc = Game1.getCharacterFromName(npcName); + if (npc == null) + { + Monitor.Log($"NPC '{npcName}' not found.", LogLevel.Error); + return; + } + + if (emoteId < 0 || emoteId > 64) + { + Monitor.Log($"EmoteID '{emoteId}' is out of range. Valid IDs: 0-64.", LogLevel.Error); + return; + } + + npc.doEmote(emoteId,false); + + Monitor.Log($"Set {npcName}'s emote to {emoteId}.", LogLevel.Info); + } + + /// + /// Handler for the "dialog" console command. + /// Usage: dialog + /// + private void TriggerDialogCommand(string command, string[] args) { + if (args.Length < 2) + { + Monitor.Log("Usage: dialog ", LogLevel.Error); + return; + } - int x1 = Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Right - (65 + (int)((StatusBars.barWidth))); - int y1 = Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - (25 + (int)((StatusBars.barHeight))); + string npcName = args[0]; + string message = string.Join(" ", args, 1, args.Length - 1); - if (Game1.currentLocation is MineShaft || Game1.currentLocation is Woods || Game1.currentLocation is SlimeHutch || Game1.currentLocation is VolcanoDungeon || who.health < who.maxHealth) - x1 -= 58; + TriggerDebugDialog(npcName, message); + } + /// + /// Handler for the "dialog" console command. + /// Usage: trigger_dialog + /// - if (!config.NoHungerAndThirst || PrimevalTitmouse.Regression.config.Debug) + /// + /// Triggers a dialog for the specified NPC with the given message. + /// + /// Name of the NPC. + /// Dialog message. + private void TriggerDebugDialog(string npcName, string message) + { + NPC npc = Game1.getCharacterFromName(npcName); + if (npc != null) { - float percentage1 = body.GetHungerPercent(); - StatusBars.DrawStatusBar(x1, y1, percentage1, new Color(115, byte.MaxValue, 56)); - int x2 = x1 - (10 + StatusBars.barWidth); - float percentage2 = body.GetThirstPercent(); - StatusBars.DrawStatusBar(x2, y1, percentage2, new Color(117, 225, byte.MaxValue)); - x1 = x2 - (10 + StatusBars.barWidth); + // Create a new Dialogue object + Dialogue dialogue = new Dialogue(npc,"",message); + + npc.setNewDialogue(dialogue, true, true); + + // Show the dialogue to the player + Game1.drawDialogue(npc); + + // Log to confirm the dialog was triggered + Monitor.Log($"Dialog triggered for {npcName}: {message}", LogLevel.Info); } - if (config.Debug) + else { - if (config.Messing) + Monitor.Log($"NPC '{npcName}' not found!", LogLevel.Warn); + } + } + + private void OnWarped(object sender, WarpedEventArgs e) + { + return; + } + public bool DIAPER_USED(string[] query, GameStateQueryContext context) + { + var underwear = body.underwear; + + var targetNpcName = query.Length > 1 ? query[1] : null; + if (targetNpcName != null) + { + switch (targetNpcName) { - float percentage = body.GetBowelPercent(); - StatusBars.DrawStatusBar(x1, y1, percentage, new Color(146, 111, 91)); - x1 -= 10 + StatusBars.barWidth; + case "pee": + return underwear.wetness > 0; + case "poop": + return underwear.messiness > 0; + default: + break; } - if (config.Wetting) + var npc = NpcBody.ByName(targetNpcName,20); + if (npc == null) return false; + + underwear = npc.underwear; + // we don't null check, that should not happen and if it does, we want to see that + } + switch (query.Length > 2 ? query[2]?.ToLower() : null) + { + case "pee": + return underwear.wetness > 0; + case "poop": + return underwear.messiness > 0; + default: + return underwear.used; + } + } + public bool DIAPER_USED_BAD(string[] query, GameStateQueryContext context) + { + var underwear = body.underwear; + + var targetNpcName = query.Length > 1 ? query[1] : null; + if (targetNpcName != null) + { + switch (targetNpcName) { - float percentage = body.GetBladderPercent(); - StatusBars.DrawStatusBar(x1, y1, percentage, new Color(byte.MaxValue, 225, 56)); + case "pee": + return underwear.wetness > (underwear.absorbency / 2); + case "poop": + return underwear.messiness > (underwear.containment / 2); + default: + break; } + var npc = NpcBody.ByName(targetNpcName, 20); + if (npc == null) return false; + + underwear = npc.underwear; + // we don't null check, that should not happen and if it does, we want to see that + } + switch (query.Length > 2 ? query[2]?.ToLower() : null) + { + case "pee": + return underwear.wetness > (underwear.absorbency / 2); + case "poop": + return underwear.messiness > (underwear.containment / 2); + default: + return underwear.used_bad; // if very wet OR slightly poopy (yes, even if a little, not like the specific questions on top) } - if (!config.Wetting && !config.Messing) - return; - int y2 = (Game1.player.questLog).Count == 0 ? 250 : 310; - Animations.DrawUnderwearIcon(body.underwear, Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Right - 94, y2); } private void GiveUnderwear() { List objList = new List(); foreach (string validUnderwearType in Strings.ValidUnderwearTypes()) - objList.Add(new Underwear(validUnderwearType, 0.0f, 0.0f, 20)); + objList.Add(new Underwear(validUnderwearType,20)); objList.Add(new StardewValley.Object("399", 99, false, -1, 0)); objList.Add(new StardewValley.Object("348", 99, false, -1, 0)); Game1.activeClickableMenu = new ItemGrabMenu(objList); } - private static void restoreItems(StardewValley.Inventories.Inventory items, Dictionary> invReplacement) + private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) { - foreach (KeyValuePair> entry in invReplacement) + var configFile = "RegressionSave.json"; + if (config.ReadSaveFiles) { - var underwear = new Underwear(); - underwear.rebuild(entry.Value, items[entry.Key]); - items[entry.Key] = underwear; + body = Helper.Data.ReadJsonFile(string.Format("{0}/{1}", Constants.SaveFolderName, configFile)); + if (body == null) body = new Body(); + else jsonLoaded[configFile] = true; } - } - - private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) - { - body = Helper.Data.ReadJsonFile(string.Format("{0}/RegressionSave.json", Constants.SaveFolderName)) ?? new Body(); + else + { + body = new Body(); + } + started = true; who = Game1.player; - var invReplacement = Helper.Data.ReadJsonFile< Dictionary>>(string.Format("{0}/RegressionSaveInv.json", Constants.SaveFolderName)); - if (invReplacement != null) - { - restoreItems(Game1.player.Items, invReplacement); - } + configFile = "RegressionSaveInv.json"; + Dictionary> invReplacement = null; + if(config.ReadSaveFiles) invReplacement = Helper.Data.ReadJsonFile>>(string.Format("{0}/{1}", Constants.SaveFolderName, configFile)); + if(invReplacement != null) jsonLoaded[configFile] = true; + restoreItems(Game1.player.Items, invReplacement); + + configFile = "RegressionSaveChest.json"; + Dictionary>> chestReplacement = null; + if (config.ReadSaveFiles) chestReplacement = Helper.Data.ReadJsonFile>>>(string.Format("{0}/{1}", Constants.SaveFolderName, configFile)); + if (chestReplacement != null) jsonLoaded[configFile] = true; - var chestReplacement = Helper.Data.ReadJsonFile>>>(string.Format("{0}/RegressionSaveChest.json", Constants.SaveFolderName)); - if (chestReplacement != null) + int locId = 0; + foreach (var location in Game1.locations) { - int locId = 0; - foreach (var location in Game1.locations) + foreach (var obj in location.Objects.Values) { - foreach (var obj in location.Objects.Values) + var id = string.Format("{0}-{1}-{2}", locId, obj.TileLocation.X, obj.TileLocation.Y); + if (obj is Chest chest) { - var id = string.Format("{0}-{1}-{2}", locId, obj.TileLocation.X, obj.TileLocation.Y); - if (obj is Chest chest && chestReplacement.ContainsKey(id)) - { - restoreItems(chest.Items, chestReplacement[id]); - } + restoreItems(chest.Items, chestReplacement != null && chestReplacement.ContainsKey(id) ? chestReplacement[id] : null); } - locId++; } - restoreItems(Game1.player.Items, invReplacement); + locId++; } Animations.AnimateNight(body); @@ -143,9 +318,10 @@ private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) private void HandleMorning(object Sender, DayStartedEventArgs e) { body.HandleMorning(); + Mail.CheckMail(); } - private static Dictionary> replaceItems(StardewValley.Inventories.Inventory items) + public static Dictionary> replaceItems(IList items) { var replacements = new Dictionary>(); @@ -161,6 +337,37 @@ private static Dictionary> replaceItems(StardewV return replacements; } + public static void restoreItems(IList items, Dictionary> invReplacement = null) + { + if (invReplacement != null) + { + foreach (KeyValuePair> entry in invReplacement) + { + var underwear = new Underwear(); + underwear.rebuild(entry.Value, items[entry.Key]); + if(items[entry.Key] != null) + { + underwear.modData.CopyFrom(items[entry.Key].modData); + } + items[entry.Key] = underwear; + } + } + + + for (int i = 0; i < items.Count; i++) + { + var item = items[i]; + // we have to access the type this way, because it's not yet of the correct class + if (item?.modData?.ContainsKey(Container.BuildKeyFor("name", Underwear.modDataKey)) == true) + { + var underwear = new Underwear(); + underwear.modData.CopyFrom(item.modData); + underwear.Stack = item.Stack; + items[i] = underwear; + } + } + } + //Save Mod related variables in separate JSON. Also trigger night handling if not on the very first day. private void BeforeSave(object Sender, SavingEventArgs e) @@ -168,69 +375,404 @@ private void BeforeSave(object Sender, SavingEventArgs e) body.bedtime = lastTimeOfDay; if (Game1.dayOfMonth != 1 || Game1.currentSeason != "spring" || Game1.year != 1) body.HandleNight(); - if (string.IsNullOrWhiteSpace(Constants.SaveFolderName)) - return; - + var chestReplacements = new Dictionary>>(); - int locId = 0; - foreach (var location in Game1.locations) + if (config.WriteSaveFiles) { - foreach (var obj in location.Objects.Values) + int locId = 0; + foreach (var location in Game1.locations) { - if (obj is Chest chest) + foreach (var obj in location.Objects.Values) { - var id = string.Format("{0}-{1}-{2}", locId, obj.TileLocation.X, obj.TileLocation.Y); - chestReplacements.Add(id, replaceItems(chest.Items)); + if (obj is Chest chest) + { + var id = string.Format("{0}-{1}-{2}", locId, obj.TileLocation.X, obj.TileLocation.Y); + chestReplacements.Add(id, replaceItems(chest.Items)); + } } + + foreach (var furn in location.furniture.OfType()) + { + Monitor.Log(string.Format("Found storage furniture {0}", furn.DisplayName), LogLevel.Info); + } + locId++; } + } + var invReplacements = config.WriteSaveFiles ? replaceItems(Game1.player.Items) : null; + + + var configFile = "RegressionSave.json"; + if (config.WriteSaveFiles || jsonLoaded.ContainsKey(configFile)) + { + Helper.Data.WriteJsonFile(string.Format("{0}/{1}", Constants.SaveFolderName, configFile), config.WriteSaveFiles ? body : null); + if (jsonLoaded.ContainsKey(configFile)) jsonLoaded.Remove(configFile); + } + + configFile = "RegressionSaveInv.json"; + if (config.WriteSaveFiles || jsonLoaded.ContainsKey(configFile)) + { + Helper.Data.WriteJsonFile(string.Format("{0}/{1}", Constants.SaveFolderName, configFile), config.WriteSaveFiles ? invReplacements : null); + if (jsonLoaded.ContainsKey(configFile)) jsonLoaded.Remove(configFile); + } - foreach (var furn in location.furniture.OfType()) + configFile = "RegressionSaveChest.json"; + if (config.WriteSaveFiles || jsonLoaded.ContainsKey(configFile)) + { + Helper.Data.WriteJsonFile(string.Format("{0}/{1}", Constants.SaveFolderName, configFile), config.WriteSaveFiles ? chestReplacements : null); + if (jsonLoaded.ContainsKey(configFile)) jsonLoaded.Remove(configFile); + } + } + + public bool StartAccident(string[] args, TriggerActionContext context, out string error) + { + + error = null; + + if (args.Length < 2) + { + error = "Parameter 1, type, should be given!"; + return false; + } + var typeStr = args[1]; + IncidentType type = IncidentType.PEE; + switch (typeStr) + { + case "pee": + type = IncidentType.PEE; + break; + case "poop": + type = IncidentType.POOP; + break; + default: + error = $"Parameter 1, type '{type}' is unknown!"; + return false; + } + + if (args.Length < 3) + { + error = "Parameter 2, target, be 'player' or an npc name"; + return false; + } + var target = args.Length < 3 ? "player" : args[2]; + target = target.ToLower(); + + + if (target == "player" || target == "farmer" || target == "self") + { + body.Accident(type); + } + else + { + var targetNpc = NpcBody.ByName(target,20); + if (targetNpc == null) { - Monitor.Log(string.Format("Found storage furniture {0}", furn.DisplayName), LogLevel.Info); + error = $"Parameter 2, '{target}' not found in local npc list in 20 range"; + return false; } - locId++; + targetNpc.accidentFromFullness(type); + } + return true; + } + public static Underwear GetUnderwearFromInventory(string underwearName, bool clean = true) + { + if (who.ActiveObject != null) + { + if (who.ActiveObject is Underwear) + { + var container = ((Underwear)who.ActiveObject).container; + if (container.name.ToLower() == underwearName.ToLower()) + { + if (!clean || !container.used) + { + return (Underwear)who.ActiveObject; + } + + } + } + return null; } + foreach (var item in who.Items) + { + if (item is Underwear) + { + var underwearFromInventory = item as Underwear; + if (underwearFromInventory.container.name.ToLower() == underwearName.ToLower()) + { + if (!clean || !underwearFromInventory.container.used) + { + return underwearFromInventory; + } + } + } + } + return null; + } + + /* + public static bool MakeUnderwearActive(string underwearName, bool clean = true) + { + if (who.ActiveObject != null) return false; + var found = GetUnderwearFromInventory(underwearName, clean); + if(found == null) return false; + who.ActiveObject = found; + return true; + }*/ + public static bool HasUnderwear(string underwearName, bool clean = true) + { + return GetUnderwearFromInventory(underwearName,clean) != null; + } + + public bool StartChangeOthers(string[] args, TriggerActionContext context, out string error) + { + try + { + if (args.Length < 2) + { + error = "Parameter 1, target, has to be the name of an npc"; + return false; + } + var target = args[1]; + target = target.ToLower(); + var targetNpc = NpcBody.ByName(target,20); + if (targetNpc == null) + { + error = $"Parameter 1, '{target}' not found in local npc list in 20 range"; + return false; + } + + string underwearName = args.Length > 2 ? args[2] : null; + var newUnderwear = GetUnderwearFromInventory(underwearName); + if (newUnderwear == null) + { + error = $"Parameter 2, '{underwearName}' not found in inventory"; + return false; + } + + var currentUnderwear = targetNpc.underwear; + // We create a new, untethered container first, of the same type. + Underwear oldUnderwear = new Underwear(currentUnderwear.name, 1); + // We "reset" that new container to the same informations (including wet or dirty), so making a copy of it. + oldUnderwear.container.ResetToDefault(currentUnderwear); - var invReplacements = replaceItems(Game1.player.Items); - Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSave.json", Constants.SaveFolderName), body); - Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSaveInv.json", Constants.SaveFolderName), invReplacements); - Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSaveChest.json", Constants.SaveFolderName), chestReplacements); + if (who.ActiveItem == newUnderwear) + { + who.reduceActiveItemByOne(); + } + else { + newUnderwear.Stack -= 1; + if (newUnderwear.Stack < 1) + { + who.removeItemFromInventory(newUnderwear); + } + } + + targetNpc.change(underwearName, args.Length > 3 ? args[3] : null); + + + //If the underwear returned is not removable, destroy it + if (!oldUnderwear.container.washable) + { + var msg = Strings.InsertVariables(Strings.RandString(Regression.t.Change_Other_Destroyed), targetNpc.npc,oldUnderwear.container); + Animations.Warn(msg); + } + else if (!who.addItemToInventoryBool(oldUnderwear, false)) //Otherwise put the old underwear into the inventory, but pull up the management window if it can't fit + { + List objList = new List(); + objList.Add(oldUnderwear); + Game1.activeClickableMenu = new ItemGrabMenu(objList); + } + } + catch (Exception e) + { + error = e.Message; + return false; + } + + error = null; + return true; } + public bool GiveUnderwear(string[] args, TriggerActionContext context, out string error) + { + try + { + if (args.Length < 2) + { + error = $"Parameter 1, needs to be a valid name of a type of underwear"; + return false; + } + + var amount = args.Length > 2 ? int.Parse(args[2]) : 1; + + var underwear = new Underwear(args[1], 1); + + //Put into the inventory, but pull up the management window if it can't fit + if (!who.addItemToInventoryBool(underwear, false)) + { + List objList = new List(); + objList.Add(underwear); + Game1.activeClickableMenu = new ItemGrabMenu(objList); + } + } + catch (Exception e) + { + error = e.Message; + return false; + } + error = null; + return true; + } + public bool StartChange(string[] args, TriggerActionContext context, out string error) + { + try + { + var underwearName = "big kid undies"; + if (args.Length > 1) + { + underwearName = args[1]; + } + + var diaper = new Underwear(underwearName, 1); + + Underwear underwear = new Underwear(body.underwear, 1); + + body.ChangeUnderwear(diaper); + body.ResetPants(); + + //If the underwear returned is not removable, destroy it + if (!underwear.container.washable) + { + Animations.Warn(Regression.t.Getting_Changed_Destroyed, body, underwear.container); + } + //Otherwise put the old underwear into the inventory, but pull up the management window if it can't fit + else if (!who.addItemToInventoryBool(underwear, false)) + { + List objList = new List(); + objList.Add(underwear); + Game1.activeClickableMenu = new ItemGrabMenu(objList); + } + var dirtyPants = body.HasWetOrMessyDebuff(); + + + if (args.Length > 2 && dirtyPants) + { + body.pants.displayName = args[2]; + body.pants.description = args[2]; + } + } + catch (Exception e) + { + error = e.Message; + return false; + } + + error = null; + return true; + } + public bool AddNpcMessage(string[] args, TriggerActionContext context, out string error) + { + try + { + if (args.Length < 2) + { + error = "Parameter 1, target, has to be the name of an npc"; + return false; + } + var target = args[1]; + target = target.ToLower(); + var targetNpc = NpcBody.ByName(target, -1); + if (targetNpc == null) + { + error = $"Parameter 1, '{target}' not found in global npc list"; + return false; + } + if (args.Length < 3) + { + error = "Parameter 2, message, has to be a message that is added as dialog to that npc"; + return false; + } + string eventToken = null; + if(args.Length > 3) + { + eventToken = args[3]; + if (targetNpc.CurrentDialogue.Count > 0) targetNpc.RemoveDialogue(eventToken); + } + var msg = args[2].Replace("___", "#").Replace("$_", "$"); + targetNpc.npc.setNewDialogue(new Dialogue(targetNpc.npc, eventToken, msg), true, false); + } + catch (Exception e) + { + error = e.Message; + return false; + } + + error = null; + return true; + } private void ReceiveUpdateTick(object sender, OneSecondUpdateTickingEventArgs e) { - //Ignore everything until we've started the day - if (!started) - return; + //Ignore everything until we've started the day + if (!started) + return; + + //If time is moving, update our body state (Hunger, thirst, etc.) + if (ShouldTimePass()) + { + //body.HandleTime(timeInTick); to handle this cleaner, we move this to the time-changing tick - //If time is moving, update our body state (Hunger, thirst, etc.) - if (ShouldTimePass()) + + // The following block makes npc (usually) not talk to you if you wear wet or messy pants... short of the special texts + var isFilthy = body.pants.used; + foreach (var npc in NpcBody.ByRange(10)) { - this.body.HandleTime(timeInTick); - if (tickCD1 != 0) //Former Bug: When consuming items, they would give 2-3 goes at the "Handle eating and drinking." if statement below. Cause: This function would trigger multiple times while the if statement below was still true, causing it to fire multiple times. + if (npc.CurrentDialogue.Count > 0) npc.RemoveDialogue(dirtyEventToken); + if(npc.CurrentDialogue.Count > 0) npc.RemoveDialogue(generalEventToken); + + if (npc.Age == 2 && !ChildrenAndDiapers) continue; + + if (isFilthy) { - tickCD2 += 1; //This should trigger multiple times during the eating animation. + var mod = "dirty"; + var responseKey = mod + Animations.responseKeyAdditionForState(npc.npc, true); + + var randNpcString = Strings.RandString(npc.GetVillagerReactions(responseKey,mod).ToArray()); + if (randNpcString == "") continue; + var npcStatement = Strings.ReplaceAndOr(randNpcString, body.pants.wetness > 0, body.pants.messiness > 0); + npcStatement = Strings.InsertVariables(npcStatement, body, (Container)null); + if (npcStatement.Contains("DIAPER_CHANGE")) + { + npcStatement = Strings.ReplaceOptional(npcStatement, body.HasWetOrMessyDebuff()); + } + npcStatement = Strings.InsertVariables(npcStatement, npc.npc); + npc.npc.setNewDialogue(new Dialogue(npc.npc, dirtyEventToken, npcStatement), true, true); } - if (tickCD2 >= 2) //Setting this to 2 should be able to balance preventing double triggers and ensuring no loss in intentional triggers. + else if (npc.CurrentDialogue.Count <= 0) { - tickCD1 = 0; - tickCD2 = 0; + var mod = "general"; + var responseKey = mod + Animations.responseKeyAdditionForState(npc.npc, false); + + var randNpcString = Strings.RandString(npc.GetVillagerReactions(responseKey, mod).ToArray()); + if (randNpcString == "") continue; + var npcStatement = Strings.ReplaceAndOr(randNpcString, body.pants.wetness > 0, body.pants.messiness > 0); + if (npcStatement.Contains("DIAPER_CHANGE")) { + npcStatement = Strings.ReplaceOptional(npcStatement, body.HasWetOrMessyDebuff()); + } + npcStatement = Strings.InsertVariables(npcStatement, body, (Container)null); + npcStatement = Strings.InsertVariables(npcStatement, npc.npc); + + npc.npc.setNewDialogue(new Dialogue(npc.npc, dirtyEventToken, npcStatement), true, true); } - - } - //Handle eating and drinking. - if (Game1.player.isEating && Game1.activeClickableMenu == null && tickCD1 == 0) - { - body.Consume(who.itemToEat.Name); - tickCD1 += 1; } + } } + + //Determine if we need to handle time passing (not the same as Game time passing) private static bool ShouldTimePass() { @@ -241,8 +783,38 @@ private static bool ShouldTimePass() private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) { //If we haven't started the day, ignore the key presses - if (!started) - return; + if (!started) return; + + // We ignore keypresses in menues + if (Game1.activeClickableMenu != null) return; + + bool altDown = e.IsDown(SButton.LeftAlt); + bool shiftDown = e.IsDown(SButton.LeftShift); + + //START Keybind-section + if (!altDown) + { + bool triggered = true; + + int button = (int)e.Button; + if (button == config.KeyGoInPants && (!shiftDown || config.KeyGoInPants != config.KeyGoInToilet)) + body.WetAndMess(true, true); + else if (button == config.KeyGoInToilet) + body.WetAndMess(true, false); + else if (button == config.KeyPee && (!shiftDown || config.KeyPee != config.KeyPeeInToilet)) + body.Wet(true, true); + else if (button == config.KeyPoop && (!shiftDown || config.KeyPoop != config.KeyPoopInToilet)) + body.Mess(true, true); + else if (button == config.KeyPeeInToilet) + body.Wet(true, false); + else if (button == config.KeyPoopInToilet) + body.Mess(true, false); + else triggered = false; + + if (triggered) return; + } + // END Keybind-section + //Interpret buttons differently if holding Left Alt & Debug is enabled if (e.IsDown(SButton.LeftAlt) && config.Debug) @@ -269,25 +841,26 @@ private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) break; case SButton.F8: config.Easymode = !config.Easymode; + Animations.Write(config.Easymode ? Regression.t.EasyMode_On : Regression.t.EasyMode_Off, body); break; case SButton.S: if (e.IsDown(SButton.LeftShift)) { - body.ChangeBowelContinence(0.1f); + body.ChangeContinence(IncidentType.POOP, 0.1f); } else { - body.ChangeBladderContinence(0.1f); + body.ChangeContinence(IncidentType.PEE, 0.1f); } break; case SButton.W: if (e.IsDown(SButton.LeftShift)) { - body.ChangeBowelContinence(-0.1f); + body.ChangeContinence(IncidentType.POOP, -0.1f); } else { - body.ChangeBladderContinence(-0.1f); + body.ChangeContinence(IncidentType.PEE, -0.1f); } break; } @@ -296,12 +869,6 @@ private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) { switch (e.Button) { - case SButton.F1: - body.Wet(true, !e.IsDown(SButton.LeftShift)); - break; - case SButton.F2: - body.Mess(true, !e.IsDown(SButton.LeftShift)); - break; case SButton.F5: Animations.CheckUnderwear(body); break; @@ -311,9 +878,22 @@ private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) case SButton.F7: Animations.CheckContinence(body); break; - case SButton.F9: - config.Debug = !config.Debug; + case SButton.F8: + Animations.CheckPottyFeeling(body); + break; + /*case SButton.F9: + npcAccident(NpcByName("vincent"), IncidentType.PEE); break; + case SButton.F10: + npcAccident(NpcByName("vincent"), IncidentType.POOP); + break; + case SButton.F11: + npcAccident(NpcByName("jas"), IncidentType.PEE); + break; + case SButton.F12: + npcAccident(NpcByName("jas"), IncidentType.POOP); + break;*/ + } } } @@ -332,7 +912,7 @@ private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) if (Game1.currentLocation is FarmHouse && (attemptToSleepMenu = e.NewMenu as DialogueBox) != null && Game1.currentLocation.lastQuestionKey == "Sleep" && !config.Easymode) { //If enough time has passed, the bed has dried - if (body.bed.IsDrying()) + if (body.bed.drying) { Response[] sleepAttemptResponses = attemptToSleepMenu.responses; if (sleepAttemptResponses.Length == 2) @@ -356,34 +936,59 @@ private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) { //Default to all underwear being available List allUnderwear = Strings.ValidUnderwearTypes(); - List availableUnderwear = allUnderwear; - bool underwearAvailableAtShop = false; - if(Game1.currentLocation is SeedShop) - { - //The seed shop does not sell the Joja diaper - availableUnderwear.Remove("Joja diaper"); - underwearAvailableAtShop = true; - } else if(Game1.currentLocation is JojaMart) - { - //Joja shop ONLY sels the Joja diaper and a cloth diaper - availableUnderwear.Clear(); - availableUnderwear.Add("Joja diaper"); - availableUnderwear.Add("Cloth diaper"); - underwearAvailableAtShop = true; - } - - if(underwearAvailableAtShop) + if (Game1.currentLocation is SeedShop) { - foreach(string type in availableUnderwear) + foreach (string type in allUnderwear) { - Underwear underwear = new Underwear(type, 0.0f, 0.0f, 1); - currentShopMenu.forSale.Add(underwear); - currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, 999)); + //The seed shop does not sell the Joja diaper + if (type == "joja diaper") continue; + //The seed shop does not sell every diaper and underwear as single items + addUnderwearToShop(currentShopMenu, type); } + } else if(Game1.currentLocation is JojaMart) { + // Joja shop sells big brands now, "pampers" and "dry nites". You probably also find normal undies and simple cloth diapers there. + // As such uses packages and has slightly lower prices (bulk) + // This makes sense and mirrors the advantages and disadvantages of large chains in rual areas + var type = "joja diaper"; + if (allUnderwear.Contains(type)) + { + addUnderwearToShop(currentShopMenu, type, 10, 0.8f); + addUnderwearToShop(currentShopMenu, type, 40, 0.7f); + } + type = "baby print diaper"; + if (allUnderwear.Contains(type)) + { + addUnderwearToShop(currentShopMenu, type, 20, 0.8f); + addUnderwearToShop(currentShopMenu, type, 60, 0.7f); + } + type = "lavender pullups"; + if (allUnderwear.Contains(type)) + { + addUnderwearToShop(currentShopMenu, type, 10, 0.8f); + addUnderwearToShop(currentShopMenu, type, 40, 0.7f); + } + type = "big kid undies"; + if (allUnderwear.Contains(type)) + { + addUnderwearToShop(currentShopMenu, type, 3, 0.8f); + } + type = "cloth diaper"; + if (allUnderwear.Contains(type)) + { + addUnderwearToShop(currentShopMenu, type, 5, 0.75f); + } + } } } + private static void addUnderwearToShop(ShopMenu shop, string type, int amount = 1, float priceMultiplier = 1f) + { + var underwear = new Underwear(type, amount); + shop.forSale.Add(underwear); + shop.itemPriceAndStock.Add(underwear, new ItemStockInformation( (int)Math.Ceiling((float)underwear.container.price * (float)amount * priceMultiplier), StardewValley.Menus.ShopMenu.infiniteStock)); + } + //Check if we are at a natural water source private static bool AtWaterSource() { @@ -415,18 +1020,66 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) return; } - //Handle a Left Click + //If we try to take or put down pants, this should only work if you are allowed to change them. if (e.Button == SButton.MouseLeft) { + + var men = Game1.activeClickableMenu as StardewValley.Menus.GameMenu; + if (men != null) + { + var inventory = men.pages[men.currentTab] as StardewValley.Menus.InventoryPage; + if (inventory != null) + { + var clothing = inventory.hoveredItem as StardewValley.Objects.Clothing; + if(clothing != null) + { + if(clothing.clothesType.Value == Clothing.ClothesType.PANTS) + { + if (body.HasWetOrMessyDebuff()) + { + Game1.activeClickableMenu = null; + if (!Regression.config.PantsChangeRequiresHome || body.InPlaceWithPants()) + { + body.ResetPants(); + Animations.Write(Regression.t.Change_At_Home, body); + } + else + { + Animations.Write(Regression.t.Change_Requires_Home, body); + } + + return; + + } + } + } + } + } + //If Left click is already being interpreted by another event (or we otherwise wouldn't process such an event. Ignore it. if ((Game1.dialogueUp || Game1.currentMinigame != null || (Game1.eventUp || Game1.activeClickableMenu != null) || Game1.fadeToBlack) || (who.isRidingHorse() || !who.canMove || (Game1.player.isEating || who.canOnlyWalk) || who.FarmerSprite.pauseForSingleAnimation)) return; + // This block tries to figure out if the clicked point was in the toolbar. Because if it was, we assume the intent was not to use the selected item. + var pos = e.Cursor.ScreenPixels; + Toolbar toolbar = Game1.onScreenMenus.OfType().FirstOrDefault(); + if (toolbar != null) + { + foreach (var button in toolbar.buttons) + { + if (button.containsPoint((int)pos.X, (int)pos.Y)) + { + // The click was on the toolbar + return; + } + } + } + ////If we're holding the watering can, attempt to drink from it. /////This is the highest priority (apparently?) if (who.CurrentTool != null && who.CurrentTool is WateringCan && e.IsDown(SButton.LeftShift)) { - this.body.DrinkWateringCan(); + body.DrinkWateringCan(); return; } @@ -435,26 +1088,35 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) if (activeObject != null) { //If the Underwear we are holding isn't currently wet, messy, or drying; change into it. - if ((double)activeObject.container.wetness + (double)activeObject.container.messiness == 0.0 && !activeObject.container.IsDrying()) + if ((double)activeObject.container.wetness + (double)activeObject.container.messiness == 0.0 && !activeObject.container.drying) { if(Regression.config.PantsChangeRequiresHome && body.HasWetOrMessyDebuff() && !body.InPlaceWithPants()) { - Animations.Say(Regression.t.Change_Requires_Pants, body); + Animations.Write(Regression.t.Change_Requires_Pants, body); return; } - who.reduceActiveItemByOne(); //Take it out of inventory - Container container = body.ChangeUnderwear(activeObject); //Put on the new underwear and return the old - Underwear underwear = new Underwear(container.name, container.wetness, container.messiness, 1); + + Underwear OldUnderwear = new Underwear(body.underwear, 1); + + if (Regression.config.UnderwearChangeCauseExposure) + { + Animations.HandleVillager(body, false, false, false, true); + } + body.ChangeUnderwear(activeObject); + who.reduceActiveItemByOne(); + body.ResetPants(); //If the underwear returned is not removable, destroy it - if (!container.removable) { } + if (!OldUnderwear.container.washable) { + Animations.Warn(Regression.t.Change_Destroyed, body, OldUnderwear.container); + } //Otherwise put the old underwear into the inventory, but pull up the management window if it can't fit - else if (!who.addItemToInventoryBool(underwear, false)) + else if (!who.addItemToInventoryBool(OldUnderwear, false)) { List objList = new List(); - objList.Add(underwear); + objList.Add(OldUnderwear); Game1.activeClickableMenu = new ItemGrabMenu(objList); - } + } } //If it is wet, messy or drying, check if we can wash it else if (activeObject.container.washable) @@ -472,10 +1134,31 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) //If we're at a water source, and not holding underwear, drink from it. if ((AtWaterSource()|| AtWell()) && e.IsDown(SButton.LeftShift)) - this.body.DrinkWaterSource(); + body.DrinkWaterSource(); } } + public static bool ChildrenAndDiapers + { + get + { + if (Game1.player.dialogueQuestionsAnswered.Contains("102")) return false; + if (Game1.player.dialogueQuestionsAnswered.Contains("101")) return true; + return true; + } + set + { + if (value) { + if (Game1.player.dialogueQuestionsAnswered.Contains("102")) Game1.player.DialogueQuestionsAnswered.Remove("102"); + if (!Game1.player.dialogueQuestionsAnswered.Contains("101")) Game1.player.DialogueQuestionsAnswered.Add("101"); + } + else + { + if (Game1.player.dialogueQuestionsAnswered.Contains("101")) Game1.player.DialogueQuestionsAnswered.Remove("101"); + if (!Game1.player.dialogueQuestionsAnswered.Contains("102")) Game1.player.DialogueQuestionsAnswered.Add("102"); + } + } + } //If approppriate, draw bars for Hunger, thirst, bladder and bowels public void ReceivePreRenderHudEvent(object sender, RenderingHudEventArgs args) @@ -484,19 +1167,505 @@ public void ReceivePreRenderHudEvent(object sender, RenderingHudEventArgs args) return; DrawStatusBars(); } + private void OnGameLaunched(object sender, GameLaunchedEventArgs e) + { + // get Generic Mod Config Menu's API (if it's installed) + var configMenu = this.Helper.ModRegistry.GetApi("spacechase0.GenericModConfigMenu"); + if (configMenu is null) + return; + + // register mod + configMenu.Register( + mod: this.ModManifest, + reset: () => config = new Config(), + save: () => this.Helper.WriteConfig(config) + ); + + // Config of the main page. Most important options + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Cheat Mode", + tooltip: () => "Allowes to spawn items, change potty training and displays debug related messages. (Debug)", + getValue: () => config.Debug, + setValue: value => config.Debug = value + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Easy Mode", + tooltip: () => "Hunger and Thirst are refilled every morning and the wet beds dried. (Easymode)", + getValue: () => config.Easymode, + setValue: value => config.Easymode = value + ); + + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Wetting", + tooltip: () => "This activates pee and bladder events.", + getValue: () => config.Wetting, + setValue: value => config.Wetting = value + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Messing", + tooltip: () => "This activates poop and bowel events.", + getValue: () => config.Messing, + setValue: value => config.Messing = value + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Children and Diapers", + tooltip: () => "Would you be comfortable seeing diaper related dialogue from Vincent and Jas?", + getValue: () => ChildrenAndDiapers, + setValue: value => ChildrenAndDiapers = value + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Bladder Capacity (mL)", + tooltip: () => "600 is around 3 potty runs a day. (MaxBladderCapacity)", + getValue: () => config.MaxBladderCapacity, + setValue: value => config.MaxBladderCapacity = value, + min: 300, max: 1800, interval: 50 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Bowel Capacity (mL)", + tooltip: () => "1000 is around 1.5 potty runs a day. (MaxBowelCapacity)", + getValue: () => config.MaxBowelCapacity, + setValue: value => config.MaxBowelCapacity = value, + min: 300, max: 1800, interval: 50 + ); + + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Always notice accidents", + tooltip: () => "Defines if you will notice accidents on low control values. (AlwaysNoticeAccidents)", + getValue: () => config.AlwaysNoticeAccidents, + setValue: value => config.AlwaysNoticeAccidents = value + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Pants Change at Home", + tooltip: () => "Changing your pants (in case you soiled your cloth) requires you to be at home. (Usually on) (PantsChangeRequiresHome)", + getValue: () => config.PantsChangeRequiresHome, + setValue: value => config.PantsChangeRequiresHome = value + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Underwear Change Causes Exposure", + tooltip: () => "Changing your underwear, by yourself, requires you to undress, as such exposing yourself. With this option activated you need to change your diapers at home or away from people. (Usually on) (UnderwearChangeCauseExposure)", + getValue: () => config.UnderwearChangeCauseExposure, + setValue: value => config.UnderwearChangeCauseExposure = value + ); + + configMenu.AddPageLink( + mod: this.ModManifest, + pageId: "Key Bindings", + text: () => "Key Bindings" + ); + configMenu.AddPageLink( + mod: this.ModManifest, + pageId: "Continence", + text: () => "Continence" + ); + configMenu.AddPageLink( + mod: this.ModManifest, + pageId: "Friendships", + text: () => "Friendships" + ); + configMenu.AddPageLink( + mod: this.ModManifest, + pageId: "Continence", + text: () => "Continence" + ); + configMenu.AddPageLink( + mod: this.ModManifest, + pageId: "Save Files", + text: () => "Save Files" + ); + // All the options related to continence balancing + configMenu.AddPage( + mod: this.ModManifest, + pageId: "Key Bindings" + ); + configMenu.AddKeybind( + mod: this.ModManifest, + name: () => "Pee Pants", + tooltip: () => "The key you want to press to just piddle yourself. (KeyPee)", + getValue: () => (SButton)config.KeyPee, + setValue: value => config.KeyPee = (int)value + ); + configMenu.AddKeybind( + mod: this.ModManifest, + name: () => "Poop Pants", + tooltip: () => "The key you want to press to just poop yourself. (KeyPoop)", + getValue: () => (SButton)config.KeyPoop, + setValue: value => config.KeyPoop = (int)value + ); + configMenu.AddKeybind( + mod: this.ModManifest, + name: () => "Pee In Potty", + tooltip: () => "The key you want to press to pee in the potty like a good girl or boy. (KeyPeeInToilet)", + getValue: () => (SButton)config.KeyPeeInToilet, + setValue: value => config.KeyPeeInToilet = (int)value + ); + configMenu.AddKeybind( + mod: this.ModManifest, + name: () => "Poop In Potty", + tooltip: () => "The key you want to press to poop in the potty like a good girl or boy. (KeyPoopInToilet)", + getValue: () => (SButton)config.KeyPoopInToilet, + setValue: value => config.KeyPoopInToilet = (int)value + ); + configMenu.AddKeybind( + mod: this.ModManifest, + name: () => "Go In Pants", + tooltip: () => "The key you want to press to pee and poop yourself. (KeyGoInPants)", + getValue: () => (SButton)config.KeyGoInPants, + setValue: value => config.KeyGoInPants = (int)value + ); + configMenu.AddKeybind( + mod: this.ModManifest, + name: () => "Go Potty", + tooltip: () => "The key you want to press to pee and poop in the potty like a good girl or boy. (KeyGoInToilet)", + getValue: () => (SButton)config.KeyGoInToilet, + setValue: value => config.KeyGoInToilet = (int)value + ); + + // All the options related to continence balancing + configMenu.AddPage( + mod: this.ModManifest, + pageId: "Continence" + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Nighttime Losses", + tooltip: () => "How serious the loss of potty training is at night, compared to daytime. Usually 50 (half). (NighttimeLossMultiplier)", + getValue: () => config.NighttimeLossMultiplier, + setValue: value => config.NighttimeLossMultiplier = value, + min: 0, max: 200, interval: 10 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Nighttime Gains", + tooltip: () => "How big the gains are if you stay dry/clean at night, compared to daytime. Usually 50 (half). (NighttimeGainMultiplier)", + getValue: () => config.NighttimeGainMultiplier, + setValue: value => config.NighttimeGainMultiplier = value, + min: 0, max: 200, interval: 10 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "In Diaper on Purpose Modifier", + tooltip: () => "How big of a negativ impact has an accident in underwear if it was on purpose?. Usually 50 (half) as much as an actual accident.", + getValue: () => config.InUnderwearOnPurposeMultiplier, + setValue: value => config.InUnderwearOnPurposeMultiplier = value, + min: 0, max: 200, interval: 10 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Accident Bladder Loss", + tooltip: () => $"2 is a 2% continence loss for {config.MaxBladderCapacity}mL accidents. (BladderLossContinenceRate)", + getValue: () => config.BladderLossContinenceRate, + setValue: value => config.BladderLossContinenceRate = value, + min: 0, max: 20, interval: 1 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Accident Bowel Loss", + tooltip: () => $"3 is a 3% continence loss for {config.MaxBowelCapacity}mL accidents. (BowelLossContinenceRate)", + getValue: () => config.BowelLossContinenceRate, + setValue: value => config.BowelLossContinenceRate = value, + min: 0, max: 20, interval: 1 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Toilet Bladder Gain", + tooltip: () => $"3 is a 3% continence gain for making it to the toilet with a bladder that is at least half full. (BladderGainContinenceRate)", + getValue: () => config.BladderGainContinenceRate, + setValue: value => config.BladderGainContinenceRate = value, + min: 0, max: 20, interval: 1 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Toilet Bowel Gain", + tooltip: () => $"3 is a 3% continence gain for making it to the toilet with a bowel that is at least half full. (BowelGainContinenceRate)", + getValue: () => config.BowelGainContinenceRate, + setValue: value => config.BowelGainContinenceRate = value, + min: 0, max: 20, interval: 1 + ); + + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Start Bladder Continence", + tooltip: () => $"Defines the starting (new game) bladder continence. Usually 70. Also applies to old saves without this mod activated (StartBladderContinence)", + getValue: () => config.StartBladderContinence, + setValue: value => config.StartBladderContinence = value, + min: (int)(Body.minBladderContinence * 100), max: 100, interval: 5 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Start Bowel Continence", + tooltip: () => $"Defines the starting (new game) bowel continence. Usually 90. Also applies to old saves without this mod activated (StartBowelContinence)", + getValue: () => config.StartBowelContinence, + setValue: value => config.StartBowelContinence = value, + min: (int)(Body.minBowelContinence * 100), max: 100, interval: 5 + ); + + // All the options related to friendship changes caused by accidents + configMenu.AddPage( + mod: this.ModManifest, + pageId: "Friendships" + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Penalty Peeing", + tooltip: () => "How peeing in public impacts friendships. 100 is normal, 50 would be half, 200 double the impact. 0 deactivates loss of frienship for pee incidents. (FriendshipPenaltyBladderMultiplier)", + getValue: () => config.FriendshipPenaltyBladderMultiplier, + setValue: value => config.FriendshipPenaltyBladderMultiplier = value, + min: 0, max: 500, interval: 10 + ); + configMenu.AddNumberOption( + mod: this.ModManifest, + name: () => "Penalty Pooping", + tooltip: () => "How pooping in public impacts friendships. 100 is normal, 50 would be half, 200 double the impact. 0 deactivates loss of frienship for poop incidents. (FriendshipPenaltyBowelMultiplier)", + getValue: () => config.FriendshipPenaltyBowelMultiplier, + setValue: value => config.FriendshipPenaltyBowelMultiplier = value, + min: 0, max: 500, interval: 10 + ); + + // All the options related to save files + configMenu.AddPage( + mod: this.ModManifest, + pageId: "Save Files" + ); + configMenu.AddParagraph( + mod: this.ModManifest, + text: () => "Starting at version 1.5.0, save files (json) are no longer required/created. The only use of this functions is to load old save files or manually edit saves." + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Read Save Files", + tooltip: () => "This will activate reading of the (legacy) save files. This will also delete save files from the last day, if a new one starts.", + getValue: () => config.ReadSaveFiles, + setValue: value => config.ReadSaveFiles = value + ); + configMenu.AddBoolOption( + mod: this.ModManifest, + name: () => "Write Save Files", + tooltip: () => "This will activate writing of the (legacy) save files. It is recommended to disable this option.", + getValue: () => config.WriteSaveFiles, + setValue: value => config.WriteSaveFiles = value + ); + } + public void DrawStatusBars() + { + + int x1 = Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Right - (65 + (int)((StatusBars.barWidth))); + int y1 = Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - (25 + (int)((StatusBars.barHeight))); + + if (Game1.currentLocation is MineShaft || Game1.currentLocation is Woods || Game1.currentLocation is SlimeHutch || Game1.currentLocation is VolcanoDungeon || who.health < who.maxHealth) + x1 -= 58; + + if (!config.NoHungerAndThirst || config.Debug) + { + float percentage1 = body.GetHungerPercent(); + StatusBars.DrawStatusBar(x1, y1, percentage1, new Color(115, byte.MaxValue, 56)); + int x2 = x1 - (10 + StatusBars.barWidth); + float percentage2 = body.GetThirstPercent(); + StatusBars.DrawStatusBar(x2, y1, percentage2, new Color(117, 225, byte.MaxValue)); + x1 = x2 - (10 + StatusBars.barWidth); + } + if (config.Debug) + { + if (config.Messing) + { + float percentage = body.GetBowelPercent(); + StatusBars.DrawStatusBar(x1, y1, percentage, new Color(146, 111, 91)); + x1 -= 10 + StatusBars.barWidth; + } + if (config.Wetting) + { + float percentage = body.GetBladderPercent(); + StatusBars.DrawStatusBar(x1, y1, percentage, new Color(byte.MaxValue, 225, 56)); + } + } + if (!config.Wetting && !config.Messing) + return; + int y3 = (Game1.player.questLog).Count == 0 ? 250 : 310; + var x3 = Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Right - 94; + Animations.DrawUnderwearIcon(body.underwear, x3, y3); + + Animations.DrawStateIcon(body, IncidentType.PEE, x3, y3 + 74); + Animations.DrawStateIcon(body, IncidentType.POOP, x3, y3 + 74 + 74); + } + + /// The original time in HHMM format (e.g., 1550 for 15:50). + /// The new time in HHMM format (e.g., 1600 for 16:00). + /// The difference in minutes as an integer. + /// Thrown when input times are invalid. + public int GetTimeDifference(int oldTime, int newTime) + { + // Validate and convert HHMM to total minutes since midnight + int ConvertToMinutes(int time) + { + int hours = time / 100; + int minutes = time % 100; + if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) + throw new ArgumentException($"Invalid time format: {time}. Expected HHMM with HH=00-23 and MM=00-59."); + return hours * 60 + minutes; + } + + int oldMinutes = ConvertToMinutes(oldTime); + int newMinutes = ConvertToMinutes(newTime); + + // Calculate the difference, accounting for midnight wrap-around + return newMinutes >= oldMinutes + ? newMinutes - oldMinutes + : (1440 - oldMinutes) + newMinutes; + } private void ReceiveTimeOfDayChanged(object sender, TimeChangedEventArgs e) { - lastTimeOfDay = Game1.timeOfDay; - //If its 6:10AM, handle delivering mail - if (Game1.timeOfDay == 610) - Mail.CheckMail(); + //lastTimeOfDay = Game1.timeOfDay; - //If its earlier than 6:30, we aren't wet/messy don't notice that we're still soiled (or don't notice with ~5% chance even if soiled) - if (rnd.NextDouble() >= 0.0555555559694767 || body.underwear.wetness + (double)body.underwear.messiness <= 0.0 || Game1.timeOfDay < 630) + int newTime = e.NewTime; + int oldTime = e.OldTime; + + // Calculate the difference + int difference = GetTimeDifference(oldTime, newTime); + + //Monitor.Log($"Time changed from {oldTime} to {newTime}. Difference: {difference} minutes.", LogLevel.Debug); + if(difference < 120) // we make sure that this doesn't get out of hand. Daychange is handled seperatly. + { + // If all of the 24 hours would be done as a 1 minute tick, there would be 1440 ticks in theory + /*float tickLen = 1440f; + float lengthTotal = (float) difference / (float)tickLen;*/ + // But we handle this as fraction of an hour, so its 1/60 * minutes + float fractionOfAnHour = (float)difference * (1f / 60f); + body.HandleTime((float)difference * (1f/60f)); + + // NPC actions are based on chance. Chances that would be vastly different if every client would run them seperatly + if (!Game1.IsMultiplayer || Game1.IsServer) + { + + foreach (NPC npc in Utility.getAllCharacters()) + { + new NpcBody(npc).RandomAction(fractionOfAnHour); + } + + } + } + + + // Update lastTimeOfDay + lastTimeOfDay = newTime; + + if (newTime < 630) return; - Animations.AnimateStillSoiled(this.body); + + //If its earlier than 6:30, we aren't wet/messy don't notice that we're still soiled (or don't notice with ~5% chance even if soiled) + if (rnd.NextDouble() < 0.0555555559694767 && body.underwear.wetness + (double)body.underwear.messiness > 0.0) + Animations.AnimateStillSoiled(body); + + if (rnd.NextDouble() < 0.0555555559694767 && (body.NeedsChangies(IncidentType.PEE) || body.NeedsChangies(IncidentType.POOP))) + Animations.AnimateShouldChange(body); + + if (Game1.player.dialogueQuestionsAnswered.Contains("change_other_yes")) + Game1.player.dialogueQuestionsAnswered.Remove("change_other_yes"); + if (Game1.player.dialogueQuestionsAnswered.Contains("change_other_no")) + Game1.player.dialogueQuestionsAnswered.Remove("change_other_no"); + } + + private delegate bool ActionHandler(string[] args, TriggerActionContext context, out string error); + public bool ActionManager(string[] args, TriggerActionContext context, out string error) + { + error = null; + + // Remove the first arg "ACTION_MANAGER" + args = args.Skip(1).ToArray(); + + // Dictionary of known actions + var actionHandlers = new Dictionary() + { + { "DIAPER_CHANGE", StartChange }, + { "CHANGE_DIAPER_OTHERS", StartChangeOthers }, + { "DIAPER_ACCIDENT", StartAccident}, + { "ADD_DIALOG", AddNpcMessage}, + { "GIVE_UNDERWEAR", GiveUnderwear} + // Add more actions here + }; + + int index = 0; + while (index < args.Length) + { + string actionName = args[index]; + if (!actionHandlers.ContainsKey(actionName)) + { + /*error = $"Unknown action: {actionName}"; + return false;*/ + // we will just assume that its not an action but a parameter from another function + } + + // Find the next action in the list or the end of the array + int nextActionIndex = args.Length; + for (int i = index + 1; i < args.Length; i++) + { + if (actionHandlers.ContainsKey(args[i])) + { + nextActionIndex = i; + break; + } + } + + // Extract arguments for this action (including the action name itself) + string[] actionArgs = args.Skip(index).Take(nextActionIndex - index).ToArray(); + + // Execute the action + if (!actionHandlers[actionName](actionArgs, context, out error)) + { + return false; + } + + // Move to the next action + index = nextActionIndex; + } + + return true; + } + + private static Queue<(Action action, int delay)> actionQueue = new Queue<(Action, int)>(); + private static bool isExecutingAction = false; + + public static void QueueAction(Action action, int delay = 1000) + { + actionQueue.Enqueue((action, delay)); + } + + private static void ExecuteNextAction() + { + if (actionQueue.Count == 0) return; + + isExecutingAction = true; + (Action action, int delay) nextAction = actionQueue.Dequeue(); + + // Execute the custom action + nextAction.action(); + + // Wait before allowing the next action to execute + DelayedAction.functionAfterDelay(() => + { + isExecutingAction = false; + }, nextAction.delay); + } + + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) + { + if (!Context.IsWorldReady) return; // Ensure the game world is loaded + + // If the queue has actions and no menu/dialogue is active, execute the next action + if (actionQueue.Count > 0 && Game1.activeClickableMenu == null && !isExecutingAction) + { + ExecuteNextAction(); + } } public Regression() diff --git a/Regression/PrimevalTitmouse/Strings.cs b/Regression/PrimevalTitmouse/Strings.cs index 6c26a52..d3926f0 100644 --- a/Regression/PrimevalTitmouse/Strings.cs +++ b/Regression/PrimevalTitmouse/Strings.cs @@ -1,4 +1,5 @@ -using StardewValley; +using Microsoft.Xna.Framework.Input; +using StardewValley; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -6,105 +7,210 @@ namespace PrimevalTitmouse { //Lots of Regex functions to handle variability in our strings. - public static class Strings - { - private static Data t = Regression.t; - private static Farmer who = Game1.player; - - public static string DescribeUnderwear(Container u, string baseDescription = null) + public static class Strings { - string newValue = baseDescription != null ? baseDescription : u.description; - float num1 = u.wetness / u.absorbency; - float num2 = u.messiness / u.containment; - if ((double) num1 == 0.0 && (double) num2 == 0.0) - { - newValue = !u.IsDrying() ? Strings.t.Underwear_Clean.Replace("$UNDERWEAR_DESC$", newValue) : Strings.t.Underwear_Drying.Replace("$UNDERWEAR_DESC$", newValue); - } - else - { - if ((double) num2 > 0.0) + private static Data t = Regression.t; + private static Farmer who = Game1.player; + + public static string DescribeUnderwear(Container u, string baseDescription = null, bool noPrefix = false) { - for (int index = 0; index < Strings.t.Underwear_Messy.Length; ++index) - { - float num3 = (float) (((double) index + 1.0) / ((double) Strings.t.Underwear_Messy.Length - 1.0)); - if (index == Strings.t.Underwear_Messy.Length - 1 || (double) num2 <= (double) num3) + string newValue = baseDescription != null ? baseDescription : u.description; + float num1 = u.wetness / u.absorbency; + float num2 = u.messiness / u.containment; + if ((double)num1 == 0.0 && (double)num2 == 0.0) + { + newValue = !u.drying ? Strings.t.Underwear_Clean.Replace("$UNDERWEAR_DESC$", newValue) : Strings.t.Underwear_Drying.Replace("$UNDERWEAR_DESC$", newValue); + } + else { - newValue = Strings.ReplaceOptional(Strings.t.Underwear_Messy[index].Replace("$UNDERWEAR_DESC$", newValue), (double) num1 > 0.0); - break; + if ((double)num2 > 0.0) + { + for (int index = 0; index < Strings.t.Underwear_Messy.Length; ++index) + { + float num3 = (float)(((double)index + 1.0) / ((double)Strings.t.Underwear_Messy.Length - 1.0)); + if (index == Strings.t.Underwear_Messy.Length - 1 || (double)num2 <= (double)num3) + { + newValue = Strings.ReplaceOptional(Strings.t.Underwear_Messy[index].Replace("$UNDERWEAR_DESC$", newValue), (double)num1 > 0.0); + break; + } + } + } + if ((double)num1 > 0.0) + { + for (int index = 0; index < Strings.t.Underwear_Wet.Length; ++index) + { + float num3 = (float)(((double)index + 1.0) / ((double)Strings.t.Underwear_Wet.Length - 1.0)); + if (index == Strings.t.Underwear_Wet.Length - 1 || (double)num1 <= (double)num3) + { + string input = Strings.t.Underwear_Wet[index].Replace("$UNDERWEAR_DESC$", newValue); + Regex regex = new Regex("<([^>]*)>"); + newValue = (double)num2 != 0.0 ? regex.Replace(input, "$1") : regex.Replace(input, ""); + break; + } + } + } } - } + string newOrOld = ""; + if(u.washable && u.InnerContainer != null && u.durability < u.InnerContainer.durability) + { + newOrOld = "used "; + if(u.durability < u.InnerContainer.durability / 2) + { + newOrOld = "old "; + } + } + if (noPrefix) return newValue; + return u.GetPrefix() + " " + newOrOld + newValue; } - if ((double) num1 > 0.0) + + + public static string InsertVariables(string msg, Body b, Container c = null) { - for (int index = 0; index < Strings.t.Underwear_Wet.Length; ++index) - { - float num3 = (float) (((double) index + 1.0) / ((double) Strings.t.Underwear_Wet.Length - 1.0)); - if (index == Strings.t.Underwear_Wet.Length - 1 || (double) num1 <= (double) num3) + string str = msg; + if (b != null && c == null) + c = b.underwear; + if (c != null) { - string input = Strings.t.Underwear_Wet[index].Replace("$UNDERWEAR_DESC$", newValue); - Regex regex = new Regex("<([^>]*)>"); - newValue = (double) num2 != 0.0 ? regex.Replace(input, "$1") : regex.Replace(input, ""); - break; + var gettingChangedDialog = Strings.RandString(Animations.Data.Diaper_Change_Dialog); + gettingChangedDialog = Strings.ReplaceAndOr(gettingChangedDialog, c.wetness > 0, c.messiness > 0); + str = str.Replace("$GETTING_CHANGED_DIALOG$", "#$b#" + gettingChangedDialog); + + str = Strings.ReplaceConditionalOptional(str, "OnSlightlyWet", c.used && !c.used_bad); + str = Strings.ReplaceConditionalOptional(str, "OnClean", !c.used); + str = Strings.ReplaceOr(str.Replace("$UNDERWEAR_NAME$", c.displayName).Replace("$UNDERWEAR_PREFIX$", c.GetPrefix()).Replace("$UNDERWEAR_DESC$", c.description).Replace("$INSPECT_UNDERWEAR_NAME$", Strings.DescribeUnderwear(c, c.displayName)).Replace("$INSPECT_UNDERWEAR_NAME_NO_PREFIX$", Strings.DescribeUnderwear(c, c.displayName,true)).Replace("$INSPECT_UNDERWEAR_DESC$", Strings.DescribeUnderwear(c, c.description)), !c.plural, "#"); + } - } + + if (b != null) + { + str = Strings.ReplaceConditionalOptional(str, "OnDebuffed", b.HasWetOrMessyDebuff()); + str = str.Replace("$PANTS_NAME$", b.pants.displayName).Replace("$PANTS_PREFIX$", b.pants.GetPrefix()).Replace("$PANTS_DESC$", b.pants.description).Replace("$BEDDING_DRYTIME$", Game1.getTimeOfDayString(b.bed.timeWhenDoneDrying.time)); + } + + return Strings.ReplaceOr(str, Strings.who.IsMale, "/").Replace("$FARMERNAME$", Strings.who.Name); } - } - return u.GetPrefix() + " " + newValue; + public static string npcUnderwearOptions(NPC npc) + { + var modifiers = Animations.Data.Villager_Underwear_Options; + Dictionary> foundDict = null; + + foreach (string key2 in Animations.npcTypeList(npc)) + { + Dictionary> dictionary; + if (modifiers.TryGetValue(key2, out dictionary)) + { + foundDict = dictionary; + } + } + + if (foundDict == null) return ""; + var list = new List(); + foreach (string key in foundDict.Keys) + { + if (!Regression.HasUnderwear(key)) continue; + var entry = foundDict[key]; + // #$r change_other_yes 2 Change_Diaper_Accept#Yes + list.Add($"#$r change_other_yes {entry["friendship"]} {entry["dialog_key"]} {(entry.TryGetValue("observerfriendship", out string val) ? val : "")}#{key.FirstCharToUpper()}"); + } + list.Add($"#$r change_other_no 0 Change_Diaper_Refuse#Not now"); + return string.Join("#", list); } + public static string InsertVariables(string msg, NPC b, Container c = null) + { + string str = msg; + if (b != null && c == null) + c = new NpcBody(b).underwear; + if (c != null) + { + var changeOtherDialog = Strings.RandString(Animations.Data.Change_Other_Dialog); + changeOtherDialog = Strings.ReplaceAndOr(changeOtherDialog, c.wetness > 0, c.messiness > 0); + changeOtherDialog += npcUnderwearOptions(b); + str = str.Replace("$CHANGE_OTHER_DIALOG$", changeOtherDialog); + str = Strings.ReplaceConditionalOptional(str, "NpcOnSlightlyWet", c.used && !c.used_bad); + str = Strings.ReplaceConditionalOptional(str, "NpcOnUsedBad", c.used && c.used_bad); + str = Strings.ReplaceConditionalOptional(str, "NpcOnClean", !c.used); + str = Strings.ReplaceOr(str.Replace("$NPC_UNDERWEAR_NAME$", c.displayName).Replace("$NPC_UNDERWEAR_PREFIX$", c.GetPrefix()).Replace("$NPC_UNDERWEAR_DESC$", c.description).Replace("$NPC_INSPECT_UNDERWEAR_NAME$", Strings.DescribeUnderwear(c, c.displayName)).Replace("$NPC_INSPECT_UNDERWEAR_NAME_NO_PREFIX$", Strings.DescribeUnderwear(c, c.displayName,true)).Replace("$NPC_INSPECT_UNDERWEAR_DESC$", Strings.DescribeUnderwear(c, c.description)), !c.plural, "#"); - public static string InsertVariables(string msg, Body b, Container c = null) - { - string str = msg; - if (b != null) - c = b.underwear; - if (c != null) - str = Strings.ReplaceOr(str.Replace("$UNDERWEAR_NAME$", c.name).Replace("$UNDERWEAR_PREFIX$", c.GetPrefix()).Replace("$UNDERWEAR_DESC$", c.description).Replace("$INSPECT_UNDERWEAR_NAME$", Strings.DescribeUnderwear(c, c.name)).Replace("$INSPECT_UNDERWEAR_DESC$", Strings.DescribeUnderwear(c, c.description)), !c.plural, "#"); - if (b != null) - str = str.Replace("$PANTS_NAME$", b.pants.name).Replace("$PANTS_PREFIX$", b.pants.GetPrefix()).Replace("$PANTS_DESC$", b.pants.description).Replace("$BEDDING_DRYTIME$", Game1.getTimeOfDayString(b.bed.timeWhenDoneDrying.time)); - return Strings.ReplaceOr(str, Strings.who.IsMale, "/").Replace("$FARMERNAME$", Strings.who.Name); - } + } - public static string InsertVariable(string inputString, string variableName, string variableValue) - { - string outputString = inputString; + if (b != null) + { + var pants = new NpcBody(b).pants; + str = str.Replace("$NPC_PANTS_NAME$", pants.displayName).Replace("$NPC_PANTS_PREFIX$", pants.GetPrefix()).Replace("$NPC_PANTS_DESC$", pants.description); + str = str.Replace("$NPC_NAME$", b.Name.FirstCharToUpper()); + str = str.Replace("$NPC_HE_SHE$", b.Gender == Gender.Male ? "he" : (b.Gender == Gender.Female ? "she" : "they")); + str = str.Replace("$NPC_HIS_HER$", b.Gender == Gender.Male ? "his" : (b.Gender == Gender.Female ? "her" : "their")); + str = str.Replace("$NPC_HIM_HER$", b.Gender == Gender.Male ? "him" : (b.Gender == Gender.Female ? "her" : "them")); + str = str.Replace("$NPC_HIS_HER_IS_ARE$", b.Gender == Gender.Male ? "his" : (b.Gender == Gender.Female ? "her" : "their")); + } + + + return str; + } + + + public static string InsertVariable(string inputString, string variableName, string variableValue) + { + string outputString = inputString; outputString = outputString.Replace(variableName, variableValue); - return outputString; - } + return outputString; + } - public static string RandString(string[] msgs = null) - { - return msgs[Regression.rnd.Next(msgs.Length)]; - } + public static string RandString(string[] msgs = null) + { + if (msgs == null || msgs.Length == 0) return ""; + return msgs[Regression.rnd.Next(msgs.Length)]; + } - public static string ReplaceAndOr(string str, bool first, bool second, string splitChar = "&") - { - Regex regex = new Regex("<([^>" + splitChar + "]*)" + splitChar + "([^>]*)>"); - if (first && !second) - return regex.Replace(str, "$1"); - if (!first & second) - return regex.Replace(str, "$2"); - if (first & second) - return regex.Replace(str, "$1 and $2"); - return regex.Replace(str, ""); - } + public static string ReplaceAndOr(string str, bool first, bool second, string splitChar = "&") + { + Regex regex = new Regex("<([^>" + splitChar + "]*)" + splitChar + "([^>]*)>"); + if (first && !second) + return regex.Replace(str, "$1"); + if (!first & second) + return regex.Replace(str, "$2"); + if (first & second) + return regex.Replace(str, "$1 and $2"); + return regex.Replace(str, ""); + } - public static string ReplaceOptional(string str, bool keep) - { - return new Regex("<([^>]*)>").Replace(str, keep ? "$1" : ""); - } + public static string ReplaceOptional(string str, bool keep) + { + return new Regex("<([^>]*)>").Replace(str, keep ? "$1" : ""); + } + /// + /// Replaces or removes [triggerText: ...] tokens in the dialogue string. + /// + /// The original dialogue string. + /// The key-triggerText that causes that token to be replaced or not. + /// If true, replace with the inner text; if false, remove the token. + /// The processed dialogue string. + public static string ReplaceConditionalOptional(string str, string key, bool keep) + { + if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(key)) + return str; - public static string ReplaceOr(string str, bool first, string splitChar = "/") - { - return new Regex("<([^>" + splitChar + "]*)" + splitChar + "([^>]*)>").Replace(str, first ? "$1" : "$2"); - } + // Escape the triggerKey to handle any special regex characters + string escapedKey = Regex.Escape(key); - public static List ValidUnderwearTypes() - { - List list = Regression.t.Underwear_Options.Keys.ToList(); - list.Remove("blue jeans"); - list.Remove("bed"); - return list; + string pattern = $@"\[{escapedKey}:\s*(.*?)\]"; + + Regex triggerTextRegex = new Regex(pattern, RegexOptions.Compiled); + return triggerTextRegex.Replace(str, keep ? " $1" : ""); + } + public static string ReplaceOr(string str, bool first, string splitChar = "/") + { + return new Regex("<([^>" + splitChar + "]*)" + splitChar + "([^>]*)>").Replace(str, first ? "$1" : "$2"); + } + + public static List ValidUnderwearTypes() + { + List list = Regression.t.Underwear_Options.Keys.ToList(); + list.Remove("legs"); + list.Remove("blue jeans"); + list.Remove("bed"); + return list; + } } - } } diff --git a/Regression/PrimevalTitmouse/Underwear.cs b/Regression/PrimevalTitmouse/Underwear.cs index 9b31952..34aadcd 100644 --- a/Regression/PrimevalTitmouse/Underwear.cs +++ b/Regression/PrimevalTitmouse/Underwear.cs @@ -1,29 +1,69 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using Netcode; using StardewValley; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Security.AccessControl; using System.Xml.Serialization; +using static PrimevalTitmouse.Container; namespace PrimevalTitmouse { public class Underwear : StardewValley.Object { - public static Color color; - public Container container; - public string id; - public Underwear() { //base.Actor(); } - public Underwear(string type, float wetness = 0.0f, float messiness = 0.0f, int count = 1) + public Underwear(string typeName, int count) { //base.Actor(); - this.Initialize(type, wetness, messiness, count); + this.Initialize(Container.GetTypeDefault(typeName), count); + } + public Underwear(Container baseType, int count) + { + //base.Actor(); + this.Initialize(baseType,count); + } + public static readonly string modDataKey = "PrimevalTitmouse/Underwear"; + + public Color color { + get { + string colorStr; + modData.TryGetValue("${modDataKey}/color", out colorStr); + if (!string.IsNullOrEmpty(colorStr)) + { + uint colorValue = uint.Parse(colorStr); + return new Color( + ((colorValue >> 24) & 0xFF) / 255f, + ((colorValue >> 16) & 0xFF) / 255f, + ((colorValue >> 8) & 0xFF) / 255f, + (colorValue & 0xFF) / 255f + ); + } + return new Color(); + } + set { + string colorStr = ((uint)(value.R * 255) << 24 | + (uint)(value.G * 255) << 16 | + (uint)(value.B * 255) << 8 | + (uint)(value.A * 255)).ToString(); + modData.Add("${modDataKey}/color", colorStr); + } + } + private Container _container; + public Container container { + get { + if (_container == null) + { + _container = new Container(this, "dinosaur undies"); + } + return _container; + } } public override bool canBeDropped() @@ -38,6 +78,7 @@ public override bool canBeGivenAsGift() public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, StackDrawType drawStackNumber, Color color, bool drawShadow) { + if (Animations.sprites == null) return; int ratio = Animations.LARGE_SPRITE_DIM / Animations.SMALL_SPRITE_DIM; Vector2 offset = new(Game1.tileSize/2, Game1.tileSize/2); //Center of tile Vector2 origin = new(Animations.LARGE_SPRITE_DIM/2, Animations.LARGE_SPRITE_DIM/2); //Center of Sprite @@ -59,24 +100,28 @@ public Dictionary getAdditionalSaveData() return new Dictionary() { { - "type", - container.name + "type", + container.name + }, + { + "wetness", + string.Format("{0}", container.wetness) }, { - "wetness", - string.Format("{0}", container.wetness) + "messiness", + string.Format("{0}", container.messiness) }, { - "messiness", - string.Format("{0}", container.messiness) + "durability", + string.Format("{0}", container.durability) }, { - "stack", - string.Format("{0}", Stack) + "stack", + string.Format("{0}", Stack) }, { - "dryingTime", - container.serializeDryingDate() + "dryingTime", + Container.serializeDryingDate(container.timeWhenDoneDrying) } }; } @@ -89,47 +134,51 @@ public override string getDescription() protected override Item GetOneNew() { - return new Underwear(this.name, this.container.wetness, this.container.messiness, 1); + //return new Underwear(this.name, this.container.wetness, this.container.messiness, -100, 1); + return new Underwear(this.container, 1); } public StardewValley.Object getReplacement() { - return new StardewValley.Object("685", 1, false, -1, 0); + var saveObj = new StardewValley.Object("685", Stack, false, -1, 0); + saveObj.modData.CopyFrom(this.modData); + return saveObj; } - public void Initialize(string type, float wetness, float messiness, int count = 1) + public void Initialize(Container baseType, int count) { - this.container = new Container(type); - this.container.wetness = wetness; - this.container.messiness = messiness; + //this.container = new Container(type); + this._container = null; + this.container.ResetToDefault(baseType); if (count > 1) Stack = count; - id = type; name = container.name; - Price = this.container.price; + Price = container.price; } - public override int maximumStackSize() { - if (container.messiness > 0.0 || container.wetness > 0.0 || container.IsDrying()) + if (!container.stackable) return 1; return base.maximumStackSize(); } public void rebuild(Dictionary data, object replacement) { - Initialize(data["type"], float.Parse(data["wetness"]), float.Parse(data["messiness"]), int.Parse(data["stack"])); + var container = new Container(); + + container.ResetToDefault(data["type"], float.Parse(data["wetness"]), float.Parse(data["messiness"]), data.ContainsKey("durability") ? int.Parse(data["durability"]) : -100); if (data.ContainsKey("dryingTime")) { - this.container.parseDryingDate(data["dryingTime"]); + container.timeWhenDoneDrying = Container.parseDryingDate(data["dryingTime"]); } + Initialize(container, int.Parse(data["stack"])); } public override string DisplayName { get { - return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Status + id); + return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Status + container.displayName); } } @@ -137,7 +186,7 @@ public override string Name { get { - return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Status + id); + return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Status + container.name); } } @@ -151,10 +200,11 @@ public string Status return "messy "; if (container.wetness > 0.0) return "wet "; - return container.IsDrying() ? "drying " : ""; + return container.drying ? "drying " : ""; } } + public static bool getPantsPlural(int itemNum) { //This was built based on the game's ClothingInformation.json file diff --git a/Regression/Regression Dialogue/Content.json b/Regression/Regression Dialogue/Content.json index 08311c5..d9257a2 100644 --- a/Regression/Regression Dialogue/Content.json +++ b/Regression/Regression Dialogue/Content.json @@ -1,40 +1,53 @@ { - "Format": "2.0.0", - "Changes": [ - { - "LogName": "Sebastian", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Sebastian.json" - }, - { - "LogName": "Jodi", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Jodi.json" - }, - { - "LogName": "Gus", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Gus.json" - }, - { - "LogName": "Sam", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Sam.json" - }, - { - "LogName": "Penny", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Penny.json" - }, - { - "LogName": "Vincent", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Vincent.json" - }, - { - "LogName": "Jas", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Jas.json" - }, - ] + "Format": "2.0.0", + "Changes": [ + { + "LogName": "Sebastian", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Sebastian.json" + }, + { + "LogName": "Jodi", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Jodi.json", + "Conditions": { + "HasMod": "Pathoschild.ContentPatcher" + } + }, + { + "LogName": "Gus", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Gus.json" + }, + { + "LogName": "Sam", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Sam.json" + }, + { + "LogName": "Penny", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Penny.json" + }, + { + "LogName": "Vincent", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Vincent.json" + }, + { + "LogName": "Jas", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Jas.json" + }, + { + "LogName": "Maru", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Maru.json" + }, + { + "LogName": "Abigail", + "Action": "Include", + "FromFile": "Dialogue/NPCs/Abigail.json" + } + ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json b/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json new file mode 100644 index 0000000..1781f58 --- /dev/null +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json @@ -0,0 +1,16 @@ +{ + "Changes":[ + { + "LogName": "Abigail", + "Action": "EditData", + "Target": "Characters/Dialogue/Abigail", + "Entries": { + + + "Diaper_Change_Accept": "#Just lie down for me!$l#$b#%Abigail changes your diaper, using way to much baby powder#$action DIAPER_CHANGE \"joja diaper\" \"stinky pants\"#$h", + "Diaper_Change_Refuse": "I was just asking.", + "Diaper_Change_Followup": "..." + } + } + ] +} \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Gus.json b/Regression/Regression Dialogue/Dialogue/NPCs/Gus.json index 5350f08..ea9ac87 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Gus.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Gus.json @@ -11,9 +11,9 @@ "Saloon8": "Must be nice to just go wherever… I’m holding a big one in, now, honestly.#$b#I can't just step away when the saloon is packed!$1", "Mon2": "Yeah, I know a lot about the people living here.#$e#That's one of the benefits of being a bartender.$h#$e#Sometimes I hear too much...#$b#%Gus winks and glances down at your pants.", -"Sat4": "Are you much of a chef, @?#$e#If you have a kitchen and some recipes, you can cook some useful dishes.#$e#Though it's easier picturing you getting fed than doing the cooking!$1", +"Sat4": "Are you much of a chef, @?#$e#If you have a kitchen and some recipes, you can cook some useful dishes.#$e#Though it's easier picturing you getting fed than doing the cooking!$1" - }, - }, + } + } ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json b/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json index 33ad327..701f041 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json @@ -1,83 +1,86 @@ { - "Changes":[ - { - "LogName":"Jas", - "Action":"EditData", - "Target":"Characters/Dialogue/Jas", - "Entries":{ + "Changes": [ + { + "LogName": "Jas", + "Action": "EditData", + "Target": "Characters/Dialogue/Jas", + "Entries": { - "Introduction": "...$u#$b#Hi...$u - #$q 101/102 ABDLChild_fallback#%Would you be comfortable seeing ABDL dialogue from Vincent and Jas? - #$r 101 0 ABDLChild_Yes#Yes, I am comfortable with that. - #$r 102 0 ABDLChild_No#No, I would like to see the original dialogue.", - //----------------- - "ABDLChild_Yes":"%The more hearts you have with them the more ABDL dialogue there will be.", - "ABDLChild_No":"%Okay. All the original lines will be unchanged, and they also won't notice you using your pants.", - "ABDLChild_fallback":"#$p 102#...$u|%The waistband of Jas's pull up faintly peeks out.", - //The question above happens durring the introduction of Vincent or Jas, whomever the player interacts with first. They'll get to choose whether or not they want ABDL dialogue for the two of them. - //Unfortunately, this only works for new farms, not if a player installs the mod and loads an old save where they've already met both Vincent and Jas. Then it defaults to the ABDL text. + "Introduction": "...$u#$b#Hi...$u #$q 101/102 ABDLChild_fallback#%Would you be comfortable seeing diaper related dialogue from Vincent and Jas? #$r 101 0 ABDLChild_Yes#Yes, I am comfortable with that. #$r 102 0 ABDLChild_No#No, I would like to see the original dialogue.", + //----------------- + "ABDLChild_Yes": "%The more hearts you have with them the more ABDL dialogue there will be.", + "ABDLChild_No": "%Okay. All the original lines will be unchanged.", + "ABDLChild_fallback": "#$p 102#...$u|%The waistband of Jas's pull up faintly peeks out.", + //The question above happens durring the introduction of Vincent or Jas, whomever the player interacts with first. They'll get to choose whether or not they want ABDL dialogue for the two of them. + //Unfortunately, this only works for new farms, not if a player installs the mod and loads an old save where they've already met both Vincent and Jas. Then it defaults to the ABDL text. -"spring_Mon":"#$p 102#Oh...Are you looking for Aunt Marnie?$u|%You notice Jas doing a potty dance before she catches you watching.#$b#%She freezes in place and blushes hard. You can hear a soft hiss.#$e#U-hmmm...$2", -"spring_Mon8":"#$p 102#It's fun to live on a farm.$h|%You notice Jas doing a potty dance before she catches you watching. She stops to smile and wave at you.#$b#%Her eyes suddenly widen and a blush spreads across her cheeks as you hear a soft hiss, but she doesn't seem too concerned.#$e#Hi @!", -"spring_Tue6":"#$p 102#You can play with my dolls if you want to. Just make sure to brush their hair when you're done.|Hi @. Can I show you something?#$b#%Jas holds up a well loved lamb plushie she was playing with.#$b#This is Bethany. She's my favorite!", -"spring_Wed2":"#$p 102#...Hi.$u|Vincent doesn't try to use the potty like I do.$3#$b#He's gross.", -"spring_Wed6":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.$3#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.", -"spring_Wed10":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.$3#$b#It's not very fun. I wish I wasn't supposed to...$2", -"spring_Thu":"#$p 102#I'm not supposed to talk to strangers...$u|%Jas is quietly sucking her thumb until she notices you nearby. She quickly puts her hands at her side and blushes.#$e#…$2", -"spring_Thu4":"#$p 102#Miss Penny is teaching me how to write in cursive.|%Jas is quietly sucking her thumb. She smiles when she notices you nearby and waves with her freehand.", -"spring_Fri2":"#$p 102#|Do you like my bow? It would probably look cute on you too!", -"spring_Sat8":"#$p 102#|I had an accident at the library yesterday...$3#$b#I told Miss Penny it was Vincent though, so I got away with it.$1#$e#I'm very clever.$4", -"spring_Sun6":"#$p 102#|Shane's gone a lot, and Aunt Marnie is busy all the time... so I'm thankful for all my toys.$h#$e#Do you want to play with me? We could play house!", -"spring_12_1": "The egg festival is tomorrow!$1#$e#I don't want to win the egg hunt, I only want to get some chocolate.", -"spring_12_2": "The egg festival is tomorrow!$1#$e#I don't want to win the egg hunt, I only want to get some chocolate.", + "spring_Mon": "#$p 102#Oh...Are you looking for Aunt Marnie?$u|%You notice Jas doing a potty dance before she catches you watching.#$b#%She freezes in place and blushes hard. You can hear a soft hiss.#$b#U-hmmm...$2#$b#$action DIAPER_ACCIDENT pee jas", + "spring_Mon8": "#$p 102#It's fun to live on a farm.$h|%You notice Jas doing a potty dance before she catches you watching. She stops to smile and wave at you.#$b#%Her eyes suddenly widen and a blush spreads across her cheeks as you hear a soft hiss, but she doesn't seem too concerned.#$action DIAPER_ACCIDENT pee jas", + "spring_Tue6": "#$p 102#You can play with my dolls if you want to. Just make sure to brush their hair when you're done.|Hi @. Can I show you something?#$b#%Jas holds up a well loved lamb plushie she was playing with.#$b#This is Bethany. She's my favorite!", + "spring_Wed2": "#$p 102#...Hi.$u|Vincent doesn't try to use the potty like I do.$3#$b#He's gross.", + "spring_Wed6": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.$3#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.", + "spring_Wed10": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.$3#$b#It's not very fun. I wish I wasn't supposed to...$2", + "spring_Thu": "#$p 102#I'm not supposed to talk to strangers...$u|%Jas is quietly sucking her thumb until she notices you nearby. She quickly puts her hands at her side and blushes.#$e#…$2", + "spring_Thu4": "#$p 102#Miss Penny is teaching me how to write in cursive.|%Jas is quietly sucking her thumb. She smiles when she notices you nearby and waves with her freehand.", + "spring_Fri2": "#$p 102#|Do you like my bow? It would probably look cute on you too!", + "spring_Sat8": "#$p 102#|I had an accident at the library yesterday...$3#$b#I told Miss Penny it was Vincent though, so I got away with it.$1#$e#I'm very clever.$4", + "spring_Sun6": "#$p 102#|Shane's gone a lot, and Aunt Marnie is busy all the time... so I'm thankful for all my toys.$h#$e#Do you want to play with me? We could play house!", + "spring_12_1": "The egg festival is tomorrow!$1#$b#I don't want to win the egg hunt, I only want to get some chocolate. All the chocolate!$1", + "spring_12_2": "The egg festival is tomorrow!$1#$b#I don't want to win the egg hunt, I only want to get some chocolate. All the chocolate!$1", -"summer_Mon8":"#$p 102#It's fun to live on a farm.$h|I'm a big girl, see!$1#$b#%Jas lifts her skirt up high to show off her pull ups. She seems very proud.#$e#Told you.$4", -"summer_Wed4":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Aunt Marnie says I'm a big girl even if I have accidents sometimes.", -"summer_Wed8":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|I'm a big girl and big girls use the potty when they have to go.#$b#It's really hard though, and I still have accidents...$2#$e#Vincent doesn't have to worry about the potty...$3", -"summer_Thu6":"#$p 102#Miss Penny is teaching me how to write in cursive.|Yesterday, Miss Penny walked away to talk to Mr. Gunther and then Vincent pooped his diaper on purpose!#$b#He told me I should do it too, but I didn't because I'm a big girl and I only get poopy on accident now.$4", -"summer_Fri2":"#$p 102#|Uhm... @? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still.#$e#Uhm... N-never mind...$2", -"summer_Fri6":"#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still. After a bit she sighs and smiles up at you.#$e#Never mind, I don't have to go anymore.", -"summer_Fri10":"#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes as her knees seem to bend on their own. After a bit she sighs and smiles up at you.#$e#Never mind, I don't have to go anymore.#$e#%Jas doesn't seem to mind the smell coming from her pull ups.", -"summer_Sat4":"#$p 102#|I didn't make it to the potty yesterday and Aunt Marnie said that pull ups are only for girls who are trying to use the potty.$3#$e#I'm going try real hard today because I am a big girl!", -"summer_Sun6":"#$p 102#|Can you keep a secret? Sometimes I go potty in my pull up on purpose when I'm playing.#$b#It's more fun than having to stop playing!$1", -"summer_Sun10":"#$p 102#|Can you keep a secret?#$b#%Jas glances around before grunting softly, pushing a mess into her pull ups. She looks up at you with a relieved smile and a deep blush.#$b#Oops!$1", -"summer_3_1":"It's my birthday tomorrow! Aunt Marnie always gets me pink cake. It's my favorite!$1", -"summer_3_2":"It's my birthday tomorrow! Aunt Marnie always gets me pink cake. It's my favorite!$1", + "summer_Mon8": "#$p 102#It's fun to live on a farm.$h|I'm a big girl, see!$1#$b#%Jas lifts her skirt up high to show off her pull ups. She seems very proud.#$e#Told you.$4", + "summer_Wed4": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Aunt Marnie says I'm a big girl even if I have accidents sometimes.", + "summer_Wed8": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|I'm a big girl and big girls use the potty when they have to go.#$b#It's really hard though, and I still have accidents...$2#$e#Vincent doesn't have to worry about the potty...$3", + "summer_Thu6": "#$p 102#Miss Penny is teaching me how to write in cursive.|Yesterday, Miss Penny walked away to talk to Mr. Gunther and then Vincent pooped his diaper on purpose!#$b#He told me I should do it too, but I didn't because I'm a big girl and I only get poopy on accident now.$4", + "summer_Fri2": "#$p 102#|Uhm... @? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still.#$b#N-never mind...$2#$b#$action DIAPER_ACCIDENT pee jas", + "summer_Fri6": "#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still. After a bit she sighs and smiles up at you.#$b#Never mind, I don't have to go anymore.#$action DIAPER_ACCIDENT pee jas", + "summer_Fri10": "#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes as her knees seem to bend on their own. After a bit she sighs and smiles up at you.#$b#Never mind, I don't have to go anymore.#$b#%Jas doesn't seem to mind the smell coming from her pull ups.#$b#$action DIAPER_ACCIDENT poop jas", + "summer_Sat4": "#$p 102#|I didn't make it to the potty yesterday and Aunt Marnie said that pull ups are only for girls who are trying to use the potty.$3#$e#I'm going try real hard today because I am a big girl!", + "summer_Sun6": "#$p 102#|Can you keep a secret? Sometimes I go potty in my pull up on purpose when I'm playing.#$b#It's more fun than having to stop playing!$1", + "summer_Sun10": "#$p 102#|Can you keep a secret?#$b#%Jas glances around before grunting softly, pushing a mess into her pull ups. She looks up at you with a relieved smile and a deep blush.#$b#Oops!$1#$action DIAPER_ACCIDENT poop jas", + "summer_3_1": "It's my birthday tomorrow! Aunt Marnie always gets me pink cake. It's my favorite!$1", + "summer_3_2": "It's my birthday tomorrow! Aunt Marnie always gets me pink cake. It's my favorite!$1", -"fall_Mon":"#$p 102#Oh...Are you looking for Aunt Marnie?$u|%You notice Jas doing a potty dance before she catches you watching.#$b#%She freezes in place and blushes hard. You can hear a soft hiss.#$e#U-hmmm...$2", -"fall_Mon8":"#$p 102#It's fun to live on a farm.$h|%You notice Jas doing a potty dance before she catches you watching. She stops to smile and wave at you.#$b#%Her eyes suddenly widen and a blush spreads across her cheeks as you hear a soft hiss, but she doesn't seem too concerned.#$e#Hi @!", -"fall_Tue6":"#$p 102#You can play with my dolls if you want to. Just make sure to brush their hair when you're done.|Hi @. Can I show you something?#$b#%Jas holds up a well loved lamb plushie she was playing with.#$b#This is Bethany. She's my favorite!", -"fall_Wed2":"#$p 102#...Hi.$u|Vincent doesn't try to use the potty like I do.$3#$b#He's gross.", -"fall_Wed6":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.$3#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.", -"fall_Wed10":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.$3#$b#It's not very fun. I wish I wasn't supposed to...$2", -"fall_Thu":"#$p 102#I'm not supposed to talk to strangers...$u|%Jas is quietly sucking her thumb until she notices you nearby. She quickly puts her hands at her side and blushes.#$e#…$2", -"fall_Thu4":"#$p 102#Miss Penny is teaching me how to write in cursive.|%Jas is quietly sucking her thumb. She smiles when she notices you nearby and waves with her freehand.", -"fall_Fri2":"#$p 102#|Do you like my bow? It would probably look cute on you too!", -"fall_Sat8":"#$p 102#|I had an accident at the library yesterday...$3#$b#I told Miss Penny it was Vincent though, so I got away with it.$1#$e#I'm very clever.$4", -"fall_Sun6":"#$p 102#|Shane's gone a lot, and Aunt Marnie is busy all the time... so I'm thankful for all my toys.$h#$e#Do you want to play with me? We could play house!", -"fall_15_1":"I'm excited for the fair tomorrow. Last year Shane won me a whole bunch of toys!", -"fall_15_2":"I'm excited for the fair tomorrow. Last year Shane won me a whole bunch of toys!", -"fall_26_1":"I'm going to do the whole maze tomorrow and I'm going going to be scared once!", -"fall_26_2":"I'm going to do the whole maze tomorrow and I'm going going to be scared once!", + "fall_Mon": "#$p 102#Oh...Are you looking for Aunt Marnie?$u|%You notice Jas doing a potty dance before she catches you watching.#$b#%She freezes in place and blushes hard. You can hear a soft hiss.#$b#U-hmmm...$2#$action DIAPER_ACCIDENT pee jas", + "fall_Mon8": "#$p 102#It's fun to live on a farm.$h|%You notice Jas doing a potty dance before she catches you watching. She stops to smile and wave at you.#$b#%Her eyes suddenly widen and a blush spreads across her cheeks as you hear a soft hiss, but she doesn't seem too concerned.#$action DIAPER_ACCIDENT pee jas", + "fall_Tue6": "#$p 102#You can play with my dolls if you want to. Just make sure to brush their hair when you're done.|Hi @. Can I show you something?#$b#%Jas holds up a well loved lamb plushie she was playing with.#$b#This is Bethany. She's my favorite!", + "fall_Wed2": "#$p 102#...Hi.$u|Vincent doesn't try to use the potty like I do.$3#$b#He's gross.", + "fall_Wed6": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.$3#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.", + "fall_Wed10": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Vincent told me he likes using his diapers.#$e#I do too, but I'm a big girl, so I'm trying to use the potty like I'm supposed to.$3#$b#It's not very fun. I wish I wasn't supposed to...$2", + "fall_Thu": "#$p 102#I'm not supposed to talk to strangers...$u|%Jas is quietly sucking her thumb until she notices you nearby. She quickly puts her hands at her side and blushes.#$b#…$2", + "fall_Thu4": "#$p 102#Miss Penny is teaching me how to write in cursive.|%Jas is quietly sucking her thumb. She smiles when she notices you nearby and waves with her free hand.", + "fall_Fri2": "#$p 102#|Do you like my bow? It would probably look cute on you too!", + "fall_Sat8": "#$p 102#|Vincent had accident at the library yesterday...$1#$b#I told Miss Penny that he pooped himself, but she checked me instead$3#$b#Then i got changed! That was not fair!$2", + "fall_Sun6": "#$p 102#|Shane's gone a lot, and Aunt Marnie is busy all the time... so I'm thankful for all my toys.$h#$e#Do you want to play with me? We could play house!", + "fall_15_1": "I'm excited for the fair tomorrow. Last year Shane won me a whole bunch of toys!", + "fall_15_2": "I'm excited for the fair tomorrow. Last year Shane won me a whole bunch of toys!", + "fall_26_1": "I'm going to do the whole maze tomorrow and I'm going going to be scared once!$3", + "fall_26_2": "I'm going to do the whole maze tomorrow and I'm going going to be scared once!$3", -"winter_Mon8":"#$p 102#It's fun to live on a farm.$h|I'm a big girl, see!$1#$b#%Jas lifts her skirt up high to show off her pull ups. She seems very proud.#$e#Told you.$4", -"winter_Wed4":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Aunt Marnie says I'm a big girl even if I have accidents sometimes.", -"winter_Wed8":"#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|I'm a big girl and big girls use the potty when they have to go.#$b#It's really hard though, and I still have accidents...$2#$e#Vincent doesn't have to worry about the potty...$3", -"winter_Thu6":"#$p 102#Miss Penny is teaching me how to write in cursive.|Yesterday, Miss Penny walked away to talk to Mr. Gunther and then Vincent pooped his diaper on purpose!#$b#He told me I should do it too, but I didn't because I'm a big girl and I only get poopy on accident now.$4", -"winter_Fri2":"#$p 102#|Uhm... @? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still.#$e#Uhm... N-never mind...$2", -"winter_Fri6":"#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still. After a bit she sighs and smiles up at you.#$e#Never mind, I don't have to go anymore.", -"winter_Fri10":"#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes as her knees seem to bend on their own. After a bit she sighs and smiles up at you.#$e#Never mind, I don't have to go anymore.#$e#%Jas doesn't seem to mind the smell coming from her pull ups.", -"winter_Sat4":"#$p 102#|I didn't make it to the potty yesterday and Aunt Marnie said that pull ups are only for girls who are trying to use the potty.$3#$e#I'm going try real hard today because I am a big girl!", -"winter_Sun6":"#$p 102#|Can you keep a secret? Sometimes I go potty in my pull up on purpose when I'm playing.#$b#It's more fun than having to stop playing!$1", -"winter_Sun10":"#$p 102#|Can you keep a secret?#$b#%Jas glances around before grunting softly, pushing a mess into her pull ups. She looks up at you with a relieved smile and a deep blush.#$b#Oops!$1", -"winter_22_1":"I finally got the perfect gift for my secret friend. I want to tell them what I got so bad!$1#$b#But then it wouldn't be a secret.$4", -"winter_22_2":"I finally got the perfect gift for my secret friend. I want to tell them what I got so bad!$1#$b#But then it wouldn't be a secret.$4", - - }, - }, - ] + "winter_Mon8": "#$p 102#It's fun to live on a farm.$h|I'm a big girl, see!$1#$b#%Jas lifts her skirt up high to show off her pull ups. She seems very proud.#$e#Told you.$4", + "winter_Wed4": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|Aunt Marnie says I'm a big girl even if I have accidents sometimes.", + "winter_Wed8": "#$p 102#Aunt Marnie won't let me go out after 6 o'clock. It's not fair!$s|I'm a big girl and big girls use the potty when they have to go.#$b#It's really hard though, and I still have accidents...$2#$e#Vincent doesn't have to worry about the potty...$3", + "winter_Thu6": "#$p 102#Miss Penny is teaching me how to write in cursive.|Yesterday, Miss Penny walked away to talk to Mr. Gunther and then Vincent pooped his diaper on purpose!#$b#He told me I should do it too, but I didn't because I'm a big girl and I only get poopy on accident now.$4", + "winter_Fri2": "#$p 102#|Uhm... @? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still.#$b#Uhm... N-ever mind...$2#$action DIAPER_ACCIDENT pee jas", + "winter_Fri6": "#$p 102#|@? Do you know where Aunt Marn...!$3#$b#%Jas blushes while suddenly holding very still. After a bit she sighs and smiles up at you.#$e#Never mind, I don't have to go anymore.", + "winter_Fri10": "#$p 102#|@? Do you know where Aunt Marn is, i need to...$3#$b#%Jas blushes as her knees seem to bend on their own. After a bit she sighs and smiles up at you.#$b#Aww...#$b#%Jas seams to be disappointed that she couldn't make it. Maybe next time.#$action DIAPER_ACCIDENT poop jas", + "winter_Sat4": "#$p 102#|I didn't make it to the potty yesterday and Aunt Marnie said that pull ups are only for girls who are trying to use the potty.$3#$e#I'm going try real hard today because I am a big girl!", + "winter_Sun6": "#$p 102#|I like winter! You can play in the snow and build snow men, but its really cold sometimes.#$b#But if you go in your pants, it gets warm again!$4#$b#But Aunt Marnie doesn't like that. Says i have to try better to be a big girl!$3", + "winter_Sun10": "#$p 102#|Can you keep a secret?#$b#%Jas glances around before grunting softly, pushing a mess into her pull ups. She looks up at you with a relieved smile and a deep blush.#$b#Oops!$1#$action DIAPER_ACCIDENT poop jas", + "winter_22_1": "I finally got the perfect gift for my secret friend. I want to tell them what I got so bad!$1#$b#But then it wouldn't be a secret.$4", + "winter_22_2": "I finally got the perfect gift for my secret friend. I want to tell them what I got so bad!$1#$b#But then it wouldn't be a secret.$4", + "Change_Diaper_Accept_BabyPrint": "*You kneel down and show jas a baby print diaper* Nooo! I am a big girl! I can make it to the potty... sometimes! *She looks upset, but she does need a change*$3#$b#%You change jas into a fresh baby print diaper while she quengels a little.#$b#...$3#$b#want pull ups$2#$b#...$3#$action CHANGE_DIAPER_OTHERS \"jas\" \"baby print diaper\"#$b#%Jas seams a little unhappy, but well protected again.", + "Change_Diaper_Accept_Training": "*You kneel down and show jas a pair of training pants.* Pullups!$1#$b#%You change jas into a pair of training pants.$3#$b#Don't tell Aunt Marn. She says i have to make it to the potty if i want to keep my pull ups.$3#$action CHANGE_DIAPER_OTHERS \"jas\" \"training pants\"#$b#%Jas seams happy. She probably will not make it to the potty, but it should be all right.", + "Change_Diaper_Accept_Lavender": "*You show jas a pair of lavender pullups. She first looks puzzled, but then recognizes them* Uh, thats the ones Aunty says are to expensiv!$0#$b#%Without much struggle you get her changed in a fresh a pair of lavender pullups.$3#$b#Yey! They cosy and look super cute!$4#$action CHANGE_DIAPER_OTHERS \"jas\" \"lavender pullups\"#$b#%Jas will probably not keep them clean for long, but she looks happy.", + "Change_Diaper_Accept_BigKids": "Oh! Undies for super big kids! Aunty Marn says i get them if i can keep my pull ups clean, but i totally can do that now!$1#$b#%You change jas into a pair of big kid undies.#$b#Have to tell vincent! He will be sooo jelous! *She looks exited*$1#$action CHANGE_DIAPER_OTHERS \"jas\" \"big kid undies\"#$b#%Marnie will be upset as soon as jas will turn up in filthy cloth. Something that is probably going to happen very soon...", + "Change_Diaper_Accept_Dinos": "Mmm, they dinos! I think they for boys. *Jas looks a little upset about the design*$2#$b#%You still change jas into a pair of padded dinosaur undies.#$b#I am a girl!$2#$b#%Jas looks a really upset, but at least she is dry again#$action CHANGE_DIAPER_OTHERS \"jas\" \"dinosaur undies\"#$b#%You question if the amount of protection is enough, while jas walks off like having frogs in her underwear.", + "Change_Diaper_Refuse": "It's ok, i'm a big girl now!$4#$b#%[NpcOnSlightlyWet: Jas probably isn't, but for now she doesn't really need a chance... yet.][NpcOnUsedBad: Looking Jas waddle away in her loaded pants, you feel much less certain about that than she is.]", + "Change_Diaper_Followup": "..." + }, + }, + ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json index 56ccc89..a232732 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json @@ -1,67 +1,64 @@ { - "Changes":[ - { - "LogName":"Jodi", - "Action":"EditData", - "Target":"Characters/Dialogue/Jodi", - "Entries":{ -//Jodi's response Ids are 110-119 - "Introduction": "Oh! Is this @? I'm Jodi.#$e#Did you get my little care package? I hope it's enough to get you started.#$e#Oh don't look so embarrassed, that old farm is very exciting! I wouldn't want our new little farmer caught unprepared when he gets a little distracted.$1^Oh don't look so embarrassed, a new farm is very exciting! I wouldn't want our new little farmer caught unprepared when she gets a little distracted.", + "Changes": [ + { + "LogName": "Jodi", + "Action": "EditData", + "Target": "Characters/Dialogue/Jodi", + "Entries": { + //Jodi's response Ids are 110-119 + "Introduction": "Oh! Is this @? I'm Jodi.#$e#Did you get my little care package? I hope it's enough to get you started.#$e#Oh don't look so embarrassed, that old farm is very exciting! I wouldn't want our new little farmer caught unprepared when he gets a little distracted.$1^Oh don't look so embarrassed, a new farm is very exciting! I wouldn't want our new little farmer caught unprepared when she gets a little distracted.", - "spring_Mon":"There's the little farmer!#$e#How's the town treating you?", - "spring_Mon6":"There's the little farmer!#$b#%Jodi pulls the back your waist band for a quick check.#$e#You should be okay for now.", - "spring_Tue4":"#$c .5#Do you have any animals on your farm? Can you tell me what the cow says?#$e#That's right! Cow goes moo!$1|Do you have any animals on your farm? Can you tell me what the chicken says?#$e#That's right! Chicken goes cluck cluck!$1", - "spring_Wed2":"Would you like to tell me all about your farm?#$e#%Jodi smiles at you while you gush about how pretty your farm is.#$e#What a clever little boy you are.$1^What a clever little girl you are.$1", - "spring_Wed8":"Would you like to tell me all about your farm?#$e#%Jodi smiles at you while you gush about how pretty your farm is. You barely even notice her hand check to see if your pants are still dry.#$e#What a clever little boy you are.$1^What a clever little girl you are.$1", - "spring_Thu2":"Sam still sleeps with his old teddy bear, though, he tries to hide it in the morning.#$e#I don't know what to say to make him feel less embarrassed about it.$2", - "spring_Fri":"How are you doing @? Are you eating enough?#$e#...Do you have enough... supplies?", - "spring_Fri4":"How are you doing @? Are you eating enough?#$e#I bet you've already run out of the diapers I gave you by now.#$e#I sure hope your farm is making enough money to buy more!$1#$e#", - "spring_Sat4":"#$p 102#I'm so glad you're trying to improve that old farm.|Vincent fell asleep on my lap yesterday.#$e#It was so precious, I never wanted it to end!$1", - "spring_Sun6":"Being motherly makes me feel important.#$b#Even if the little ones aren't my own!$1#$e#%Jodi gives you a wink.", + "spring_Mon": "There's the little farmer!#$e#How's the town treating you?", + "spring_Mon6": "There's the little farmer!#$b#%Jodi pulls the back your waist band for a quick check.#$b#$query !DIAPER_USED# You should be okay for now.|$GETTING_CHANGED_DIALOG$", + "spring_Tue4": "#$c .5#Do you have any animals on your farm? Can you tell me what the cow says?#$b#That's right! Cow goes moo!$1|Do you have any animals on your farm? Can you tell me what the chicken says?#$b#That's right! Chicken goes cluck cluck!$1", + "spring_Wed2": "Would you like to tell me all about your farm?#$b#%Jodi smiles at you while you gush about how pretty your farm is.#$b#What a clever little boy you are.$1^What a clever little girl you are.$1", + "spring_Wed8": "Would you like to tell me all about your farm?#$b#%Jodi smiles at you while you gush about how pretty your farm is. You barely even notice her hand check to see if your pants are still dry.#$b#What a clever little ${boy^girl}$ you are.$1#$b#$query !DIAPER_USED# And still clean? How did that happen?|$GETTING_CHANGED_DIALOG$", + "spring_Thu2": "Sam still sleeps with his old teddy bear, though, he tries to hide it in the morning.#$b#I don't know what to say to make him feel less embarrassed about it.$2", + "spring_Fri": "How are you doing @? Are you eating enough?#$e#...Do you have enough... supplies?", + "spring_Fri4": "How are you doing @? Are you eating enough?#$e#I bet you've already run out of the diapers I gave you by now.#$e#I sure hope your farm is making enough money to buy more!$1#$e#", + "spring_Sat4": "#$p 102#I'm so glad you're trying to improve that old farm.|Vincent fell asleep on my lap yesterday.#$e#It was so precious, I never wanted it to end!$1", + "spring_Sun6": "Being motherly makes me feel important.#$b#Even if the little ones aren't my own!$1#$e#%Jodi gives you a wink.", - "summer_Mon6":"%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve and smile up at her.#$e#Awwwww.", - "summer_Mon10":"%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve as your thumb finds its way into your mouth without you noticing.#$e#Awwwww. Well aren't you a precious little boy.^Well aren't you a precious little girl.$1", - "summer_Tue6":"#$p 102#Sam tries really hard to act like a big kid, but he still melts when I pet his hair just like when he was a little boy.|Sometimes I catch Sam watching me change Vincent.#$e#He almost looks jealous.$1", -"summer_Wed8":"Oh hi there @!#$q 110/111 Show_Followup#Oh, do you want to show me something? -#$r 110 0 Show_Nice#Show her the pretty flower you picked. -#$r 110 0 Show_Nice#Show her the cool rock you found in the mines. -#$r 110 0 Show_Nice#Show her your favorite plushie. -#$r 111 0 Show_Diaper#Show her your diaper.", -"Show_Nice": "%Jodi holds it delicately, looking at it like it's the most important thing in the world.#$b#This is wonderful! Thank you for showing me.$1#$b#%Jodi gives it back and pats your head affectionately.", -"Show_Diaper": "%Jodi grins at your proud display.#$b#Well isn't that something!$1#$b#Let's see if it's still clean.#$b#%Jodi presses her hand against your diaper, giving it a thorough check.", -"Show_Followup":"#$p 110#Well don't you look excited! Did you find even more things to show me?$1|Well don't you look excited! Are you going to show off for me again?$1#$b#%You shamelessly show Jodi your diaper again and she pats it fondly.", - "summer_Thu4":"That farm seems like a lot of work for such a little farmer! I guess you're only pretending to be so little.#$e#%Jodi winks at you.", - "summer_Fri8":"#$p 102#Maintaining a household is difficult work... but somebody has to do it.|Vincent doesn't show any signs of getting out of diapers any time soon.#$e#I guess he'll just be my little boy for a little bit longer.$1", - "summer_Sat":"%Jodi is humming a soft song to herself while she goes about her business. It's familiar somehow.", - "summer_Sat10":"%Jodi is humming a soft song to herself while she goes about her business. It's familiar somehow.#$e#%She notices you paying attention and smiles. Without stopping her hum, she pulls you into a hug, letting you feel the comforting hum in her chest.#$e#Looks like someone might need a nap.", - "summer_Sun6":"Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you. She gives it a kiss for good measure.#$e#There we go, all better. Have fun playing!", - "summer_Sun10":"Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you.#$b#She gives it a kiss for good measure before patting your bottom to send you away.#$e#There we go, all better. Have fun playing!", + "summer_Mon6": "%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve and smile up at her.#$e#Awwwww.", + "summer_Mon10": "%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve as your thumb finds its way into your mouth without you noticing.#$e#Awwwww. Well aren't you a precious little boy.^Well aren't you a precious little girl.$1", + "summer_Tue6": "#$p 102#Sam tries really hard to act like a big kid, but he still melts when I pet his hair just like when he was a little boy.|Sometimes I catch Sam watching me change Vincent.#$e#He almost looks jealous.$1", + "summer_Wed8": "Oh hi there @!#$q 110/111 Show_Followup#Oh, do you want to show me something? #$r 110 0 Show_Nice#Show her the pretty flower you picked.#$r 110 0 Show_Nice#Show her the cool rock you found in the mines.#$r 110 0 Show_Nice#Show her your favorite plushie.#$r 111 0 Show_Diaper#Show her your diaper.", + "Show_Nice": "%Jodi holds it delicately, looking at it like it's the most important thing in the world.#$b#This is wonderful! Thank you for showing me.$1#$b#%Jodi gives it back and pats your head affectionately.", + "Show_Diaper": "%Jodi grins at your proud display.#$b#Well isn't that something!$1#$b#Let's see if it's still clean.#$b#%Jodi presses her hand against your diaper, giving it a thorough check.#$b#$query !DIAPER_USED# What a surprise! Well, lets see how long you can stay clean!|$GETTING_CHANGED_DIALOG$", + "Show_Followup": "#$p 110#Well don't you look excited! Did you find even more things to show me?$1|Well don't you look excited! Are you going to show off for me again?$1#$b#%You shamelessly show Jodi your diaper again and she pats it fondly.", + "summer_Thu4": "That farm seems like a lot of work for such a little farmer! I guess you're only pretending to be so little.#$e#%Jodi winks at you.", + "summer_Fri8": "#$p 102#Maintaining a household is difficult work... but somebody has to do it.|Vincent doesn't show any signs of getting out of diapers any time soon.#$e#I guess he'll just be my little boy for a little bit longer.$1", + "summer_Sat": "%Jodi is humming a soft song to herself while she goes about her business. It's familiar somehow.", + "summer_Sat10": "%Jodi is humming a soft song to herself while she goes about her business. It's familiar somehow.#$e#%She notices you paying attention and smiles. Without stopping her hum, she pulls you into a hug, letting you feel the comforting hum in her chest.#$e#Looks like someone might need a nap.", + "summer_Sun6": "Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you. She gives it a kiss for good measure.#$e#There we go, all better. Have fun playing!", + "summer_Sun10": "Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you.#$b#She gives it a kiss for good measure before patting your bottom to send you away.#$b#There we go, all better. Have fun playing!", - "fall_Mon2":"#$p 102#There's the little farmer!|Sam doesn't think I notice that Vincent's diapers run out faster than they should.#$e#I guess I still have two little boys, don't I!$1", - "fall_Tue4":"#$c .5#Do you have any animals on your farm? Can you tell me what the dog says?#$e#That's right! Dog says bark!$1|Do you have any animals on your farm? Can you tell me what the cat says?#$e#That's right! Cat says meow!$1", - "fall_Wed8":"If you ever need help with one of your little accidents, don't be afraid to ask, okay?#$e#You're so cute when you're blushing!$1", - "fall_Thu2":"Are you hungry?#$b#%Jodi pulls out a granola bar for you and smiles warmly as you take it.#$e#That should hold you over for now.", - "fall_Fri2":"#$p 102#I bet you've already run out of the diapers I gave you by now.|I guess I'd have less work to do if Vincent was potty trained.#$e#At least boys are easy to clean.", - "fall_Sat":"There's the little farmer!#$e#How's the town treating you?", - "fall_Sat8":"There's the little farmer!#$b#%Jodi pulls the back your waist band for a quick check.#$e#You should be okay for now.", - "fall_Sun6":"Being motherly makes me feel important.#$b#Even if the little ones aren't my own!$1#$e#%Jodi gives you a wink.", + "fall_Mon2": "#$p 102#There's the little farmer!|Sam doesn't think I notice that Vincent's diapers run out faster than they should.#$e#I guess I still have two little boys, don't I!$1", + "fall_Tue4": "#$c .5#Do you have any animals on your farm? Can you tell me what the dog says?#$e#That's right! Dog says bark!$1|Do you have any animals on your farm? Can you tell me what the cat says?#$e#That's right! Cat says meow!$1", + "fall_Wed8": "If you ever need help with one of your little accidents, don't be afraid to ask, okay?#$e#You're so cute when you're blushing!$1", + "fall_Thu2": "Are you hungry?#$b#%Jodi pulls out a granola bar for you and smiles warmly as you take it.#$e#That should hold you over for now.", + "fall_Fri2": "#$p 102#I bet you've already run out of the diapers I gave you by now.|I guess I'd have less work to do if Vincent was potty trained.#$b#At least boys are easy to clean.", + "fall_Sat": "There's the little farmer!#$e#How's the town treating you?", + "fall_Sat8": "How is potty training treating you?#$b#%Jodi pulls the back your waist band for a quick check.#$b#$query !DIAPER_USED# Getting better?|$GETTING_CHANGED_DIALOG$", + "fall_Sun6": "Being motherly makes me feel important.#$b#Even if the little ones aren't my own!$1#$e#%Jodi gives you a wink.", - "winter_Mon10":"%Jodi is humming a soft song to herself while she goes about her business. It's familiar somehow.#$e#%She notices you paying attention and smiles. Without stopping her hum, she pulls you into a hug, letting you feel the comforting hum in her chest.#$e#Looks like someone might need a nap.", - "winter_Tue10":"%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve as your thumb finds its way into your mouth without you noticing.#$e#Awwwww. Well aren't you a precious little boy.^Well aren't you a precious little girl.$1", - "winter_Wed6":"Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you. She gives it a kiss for good measure.#$e#There we go, all better. Have fun playing!", - "winter_Wed10":"Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you.#$b#She gives it a kiss for good measure before patting your bottom to send you away.#$e#There we go, all better. Have fun playing!", - "winter_Thu4":"Sam tries really hard to act like a big kid, but he still melts when I pet his hair just like when he was a little boy.#$e#It feels nice to know he trusts me enough to let his guard down.#$e#It makes me feel like a good mother.$1", - "winter_Fri2":"You're a good boy. You know that, right?^You're a good girl. You know that, right?", - "winter_Sat6":"Maybe I should push Vincent to use the potty more, but I don't want him to feel ashamed about himself.$2#$e#He just looks so carefree playing in his diapers too. I don't want to take that away from him.", - "winter_Sun6":"%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve and smile up at her.#$e#Awwwww.", - "winter_Sun10":"%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve as your thumb finds its way into your mouth without you noticing.#$e#Awwwww. Well aren't you a precious little boy.^Well aren't you a precious little girl.$1", - - - } - } - ] + "winter_Mon10": "%Jodi is humming a soft song to herself while she goes about her business. It's familiar somehow.#$e#%She notices you paying attention and smiles. Without stopping her hum, she pulls you into a hug, letting you feel the comforting hum in her chest.#$e#Looks like someone might need a nap.", + "winter_Tue10": "%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve as your thumb finds its way into your mouth without you noticing.#$e#Awwwww. Well aren't you a precious little ${boy^girl}$.$1", + "winter_Wed6": "Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you. She gives it a kiss for good measure.#$e#There we go, all better. Have fun playing!", + "winter_Wed10": "Oh no! @! Is that a boo boo on your finger? What happened?$2#$b#%You tell Jodi about hurting your finger on the farm with tears in your eyes while she puts on a bandaid for you.#$b#She gives it a kiss for good measure before patting your bottom to send you away.#$e#There we go, all better. Have fun playing!", + "winter_Thu4": "Sam tries really hard to act like a big kid, but he still melts when I pet his hair just like when he was a little boy.#$e#It feels nice to know he trusts me enough to let his guard down.#$e#It makes me feel like a good mother.$1", + "winter_Fri2": "You're a good ${boy^girl}$. You know that, right?", + "winter_Sat6": "Maybe I should push Vincent to use the potty more, but I don't want him to feel ashamed about himself.$2#$e#He just looks so carefree playing in his diapers too. I don't want to take that away from him.", + "winter_Sun6": "%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve and smile up at her.#$b#Awwwww.", + "winter_Sun10": "%Jodi sees you standing nearby and holds out her hand. You grab onto her sleeve as your thumb finds its way into your mouth without you noticing.#$e#Awwwww. Well aren't you a precious little ${boy^girl}$.$1", + "Diaper_Change_Accept": "Comeon, lets get you in a fresh diaper. Just a second... see it stretches! There! Right as rain!$l#$b#%Jodi changes you from $INSPECT_UNDERWEAR_NAME$ into one of Vincents baby print diapers[OnDebuffed: and some of Sams old pants]#$action DIAPER_CHANGE \"baby print diaper\" \"sams old pants\"#$h", + "Diaper_Change_Refuse": "Well, if you are like Vincent and want to stay in your filthy diapers, suit yourself! Just don't leak on the couch, you hear?", + "Diaper_Change_Followup": "..." + } + } + ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json b/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json new file mode 100644 index 0000000..49ab0ab --- /dev/null +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json @@ -0,0 +1,15 @@ +{ + "Changes":[ + { + "LogName":"Maru", + "Action":"EditData", + "Target":"Characters/Dialogue/Maru", + "Entries": { + "Diaper_Change_Accept": "%Maru changes you quick and professional#$action DIAPER_CHANGE \"joja diaper\"#$h", + "Diaper_Change_Refuse": "I am here if you change your mind.", + "Diaper_Change_Followup": "..." + + } + } + ] +} \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json b/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json index 3a95fc4..2e50e17 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json @@ -8,10 +8,10 @@ //Penny's response Ids are 130-139 -"spring_Mon8":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 +"spring_Mon6":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 #$q 134/135 Adult_Followup#I have a hard time thinking of you like you're an adult... -#$r 134 0 Adult_Little#Honestly, I don't really feel like one. -#$r 134 0 Adult_Little#Good! Cause I don't wanna be one. +#$r 134 10 Adult_Little#Honestly, I don't really feel like one. +#$r 134 10 Adult_Little#Good! Cause I don't wanna be one. #$r 135 0 Adult_Big#Not fair! I'm a big kid! ", "Adult_Little": "Well that's a relief! I was afraid I was reading too far into things.$1#$b#Though, your little potty problems are a dead give away, aren't they little one?$4", @@ -34,10 +34,10 @@ "Potty_Followup":"#$p 131#I'm sure you can handle it all on your own.|%Penny lowers her voice.#$b#Do you need to check in with your body and see if you need the potty @?$4", "spring_Sat6":"Oh hello @.#$q 132/133 Show_Followup#Oh, do you want to show me something? -#$r 132 0 Show_Nice#Show her the pretty flower you picked. -#$r 132 0 Show_Nice#Show her the cool rock you found in the mines. -#$r 132 0 Show_Nice#Show her your favorite plushie. -#$r 133 0 Show_Diaper#Show her your diaper.", +#$r 132 5 Show_Nice#Show her the pretty flower you picked. +#$r 132 5 Show_Nice#Show her the cool rock you found in the mines. +#$r 132 5 Show_Nice#Show her your favorite plushie. +#$r 133 5 Show_Diaper#Show her your diaper.", "Show_Nice": "Oh wow @, that is very lovely! Thank you for showing me.#$b#You look so pleased! You're just like a little kid at show and tell.$1", "Show_Diaper": "Oh goodness @. That doesn't look like you're trying very hard to make it to the potty.$3", "Show_Followup":"Well don't you look excited!$1#$e#%Penny pats your head fondly.", @@ -48,18 +48,18 @@ "summer_Tue6":"#$p 102#I'm tutoring Vincent and Jas today... They're a handful, but it's nice to make a difference in someone's life.|Jas is so proud of her pull ups. I'm really proud to have helped her get there.$1#$b#She's still not great at keeping them clean...$3", "summer_Wed6":"Oh hello @.#$q 132/133 Show_Followup#Oh, do you want to show me something? -#$r 132 0 Show_Nice#Show her the pretty flower you picked. -#$r 132 0 Show_Nice#Show her the cool rock you found in the mines. -#$r 132 0 Show_Nice#Show her your favorite plushie. -#$r 133 0 Show_Diaper#Show her your diaper.", +#$r 132 5 Show_Nice#Show her the pretty flower you picked. +#$r 132 5 Show_Nice#Show her the cool rock you found in the mines. +#$r 132 5 Show_Nice#Show her your favorite plushie. +#$r 133 5 Show_Diaper#Show her your diaper.", "Show_Nice": "Oh wow @, that is very lovely! Thank you for showing me.#$b#You look so pleased! You're just like a little kid at show and tell.$1", "Show_Diaper": "Oh goodness @. That doesn't look like you're trying very hard to make it to the potty.$3", "Show_Followup":"Well don't you look excited!$1#$e#%Penny pats your head fondly.", -"summer_Fri8":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 +"summer_Fri6":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 #$q 134/135 Adult_Followup#I have a hard time thinking of you like you're an adult... -#$r 134 0 Adult_Little#Honestly, I don't really feel like one. -#$r 134 0 Adult_Little#Good! Cause I don't wanna be one. +#$r 134 10 Adult_Little#Honestly, I don't really feel like one. +#$r 134 10 Adult_Little#Good! Cause I don't wanna be one. #$r 135 0 Adult_Big#Not fair! I'm a big kid! ", "Adult_Little": "Well that's a relief! I was afraid I was reading too far into things.$1#$b#Though, your little potty problems are a dead give away, aren't they little one?$4", @@ -84,18 +84,18 @@ "fall_Tue4":"Hello there @. You look happy today.#$b#$y 'Have you been doing better with your potty issues?_Yup! It's easy!_Good! I'm glad to hear it.$1_Not really. I still have accidents..._Oh @. It's okay, that's nothing to be ashamed of. Keep trying your hardest, you'll get it!'", "fall_Wed6":"Oh hello @.#$q 132/133 Show_Followup#Oh, do you want to show me something? -#$r 132 0 Show_Nice#Show her the pretty flower you picked. -#$r 132 0 Show_Nice#Show her the cool rock you found in the mines. -#$r 132 0 Show_Nice#Show her your favorite plushie. -#$r 133 0 Show_Diaper#Show her your diaper.", +#$r 132 5 Show_Nice#Show her the pretty flower you picked. +#$r 132 5 Show_Nice#Show her the cool rock you found in the mines. +#$r 132 5 Show_Nice#Show her your favorite plushie. +#$r 133 5 Show_Diaper#Show her your diaper.", "Show_Nice": "Oh wow @, that is very lovely! Thank you for showing me.#$b#You look so pleased! You're just like a little kid at show and tell.$1", "Show_Diaper": "Oh goodness @. That doesn't look like you're trying very hard to make it to the potty.$3", "Show_Followup":"Well don't you look excited!$1#$e#%Penny pats your head fondly.", -"fall_Sun8":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 +"fall_Sun6":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 #$q 134/135 Adult_Followup#I have a hard time thinking of you like you're an adult... -#$r 134 0 Adult_Little#Honestly, I don't really feel like one. -#$r 134 0 Adult_Little#Good! Cause I don't wanna be one. +#$r 134 10 Adult_Little#Honestly, I don't really feel like one. +#$r 134 10 Adult_Little#Good! Cause I don't wanna be one. #$r 135 0 Adult_Big#Not fair! I'm a big kid! ", "Adult_Little": "Well that's a relief! I was afraid I was reading too far into things.$1#$b#Though, your little potty problems are a dead give away, aren't they little one?$4", @@ -117,10 +117,10 @@ "winter_Tue6":"I wish I could treat my mom like the toddler she acts like all the time.$3#$e#It would probably be good for her...$2", "winter_Wed6":"Oh hello @.#$q 132/133 Show_Followup#Oh, do you want to show me something? -#$r 132 0 Show_Nice#Show her the pretty flower you picked. -#$r 132 0 Show_Nice#Show her the cool rock you found in the mines. -#$r 132 0 Show_Nice#Show her your favorite plushie. -#$r 133 0 Show_Diaper#Show her your diaper.", +#$r 132 5 Show_Nice#Show her the pretty flower you picked. +#$r 132 5 Show_Nice#Show her the cool rock you found in the mines. +#$r 132 5 Show_Nice#Show her your favorite plushie. +#$r 133 5 Show_Diaper#Show her your diaper.", "Show_Nice": "Oh wow @, that is very lovely! Thank you for showing me.#$b#You look so pleased! You're just like a little kid at show and tell.$1", "Show_Diaper": "Oh goodness @. That doesn't look like you're trying very hard to make it to the potty.$3", "Show_Followup":"Well don't you look excited!$1#$e#%Penny pats your head fondly.", @@ -140,16 +140,19 @@ "winter_Fri6":"#$p 102#I'm tutoring Vincent and Jas today... They're a handful, but it's nice to make a difference in someone's life.|Jas is so proud of her pull ups. I'm really proud to have helped her get there.$1#$b#She's still not great at keeping them clean...$3", "winter_Sat4":"Hello there @. You look happy today.#$b#$y 'Have you been doing better with your potty issues?_Yup! It's easy!_Good! I'm glad to hear it.$1_Not really. I still have accidents..._Oh @. It's okay, that's nothing to be ashamed of. Keep trying your hardest, you'll get it!'", -"winter_Sun8":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 +"winter_Sun6":"Hello @! I'm really glad I've gotten to know you.#$b#I want to tell you something; it's a little embarrassing.$4 #$q 134/135 Adult_Followup#I have a hard time thinking of you like you're an adult... -#$r 134 0 Adult_Little#Honestly, I don't really feel like one. -#$r 134 0 Adult_Little#Good! Cause I don't wanna be one. +#$r 134 10 Adult_Little#Honestly, I don't really feel like one. +#$r 134 10 Adult_Little#Good! Cause I don't wanna be one. #$r 135 0 Adult_Big#Not fair! I'm a big kid! ", "Adult_Little": "Well that's a relief! I was afraid I was reading too far into things.$1#$b#Though, your little potty problems are a dead give away, aren't they little one?$4", "Adult_Big": "%Penny giggles sweetly at your comment and pats your head.#$b#Of course you are!$1", "Adult_Followup":"#$p 135#I prefer thinking of you as a little kid rather than the big kid you say you are.$4|I'm glad you feel like a little kid!$1#$b#I think I prefer think of you as one.$4", - + + "Diaper_Change_Accept": "#Lets get that butt cleaned up!$l#$b#%Penny changes your diaper and smiles at you#$action DIAPER_CHANGE \"heart diaper\" \"second hand pants\"#$h", + "Diaper_Change_Refuse": "Do you want to play the big kid today? I can see it sagging from here!", + "Diaper_Change_Followup": "..." }, }, diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json index 6e4b2ce..96bcb37 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json @@ -14,7 +14,7 @@ "spring_Mon2":"I can't believe I have a job...$2 #$q 120/121 Job_Followup#It almost feels like I'm not old enough yet. #$r 120 0 Job_Ready#You just need a little more time before you're ready. -#$r 120 0 Job_Pretend#You could always just stop pretending to be a big boy. +#$r 121 0 Job_Pretend#You could always just stop pretending to be a big boy. ", "Job_Ready": "Yeah, I guess I do, but I'm supposed to be responsible for Mommy...$9#$b#I mean Mom...$8", "Job_Pretend": "Man I wish. It'd be so much better to just play all day. Just like Vincent.$4#$b#He doesn't have to work.$5", @@ -35,8 +35,8 @@ "spring_Sun8":"It's been wonderful getting to know you @. I feel like I can be perfectly honest with you. #$q 124/125 Little_Followup#I don't like being a big kid, I wanna go back to being a little boy. #$r 124 0 Little_Little#Awww, Sam. You ARE just a little boy! -#$r 125 0 Little_Little#Looks like I'm going to need some more diapers for the little boy. -#$r 124 0 Little_Excited#Yeah, being big is gross. We should play together! +#$r 124 0 Little_Little#Looks like I'm going to need some more diapers for the little boy. +#$r 125 0 Little_Excited#Yeah, being big is gross. We should play together! #$r 125 0 Little_Excited#I'll change your diapers if you change mine. ", "Little_Little": "Uh huh!$3#$b#%Sam squeals happily and hides his blushing face.", @@ -48,7 +48,7 @@ "summer_Mon2":"I can't believe I have a job...$2 #$q 120/121 Job_Followup#It almost feels like I'm not old enough yet. #$r 120 0 Job_Ready#You just need a little more time before you're ready. -#$r 120 0 Job_Pretend#You could always just stop pretending to be a big boy. +#$r 121 0 Job_Pretend#You could always just stop pretending to be a big boy. ", "Job_Ready": "Yeah, I guess I do, but I'm supposed to be responsible for Mommy...$9#$b#I mean Mom...$8", "Job_Pretend": "Man I wish. It'd be so much better to just play all day. Just like Vincent.$4#$b#He doesn't have to work.$5", @@ -101,8 +101,8 @@ "fall_Fri8":"It's been wonderful getting to know you @. I feel like I can be perfectly honest with you. #$q 124/125 Little_Followup#I don't like being a big kid, I wanna go back to being a little boy. #$r 124 0 Little_Little#Awww, Sam. You ARE just a little boy! -#$r 125 0 Little_Little#Looks like I'm going to need some more diapers for the little boy. -#$r 124 0 Little_Excited#Yeah, being big is gross. We should play together! +#$r 124 0 Little_Little#Looks like I'm going to need some more diapers for the little boy. +#$r 125 0 Little_Excited#Yeah, being big is gross. We should play together! #$r 125 0 Little_Excited#I'll change your diapers if you change mine. ", "Little_Little": "Uh huh!$3#$b#%Sam squeals happily and hides his blushing face.", @@ -141,7 +141,16 @@ "Little_Little": "Uh huh!$3#$b#%Sam squeals happily and hides his blushing face.", "Little_Excited": "Yeah!$3#$b#%Sam squeals happily and hides his blushing face.", "Little_Followup":"#$p 124#You always make me feel so little. It means so much to me, thank you.$4|I really want to go back to diapers full time.$4#$b#I just don't think I can while I'm still living with Mommy.$10", - + + "Change_Diaper_Accept_BabyPrint": "Are those vincents? I... mmm.$8#$b#%You change sam while he is covering his eyes with both of his hands. How cute!#$b#...$9#$b#I kind of like them.$8#$action CHANGE_DIAPER_OTHERS \"sam\" \"baby print diaper\"#$b#Seams fine, a little small perhaps. Maybe another diaper would fit him better?", + "Change_Diaper_Accept_Training": "Are those... training pants?$8#$b#%You change sam into a pair of training pants.#$b#%He probably could make it to the potty, but you are pretty sure those pants will be soaked by the end of the hour.#$action CHANGE_DIAPER_OTHERS \"sam\" \"training pants\"#$b#%He probably would like another type of diaper more.", + "Change_Diaper_Accept_BigKids": "You sure i am ready for those?$1#$b#%You change sam into a pair of big kid undies.#$b#%He looks a bit disappointed. Maybe he isn't as big of a kid as he wants you to think he is.$1#$action CHANGE_DIAPER_OTHERS \"sam\" \"big kid undies\"", + "Change_Diaper_Accept_Joja": "Thats the one from the joja mart, right? I tried those myself, they fit better. But i made the couch wet last time when i...$8#$b#%You change sam into a joja diaper, while he is still realizing what he just admitted to#$b#I told mum it was vincent.$9#$action CHANGE_DIAPER_OTHERS \"sam\" \"joja diaper\"#$b#%Another brand might be better...", + "Change_Diaper_Accept_HeartDiaper": "A heart, how... cute?$1#$b#%You change sam into a heart diaper.#$b#%He playes it off like he doesn't like it all that much, considering the design. But being in those thick, cosy, crinkeling diapers, he can't keep up the fascade long.#$action CHANGE_DIAPER_OTHERS \"sam\" \"heart diaper\"#$b#I guess they are nice...$9#$b#You get the impression sam likes those way more than he is willing to admit. And he looks very cute in them.", + + "Diaper_Change_Accept": "#Ah, hold still. Don't worry, i have to change Vincent all the time when i babysit!$l#$b#%Sam changes your diaper, like he does for Vincent.#$action DIAPER_CHANGE \"baby print diaper\" \"sams old pants\"#$h", + "Diaper_Change_Refuse": "Oh, ok.", + "Diaper_Change_Followup": "..." } }, @@ -149,62 +158,62 @@ "LogName":"Sam Marriage", "Action":"EditData", "Target":"Characters/Dialogue/MarriageDialogueSam", - "Entries":{ - - "Rainy_Day_0": "%Sam is staring out the window, watching the rain roll down wearing just his soggy night diaper and pajama shirt.#$e#%He doesn't seem to notice you. He bends his knees slightly, gently pushing a soft mess into his diaper without a second though. Only then do you tap his shoulder.#$b#@!8#$b#I-I was just watchin' the rain$10.", - "Rainy_Day_1": "Sebastian loves this kind of weather. When we were little we used to go frog catching when it rained.#$e#Do you wanna go catch frogs?!$1", - "Rainy_Day_2": "Hey, I found one of these rolling around in the back of a drawer. [90 88 86 535]#$e#I thought you might be able to use it.", - "Rainy_Day_3": "Aw, man. These cloudy days are kind of a drag...$7#$e#We could just play inside all day.#$b#$y 'Maybe we can cuddle and watch some cartoons._You'll need to wear a second diaper this time._I didn't leak THAT much last time!$1_You'll have to change me first!_Awww, but I'll miss out on all the squishing.$10'", - "Rainy_Day_4": "How'd you sleep? The sound of rain really makes me zonk.#$e#I woke up wet too, but I don't remember waking up to pee.$4#$b#That rain really works on me, huh!$10", - "patio_Sam": "*Sigh*... I'm never gonna land this trick...$s", - "Rainy_Night_0": "Hey, how was your day? I just layed around and read comics most of the day... it was great.$1#$b#What? N-no, I don't need a change!$8#$e#%It is obvious Sam is in a stinky diaper.", - "Rainy_Night_1": "It was a pretty low-key day for me... colas, frozen pizza, a few hours noodling around with a coloring book. I feel relaxed.#$e#%Sam proves his point by sighing and flooding his diaper in front of you, blushing softly.", - "Rainy_Night_2": "Earlier, I listened to our live recording from that show we played. Remember that? Man, was that sloppy.#$b#It made me a little nervous that you were there, I didn't want to mess up and have you think I was a loser!$10", - "Rainy_Night_3": "#$p 102#I hope Vincent's not too lonely now that I'm gone... I kinda felt responsible for the little guy.$s|I hope Vincent's not too lonely now that I'm gone... I kinda felt responsible for the little guy.$s#$e#I bet he'd get a kick out of how much of a little guy I turned out to be!$10.Sometimes I like to imagine being little like this right along side him. Having Mommy change our diapers together.$4#$e#I doubt I could ever fill a diaper as good as he can!$10", - "Rainy_Night_4": "Hey, I tossed a couple frozen pizzas into the oven. Here's yours. [206]$h#$e#%Sam sits down to eat with an audible squish. He doesn't seem concerned about it.", - "Indoor_Day_0": "Phew... I'll tell you one thing I don't miss about my old life... working at JojaMart.#$e#Did I ever tell you how embarrassed I got every time I had to work in the diaper isle?$10#$e#One time I found an open package, and instead of throwing it out I hid it for later.$4#$e#I was so nervous, but I'm glad I did it! That was a fun week.$10", - "Indoor_Day_1": "Hey, I made you some instant pancakes. Enjoy. [211]$h#$e#What? I never learned to cook... Mommy always did that.#$e#I miss her a lot actually$2", - "Indoor_Day_2": "Good morning @.#$b#$y 'Sam is obviously in need of a diaper change._Common little boy, let's go take care of that diaper._Y-yeah, Okay!_Hmmm._I think that should hold until after breakfast._%Sam just blushes and nods, reaching his hand down to feel how squishy his diaper is.'", - "Indoor_Day_3": "Uhhmmmm, @? C-can I show you something?$4#$e#%Sam presses your hand into his diaper front. It's still dry, but not for long.#$b#%Sam sighs as you feel the warmth spread across your hand. You give it a good squish just to watch him squirm.", - "Indoor_Day_4": "Um... Maybe I'll help out on the farm some other day. I feel lazy today.$1#$e#%Sam wiggles his crinkly bottom at you before scampering off to find his coloring book.", - "Indoor_Night_0": "Hey, you look tired. Let me help you relax tonight, okay? Maybe I'll give you a massage later.#$e$I owe you that much for taking care of my diapers all the time!$10", - "Indoor_Night_1": "My day?$8#$b#Oh... I can hardly remember. I didn't really do anything of note. Just relaxed and had a good time.$3#$b#It doesn't take long to notice Sam's leaking diaper he was trying to sneak by you.", - "Indoor_Night_2": "Hey, sorry I didn't make the bed. You know I'm sloppy... that's why you like me, right?$h#$b#You notice Sam's messy diaper just before he plops down on it with an audible squish.", - "Indoor_Night_3": "#$p 102#The only thing I miss about living at home is Mommy's fish casserole. And Mommy... I miss my Mommy$9|As much as I love being open about my diapers with you, I kind of miss the naughty rush of nabbing one of Vincent's.#$b#Or being sneaky while watching Vincent get changed.$4#$e#Is it weird to miss wanting the thing you finally have?$10", - "Indoor_Night_4": "Ready to hit the hay? I got all the diaper supplies laid out all by myself this time!$3#$e# I love you so much.$4", - "Outdoor_0": "Maybe I should get some off-road wheels for my skateboard. Mayor Lewis can't touch me out here.$h", - "Outdoor_1": "I still get nervous about my diapers crinkling when I'm off the farm.#$e#At least I don't have to worry about that here!$1", - "Outdoor_2": "Hi, @! If I knew more about farm work I'd help you out more. Sorry!#$e#It makes me feel like a helpless little Daddy's boy!$3^It makes me feel like a helpless little Momma's boy!$3", - "Outdoor_3": "Something in the air makes me feel positive... maybe it's the faint whiff of pizza from Gus' ovens.#$b#%Wait... That smell's not pizza.$10", - "Outdoor_4": "Wow... you look great today, and the specks of mud just add some extra charm.$l", - "OneKid_0": "I'll change %kid1's diaper... don't worry about it. You've already done your fair share of changing diapers!$10", - "OneKid_1": "It's weird, but I really like being a father!$h#$e#I feel like all of our little time together prepared me for how much playing babies need to do!", - "OneKid_3": "I think we should have another kid. Why stop now?", - "TwoKids_0": "I woke up early, fed the kids and changed their diapers! We're all set. You can just focus on raking in that sweet money.$h#$e#I'm just kidding... I didn't marry you for the money. Though the diaper budget has certainly gone up.", - "TwoKids_1": "We have to make sure and give %kid1 a lot of attention now that we have %kid2. We don't want any jealousy between them.#$e#I know how jealous I always felt about Vincent...$9", - "TwoKids_2": "It's fun to see the babies playing with each other. I think they're going to be very close.", - "TwoKids_3": "I never thought I'd become such a family man, but I'm really satisfied with what we've built here. Life is going great.$h", - "Good_1": "Do you ever think of that night we snuck into my room? I do, often...$l#$b#It was the first time I wore diapers around anyone else.$4", - "Good_2": "You know, I think I had a feeling we'd be together from the very beginning. There's just something special between us.$l#$b#I spent so much time fantasizing about being the farmer's little boy, and now it's a reality!$1", - "Good_3": "%Sam tugs on your sleeve bashfully.#$b#Uhmmmm, @? Can you change me please?$4#$e#Sam looks even more embarrassed as you give him a thorough check, just to make sure he really needs one.", - "Good_6": "Be careful out there! I know you go into the caves sometimes... you could be eaten alive in there!#$e#And my diaper would never get changed again and I would drown.$8#$b#Yup, that's what would happen.$1", - "Good_4": "%Sam is giggling to himself while playing with a jingly toy. You decide to give a quick diaper check while he's distracted.#$b#H-hey!$8#$e#He definitely needs a change.", - "Good_5": "I wanna show you something!$3#$b#Sam holds up a crayon drawing of both of you smiling on the farm.#$e#Do you love it?!$1", - "funLeave_Sam": "I'm gonna visit the family today, okay? I'll be home in the evening.", - "funReturn_Sam": "#$p 102#Seeing my family today was nice. I didn't realize just how much I missed my Mommy$4|I saw my family today, and I decided to wear my diapers. I don't think anyone noticed.#$b#I've been in them for so long here that I was afraid I'd have an accident if I didn't.$10#$e#Vincent was the same proud little diaper boy he always is.#$b#It was fun getting to play with him while we were both in diapers.", - "spring_1": "Ub... spring... my doze... allergies.$s", - "spring_12": "Are you excited for tomorrow's festival? It'll be cool to see Sebastian again.", - "spring_23": "Oh... tomorrow's the flower dance, isn't it? I thought I could get out of it now that we're married.#$e#Whatever. I guess it's funny in a weird way, especially now that I'm going to be waddling the whole time.$1", - "summer_1": "The pollen count is a little lower in summer, so my nose is really happy.$h", - "summer_10": "Have you thought about what you're going to put in the luau soup?#$e#It might be funny to put something nasty. You know, to play a prank on the governor!$h#$e#Sorry...", - "summer_27": "Summer's great, but I'm ready for the fall now.#$e#Should we watch the jellyfish tomorrow night? It's always kind of fun.", - "fall_1": "It seems like the whole valley's changed overnight... I guess fall's finally here.", - "fall_15": "Hey, tomorrow's the fair. I need to get my old slingshot wrist back in shape...", - "fall_26": "I wonder if Mommy will let Vincent enter the haunted maze this year. Probably not...$h#$e#Poor kid. He's gonna have to grow up some day...#$e#Well...Maybe not. I sure didn't!$10", - "winter_1": "The cold air makes my diapers feel even more warm and cozy. It's pretty wonderful.$1", - "winter_7": "Are we going to stop by the ice festival tomorrow? It might be fun to see everyone again...", - "winter_28": "We had a great year, @... it's kind of sad that it's over.#$e#We'll just have to make next year even better!$h", - } + "Entries": { + + "Rainy_Day_0": "%Sam is staring out the window, watching the rain roll down wearing just his soggy night diaper and pajama shirt.#$e#%He doesn't seem to notice you. He bends his knees slightly, gently pushing a soft mess into his diaper without a second though. Only then do you tap his shoulder.#$b#@!8#$b#I-I was just watchin' the rain$10.", + "Rainy_Day_1": "Sebastian loves this kind of weather. When we were little we used to go frog catching when it rained.#$e#Do you wanna go catch frogs?!$1", + "Rainy_Day_2": "Hey, I found one of these rolling around in the back of a drawer. [90 88 86 535]#$e#I thought you might be able to use it.", + "Rainy_Day_3": "Aw, man. These cloudy days are kind of a drag...$7#$e#We could just play inside all day. Maybe we can cuddle and watch some cartoons.#$b#$y 'You'll need to wear a second diaper this time._I didn't leak THAT much last time!$1_You'll have to change me first!_Awww, but I'll miss out on all the squishing.$10'", + "Rainy_Day_4": "How'd you sleep? The sound of rain really makes me zonk.#$e#I woke up wet too, but I don't remember waking up to pee.$4#$b#That rain really works on me, huh!$10", + "patio_Sam": "*Sigh*... I'm never gonna land this trick...$s", + "Rainy_Night_0": "Hey, how was your day? I just layed around and read comics most of the day... it was great.$1#$b#What? N-no, I don't need a change!$8#$e#%It is obvious Sam is in a stinky diaper.", + "Rainy_Night_1": "It was a pretty low-key day for me... colas, frozen pizza, a few hours noodling around with a coloring book. I feel relaxed.#$e#%Sam proves his point by sighing and flooding his diaper in front of you, blushing softly.", + "Rainy_Night_2": "Earlier, I listened to our live recording from that show we played. Remember that? Man, was that sloppy.#$b#It made me a little nervous that you were there, I didn't want to mess up and have you think I was a loser!$10", + "Rainy_Night_3": "#$p 102#I hope Vincent's not too lonely now that I'm gone... I kinda felt responsible for the little guy.$s|I hope Vincent's not too lonely now that I'm gone... I kinda felt responsible for the little guy.$s#$e#I bet he'd get a kick out of how much of a little guy I turned out to be!$10.Sometimes I like to imagine being little like this right along side him. Having Mommy change our diapers together.$4#$e#I doubt I could ever fill a diaper as good as he can!$10", + "Rainy_Night_4": "Hey, I tossed a couple frozen pizzas into the oven. Here's yours. [206]$h#$e#%Sam sits down to eat with an audible squish. He doesn't seem concerned about it.", + "Indoor_Day_0": "Phew... I'll tell you one thing I don't miss about my old life... working at JojaMart.#$e#Did I ever tell you how embarrassed I got every time I had to work in the diaper isle?$10#$e#One time I found an open package, and instead of throwing it out I hid it for later.$4#$e#I was so nervous, but I'm glad I did it! That was a fun week.$10", + "Indoor_Day_1": "Hey, I made you some instant pancakes. Enjoy. [211]$h#$e#What? I never learned to cook... Mommy always did that.#$e#I miss her a lot actually$2", + "Indoor_Day_2": "Good morning @.#$b#%Sam is obviously in need of a diaper change.#$b#$y 'Common little boy, let's go take care of that diaper._Y-yeah, Okay!_Hmmm. I think that should hold until after breakfast._*Sam just blushes and nods, reaching his hand down to feel how squishy his diaper is*'", + "Indoor_Day_3": "Uhhmmmm, @? C-can I show you something?$4#$e#%Sam presses your hand into his diaper front. It's still dry, but not for long.#$b#%Sam sighs as you feel the warmth spread across your hand. You give it a good squish just to watch him squirm.", + "Indoor_Day_4": "Um... Maybe I'll help out on the farm some other day. I feel lazy today.$1#$e#%Sam wiggles his crinkly bottom at you before scampering off to find his coloring book.", + "Indoor_Night_0": "Hey, you look tired. Let me help you relax tonight, okay? Maybe I'll give you a massage later.#$e$I owe you that much for taking care of my diapers all the time!$10", + "Indoor_Night_1": "My day?$8#$b#Oh... I can hardly remember. I didn't really do anything of note. Just relaxed and had a good time.$3#$b#It doesn't take long to notice Sam's leaking diaper he was trying to sneak by you.", + "Indoor_Night_2": "Hey, sorry I didn't make the bed. You know I'm sloppy... that's why you like me, right?$h#$b#You notice Sam's messy diaper just before he plops down on it with an audible squish.", + "Indoor_Night_3": "#$p 102#The only thing I miss about living at home is Mommy's fish casserole. And Mommy... I miss my Mommy$9|As much as I love being open about my diapers with you, I kind of miss the naughty rush of nabbing one of Vincent's.#$b#Or being sneaky while watching Vincent get changed.$4#$e#Is it weird to miss wanting the thing you finally have?$10", + "Indoor_Night_4": "Ready to hit the hay? I got all the diaper supplies laid out all by myself this time!$3#$e# I love you so much.$4", + "Outdoor_0": "Maybe I should get some off-road wheels for my skateboard. Mayor Lewis can't touch me out here.$h", + "Outdoor_1": "I still get nervous about my diapers crinkling when I'm off the farm.#$e#At least I don't have to worry about that here!$1", + "Outdoor_2": "Hi, @! If I knew more about farm work I'd help you out more. Sorry!#$e#It makes me feel like a helpless little Daddy's boy!$3^It makes me feel like a helpless little Momma's boy!$3", + "Outdoor_3": "Something in the air makes me feel positive... maybe it's the faint whiff of pizza from Gus' ovens.#$b#%Wait... That smell's not pizza.$10", + "Outdoor_4": "Wow... you look great today, and the specks of mud just add some extra charm.$l", + "OneKid_0": "I'll change %kid1's diaper... don't worry about it. You've already done your fair share of changing diapers!$10", + "OneKid_1": "It's weird, but I really like being a father!$h#$e#I feel like all of our little time together prepared me for how much playing babies need to do!", + "OneKid_3": "I think we should have another kid. Why stop now?", + "TwoKids_0": "I woke up early, fed the kids and changed their diapers! We're all set. You can just focus on raking in that sweet money.$h#$e#I'm just kidding... I didn't marry you for the money. Though the diaper budget has certainly gone up.", + "TwoKids_1": "We have to make sure and give %kid1 a lot of attention now that we have %kid2. We don't want any jealousy between them.#$e#I know how jealous I always felt about Vincent...$9", + "TwoKids_2": "It's fun to see the babies playing with each other. I think they're going to be very close.", + "TwoKids_3": "I never thought I'd become such a family man, but I'm really satisfied with what we've built here. Life is going great.$h", + "Good_1": "Do you ever think of that night we snuck into my room? I do, often...$l#$b#It was the first time I wore diapers around anyone else.$4", + "Good_2": "You know, I think I had a feeling we'd be together from the very beginning. There's just something special between us.$l#$b#I spent so much time fantasizing about being the farmer's little boy, and now it's a reality!$1", + "Good_3": "%Sam tugs on your sleeve bashfully.#$b#Uhmmmm, @? Can you change me please?$4#$e#Sam looks even more embarrassed as you give him a thorough check, just to make sure he really needs one.", + "Good_6": "Be careful out there! I know you go into the caves sometimes... you could be eaten alive in there!#$e#And my diaper would never get changed again and I would drown.$8#$b#Yup, that's what would happen.$1", + "Good_4": "%Sam is giggling to himself while playing with a jingly toy. You decide to give a quick diaper check while he's distracted.#$b#H-hey!$8#$e#He definitely needs a change.", + "Good_5": "I wanna show you something!$3#$b#Sam holds up a crayon drawing of both of you smiling on the farm.#$e#Do you love it?!$1", + "funLeave_Sam": "I'm gonna visit the family today, okay? I'll be home in the evening.", + "funReturn_Sam": "#$p 102#Seeing my family today was nice. I didn't realize just how much I missed my Mommy$4|I saw my family today, and I decided to wear my diapers. I don't think anyone noticed.#$b#I've been in them for so long here that I was afraid I'd have an accident if I didn't.$10#$e#Vincent was the same proud little diaper boy he always is.#$b#It was fun getting to play with him while we were both in diapers.", + "spring_1": "Ub... spring... my doze... allergies.$s", + "spring_12": "Are you excited for tomorrow's festival? It'll be cool to see Sebastian again.", + "spring_23": "Oh... tomorrow's the flower dance, isn't it? I thought I could get out of it now that we're married.#$e#Whatever. I guess it's funny in a weird way, especially now that I'm going to be waddling the whole time.$1", + "summer_1": "The pollen count is a little lower in summer, so my nose is really happy.$h", + "summer_10": "Have you thought about what you're going to put in the luau soup?#$e#It might be funny to put something nasty. You know, to play a prank on the governor!$h#$e#Sorry...", + "summer_27": "Summer's great, but I'm ready for the fall now.#$e#Should we watch the jellyfish tomorrow night? It's always kind of fun.", + "fall_1": "It seems like the whole valley's changed overnight... I guess fall's finally here.", + "fall_15": "Hey, tomorrow's the fair. I need to get my old slingshot wrist back in shape...", + "fall_26": "I wonder if Mommy will let Vincent enter the haunted maze this year. Probably not...$h#$e#Poor kid. He's gonna have to grow up some day...#$e#Well...Maybe not. I sure didn't!$10", + "winter_1": "The cold air makes my diapers feel even more warm and cozy. It's pretty wonderful.$1", + "winter_7": "Are we going to stop by the ice festival tomorrow? It might be fun to see everyone again...", + "winter_28": "We had a great year, @... it's kind of sad that it's over.#$e#We'll just have to make next year even better!$h" + } } ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Sebastian.json b/Regression/Regression Dialogue/Dialogue/NPCs/Sebastian.json index 17266e7..0f56256 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Sebastian.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Sebastian.json @@ -11,11 +11,8 @@ "diaperquestion_yes":"Oh...#$b#Well I hope you're not too embarrassed.#$b#I think it's kind of cute actually.$4", "diaperquestion_no":"Really?#$b#I thought that might have been the case#$e#Wow$4", "diaperquestion_followup":"#$p 306#Your diapers make you look like such a little boy.$1^Your diapers make you look like such a little girl.$1|I hope I didn't make you upset when I asked about your diapers.$2", - - - } - }, + } ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json b/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json index d44bd95..7839756 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json @@ -4,68 +4,69 @@ "LogName":"Vincent", "Action":"EditData", "Target":"Characters/Dialogue/Vincent", - "Entries":{ - "Introduction": "Oh, a stranger! My name's Vincent.#$b#Mommy says not to talk to strangers... But you seem okay. - #$q 101/102 ABDLChild_fallback#%Would you be comfortable seeing ABDL dialogue from Vincent and Jas? - #$r 101 0 ABDLChild_Yes#Yes, I am comfortable with that. - #$r 102 0 ABDLChild_No#No, I would like to see the original dialogue.", - //----------------- - "ABDLChild_Yes":"%The more hearts you have with them the more ABDL dialogue there will be.", - "ABDLChild_No":"%Okay. All the original lines will be unchanged, and they also won't notice you using your pants.", - "ABDLChild_fallback":"#$p 102#What's your name?|%You hear a crinkle with each step Vincent takes.", - //The question above happens during the introduction of Vincent or Jas, whomever the player interacts with first. They'll get to choose whether or not they want ABDL dialogue for the two of them. - //Unfortunately, this only works for new farms, not if a player installs the mod and loads an old save where they've already met both Vincent and Jas. Then it defaults to the ABDL text. + "Entries": { + "Introduction": "Oh, a stranger! My name's Vincent.#$b#Mommy says not to talk to strangers... But you seem okay.#$q 101/102 ABDLChild_fallback#%Would you be comfortable seeing diaper related dialogue from Vincent and Jas?#$r 101 0 ABDLChild_Yes#Yes, I am comfortable with that.#$r 102 0 ABDLChild_No#No, I would like to see the original dialogue.", + //----------------- + "ABDLChild_Yes": "%The more hearts you have with them the more ABDL dialogue there will be.", + "ABDLChild_No": "%Okay. All the original lines will be unchanged.", + "ABDLChild_fallback": "#$p 102#What's your name?|%You hear a crinkle with each step Vincent takes.", + //The question above happens during the introduction of Vincent or Jas, whomever the player interacts with first. They'll get to choose whether or not they want ABDL dialogue for the two of them. + //Unfortunately, this only works for new farms, not if a player installs the mod and loads an old save where they've already met both Vincent and Jas. Then it defaults to the ABDL text. + "spring_12_1": "The egg hunt is tomorrow! I'm gonna find so many!$1#$e#I'm a good finder.", + "spring_12_2": "The egg hunt is tomorrow! I'm gonna find so many!$1#$e#I'm a good finder.", + "spring_Mon10": "#$p 102#I wanna be just like my big brother when I grow up!|I think I need my diaper changed, but I'm gonna wait until Mommy checks me.#$b#I don't mind being messy a bit longer!$1#$action DIAPER_ACCIDENT poop vincent", + "spring_Tue": "#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|I like it better when Miss Penny reads to us.", + "spring_Tue10": "#$p 102#Don't tell Mommy... but you're my favorite grown-up.$h|I found a frog and put it in my diaper.#$b#It's a surprise for Mommy!$1#$e#%Vincent looks like he's being tickled.#$action DIAPER_ACCIDENT pee vincent", + "spring_Wed2": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|Mommy told me I can still be her little baby boy if I wasn't ready to grow up yet.#$e#I love my Mommy!$1", + "spring_Thu": "#$p 102#I'm hungry... where's Mommy?$s|%You notice Vincent's diaper peeking out of his waistband.#$e#Hi @!$1", + "spring_Thu6": "#$p 102#You're not as boring as most grown-ups!|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.", + "spring_Thu10": "#$p 102#You're not as boring as most grown-ups!|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.#$e#%You just barely notice a squish.#$action DIAPER_ACCIDENT pee vincent", + "spring_Fri2": "#$p 102#Oh no... Mommy's making lentil soup tonight.$s|Sam says I'm still his cute little baby brother.#$e#%Vincent wiggles in glee.", + "spring_Fri_inlaw_Sam": "#$p 102#Oh no... Mommy's making lentil soup tonight.$s|How's my brother doing?#$e#Can you tell him he can still borrow my stuffies if he wants?$3#$b#I don't want him to be scared.$2", + "spring_Sat8": "#$p 102#Miss Penny makes me read a new book every week.$s|Jas pooped in her pull ups at the library yesterday!#$b#She blamed it on me and Ms. Penny believed her.$2#$b#I was pretty messy though.$3#$b#But right now i am just a little wet, i think.#$action DIAPER_ACCIDENT pee vincent", + "spring_Sun4": "#$p 102#Hi there!|I can tie my own shoes now, but sometimes I ask Mommy to do it for me anyway.#$e#I like how it makes her all smiley!$1", - "spring_12_1": "The egg hunt is tomorrow! I'm gonna find so many!$1#$e#I'm a good finder.", - "spring_12_2": "The egg hunt is tomorrow! I'm gonna find so many!$1#$e#I'm a good finder.", - "spring_Mon10":"#$p 102#I wanna be just like my big brother when I grow up!|I think I need my diaper changed, but I'm gonna wait until Mommy checks me.#$e#I don't mind being messy a bit longer!$1", - "spring_Tue":"#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|I like it better when Miss Penny reads to us.", - "spring_Tue10":"#$p 102#Don't tell Mommy... but you're my favorite grown-up.$h|I found a frog and put it in my diaper.#$b#It's a surprise for Mommy!$1#$e#%Vincent looks like he's being tickled.", - "spring_Wed2":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|Mommy told me I can still be her little baby boy if I wasn't ready to grow up yet.#$e#I love my Mommy!$1", - "spring_Thu":"#$p 102#I'm hungry... where's Mommy?$s|%You notice Vincent's diaper peeking out of his waistband.#$e#Hi @!$1", - "spring_Thu6":"#$p 102#You're not as boring as most grown-ups!|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.", - "spring_Thu10":"#$p 102#You're not as boring as most grown-ups!|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.#$e#%You just barely notice a squish.", - "spring_Fri2":"#$p 102#Oh no... Mommy's making lentil soup tonight.$s|Sam says I'm still his cute little baby brother.#$e#%Vincent wiggles in glee.", - "spring_Fri_inlaw_Sam":"#$p 102#Oh no... Mommy's making lentil soup tonight.$s|How's my brother doing?#$e#Can you tell him he can still borrow my stuffies if he wants?$3#$b#I don't want him to be scared.$2", - "spring_Sat8":"#$p 102#Miss Penny makes me read a new book every week.$s|Jas pooped in her pull ups at the library yesterday!#$e#She blamed it on me and Ms. Penny believed her.$2#$e#I was pretty messy though.$3", - "spring_Sun4":"#$p 102#Hi there!|I can tie my own shoes now, but sometimes I ask Mommy to do it for me anyway.#$e#I like how it makes her all smiley!$1", + "summer_Mon4": "#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.$3", + "summer_Mon8": "#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.$3#$b#Pull ups are basically just diapers anyway.", + "summer_Tue": "#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|My teddy bear's name is Squishy.#$b#I like him a lot!$1", + "summer_Tue_inlaw_Penny": "#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|Does Miss Penny change your diapers too?#$b#She says I gotta try and use the potty more, but if I do she won't change me anymore.$2", + "summer_Wed10": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|@! I wanna show you something cool!#$e#%Vincent squats down shamelessly, grunting softly while you watch his pants droop.#$e#All done!$1#$action DIAPER_ACCIDENT poop vincent", + "summer_Thu6": "#$p 102#You're not as boring as most grown-ups!|Mommy wants me to try using the potty, but I don't wanna.$3#$b#It's scary, and I don't wanna be a big kid yet.$2", + "summer_Fri2": "#$p 102#Ew, it's boiled beet night again...$s|%Vincent is sucking on his thumb and humming happily to himself.#$e#Hi @!$1", + "summer_Fri10": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%Vincent is sucking on his thumb and humming happily to himself.#$e#%You notice him pause for a minute, a faint blush on his cheeks, and a little grin behind his thumb.#$action DIAPER_ACCIDENT pee vincent", + "summer_Sat10": "#$p 102#Don't tell Mommy... but you're my favorite grown-up.$h|I found a frog and put it in my diaper.#$b#It's a surprise for Mommy!$1#$e#%Vincent looks like he's being tickled.", + "summer_Sun2": "#$p 102#Miss Penny makes me read a new book every week.$s|Sometimes, when I'm bored, I like to play with my old baby toys.", - "summer_Mon4":"#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.$3", - "summer_Mon8":"#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.$3#$e#Pull ups are basically just diapers anyway.", - "summer_Tue":"#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|My teddy bear's name is Squishy.#$e#I like him a lot!$1", - "summer_Tue_inlaw_Penny":"#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|Does Miss Penny change your diapers too?#$e#She says I gotta try and use the potty more, but if I do she won't change me anymore.$2", - "summer_Wed10":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|@! I wanna show you something cool!#$e#%Vincent squats down shamelessly, grunting softly while you watch his pants droop.#$e#All done!$1", - "summer_Thu6":"#$p 102#You're not as boring as most grown-ups!|Mommy wants me to try using the potty, but I don't wanna.$3#$b#It's scary, and I don't wanna be a big kid yet.$2", - "summer_Fri2":"#$p 102#Ew, it's boiled beet night again...$s|%Vincent is sucking on his thumb and humming happily to himself.#$e#Hi @!$1", - "summer_Fri10":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%Vincent is sucking on his thumb and humming happily to himself.#$e#%You notice him pause for a minute, his free hand resting on his diaper, a faint blush on his cheeks, and a little grin behind his thumb.#$e#Ahhhh.", - "summer_Sat10":"#$p 102#Don't tell Mommy... but you're my favorite grown-up.$h|I found a frog and put it in my diaper.#$b#It's a surprise for Mommy!$1#$e#%Vincent looks like he's being tickled.", - "summer_Sun2":"#$p 102#Miss Penny makes me read a new book every week.$s|Sometimes, when I'm bored, I like to play with my old baby toys.", + "fall_Mon4": "#$p 102#I wanna be just like my big brother when I grow up!|Jas keeps bragging about being in pull ups.#$e#I miss when we were in diapers together.$2", + "fall_Tue10": "#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|Wanna know a secret?#$b#I don't wanna stop wearing diapers.$3#$b#Mommy says it's okay if I'm not ready yet!$1", + "fall_Wed": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%You notice Vincent's diaper peeking out of his waistband.", + "fall_Wed6": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.", + "fall_Wed10": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.#$e#%You just barely notice a squish.#$action DIAPER_ACCIDENT pee vincent", + "fall_Thu10": "#$p 102#You're not as boring as most grown-ups!|I think I need my diaper changed, but I'm gonna wait until Mommy checks me.#$b#I don't mind being messy a bit longer!$1#$action DIAPER_ACCIDENT poop vincent", + "fall_Fri4": "#$p 102#Oh no... Mommy's making lentil soup tonight.$s|I can tie my own shoes now, but sometimes I ask Mommy to do it for me anyway.#$b#I like how it makes her all smiley!$1", + "fall_Sat6": "#$p 102#Miss Penny makes me read a new book every week.$s|I had an accident in the libary yesterday$3#$b#Jas told on me, that was not nice!$2#$b#But then Miss Penny changed jas instead of me, that was great!$1#$b#But i have a big of rash now...$3", + "fall_Sun4": "#$p 102#Hi there!|Sam says I'm still his cute little baby brother.#$b#%Vincent wiggles in glee.", + "fall_Sun_inlaw_Sam": "#$p 102#Hi there!|How's my brother doing?#$e#Can you tell him he can still borrow my stuffies if he wants?$3#$b#I don't want him to be scared.$2", - "fall_Mon4":"#$p 102#I wanna be just like my big brother when I grow up!|Jas keeps bragging about being in pull ups.#$e#I miss when we were in diapers together.$2", - "fall_Tue10":"#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|Wanna know a secret?#$e#I don't wanna stop wearing diapers.$3#$e#Mommy says it's okay if I'm not ready yet!$1", - "fall_Wed":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%You notice Vincent's diaper peeking out of his waistband.", - "fall_Wed6":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.", - "fall_Wed10":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%You notice Vincent's diaper peeking out of his waistband.#$b#%When he sees you he giggles and pats his crinkly bottom.#$e#%You just barely notice a squish.", - "fall_Thu10":"#$p 102#You're not as boring as most grown-ups!|I think I need my diaper changed, but I'm gonna wait until Mommy checks me.#$e#I don't mind being messy a bit longer!$1", - "fall_Fri4":"#$p 102#Oh no... Mommy's making lentil soup tonight.$s|I can tie my own shoes now, but sometimes I ask Mommy to do it for me anyway.#$e#I like how it makes her all smiley!$1", - "fall_Sat6":"#$p 102#Miss Penny makes me read a new book every week.$s|Mommy told me I can still be her little baby boy if I wasn't ready to grow up yet.#$e#I love my Mommy!$1", - "fall_Sun4":"#$p 102#Hi there!|Sam says I'm still his cute little baby brother.#$e#%Vincent wiggles in glee.", - "fall_Sun_inlaw_Sam":"#$p 102#Hi there!|How's my brother doing?#$e#Can you tell him he can still borrow my stuffies if he wants?$3#$b#I don't want him to be scared.$2", - - "winter_Mon":"#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.", - "winter_Mon8":"#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.$3#$e#Pull ups are basically just diapers anyway.", - "winter_Tue10":"#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|%Vincent stares off for a moment and sighs in relief as a faint hiss reaches your ears.#$e#Just warmin' up!$1", - "winter_Wed2":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%Vincent is sucking on his thumb and humming happily to himself.#$e#Hi @!$1", - "winter_Wed10":"#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%Vincent is sucking on his thumb and humming happily to himself.#$e#%You notice him pause for a minute, his free hand resting on his diaper, a faint blush on his cheeks, and a little grin behind his thumb.#$e#Ahhhh", - "winter_Thu8":"#$p 102#You're not as boring as most grown-ups!|Mommy wants me to try using the potty, but I don't wanna.$3#$b#It's SO cold!$2", - "winter_Fri":"#$p 102#Oh no... Mommy's making lentil soup tonight.$s|Sam said he'd make a snow man with me today!#$e#We're gonna have hot chocolate after too.", - "winter_Sat10":"#$p 102#Don't tell Mommy... but you're my favorite grown-up.$h|@! I wanna show you something cool!#$e#%Vincent squats down shamelessly, grunting softly while you watch his pants droop.#$e#All done!$1", - "winter_Sun":"#$p 102#Miss Penny makes me read a new book every week.$s|My teddy bear's name is Squishy.#$e#I like him a lot!$1", - "winter_Sun_inlaw_Penny":"#$p 102#Miss Penny makes me read a new book every week.$s|Does Miss Penny change your diapers too?#$e#She says I gotta try and use the potty more, but if I do she won't change me anymore.$2", - - - }, - }, + "winter_Mon": "#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.", + "winter_Mon8": "#$p 102#I wanna be just like my big brother when I grow up!|Jas only pretends to be a big girl.$3#$e#Pull ups are basically just diapers anyway.", + "winter_Tue10": "#$p 102#*sigh*... Mommy won't let me have any more gummies today.$s|%Vincent stares off for a moment and sighs in relief as a faint hiss reaches your ears.#$b#Just warmin' up!$1#$action DIAPER_ACCIDENT pee vincent", + "winter_Wed2": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%Vincent is sucking on his thumb and humming happily to himself.#$e#Hi @!$1", + "winter_Wed10": "#$p 102#I wanna look for bugs, but Mommy gets mad when I'm all dirty.$u|%Vincent is sucking on his thumb and humming happily to himself.#$b#%You notice him pause for a minute, his free hand resting on his diaper, a faint blush on his cheeks, and a little grin behind his thumb.#$b#Ahhhh#$action DIAPER_ACCIDENT poop vincent", + "winter_Thu8": "#$p 102#You're not as boring as most grown-ups!|Mommy wants me to try using the potty, but I don't wanna.$3#$b#It's SO cold!$2", + "winter_Fri": "#$p 102#Oh no... Mommy's making lentil soup tonight.$s|Sam said he'd make a snow man with me today!#$e#We're gonna have hot chocolate after too.", + "winter_Sat10": "#$p 102#Don't tell Mommy... but you're my favorite grown-up.$h|@! I wanna show you something cool!#$b#%Vincent squats down shamelessly, grunting softly while you watch his pants droop.#$b#All done!$1#$action DIAPER_ACCIDENT poop vincent", + "winter_Sun": "#$p 102#Miss Penny makes me read a new book every week.$s|My teddy bear's name is Squishy.#$e#I like him a lot!$1", + "winter_Sun_inlaw_Penny": "#$p 102#Miss Penny makes me read a new book every week.$s|Does Miss Penny change your diapers too?#$b#She says I gotta try and use the potty more, but if I do she won't change me anymore.$2", + "Change_Diaper_Accept_BabyPrint": "*You quickly grab vincent, before he even realized what you are up to*$3#$b#%You change vincent into a baby print diaper.#$b#Oh! Thats the same ones Jodi and Sam always put me into! Thanks!$0#$b#%Vincent seams happy and well protected now...#$action ACTIONS CHANGE_DIAPER_OTHERS vincent \"baby print diaper\" ADD_DIALOG jodi \"Thank you for taking such good care of my baby boy. Here, just to make sure you don't run out, i know you need them too.___$_b___%You take the baby print diaper, a little bit embarrased.___$_action GIVE_UNDERWEAR \\\"baby print diaper\\\"\" change_vincent", + "Change_Diaper_Accept_Training": "*You show vincent a pair of training pants. He looks eager to get into them.*$0#$b#%You change vincent into a pair of training pants.#$b#I am big now! Now i have the same ones jas gets all the time!$1#$b#%You are left to think about if that was really enough protection...#$action ACTIONS CHANGE_DIAPER_OTHERS vincent \"training pants\" ADD_DIALOG jodi \"Did Vincent got the training pants last time from you? I was just wondering if he swapped with jas. Lots of washing and tears i tell you. Here...___$_b___%Jodi seams upset while handing you the pair of training pants.___$_action GIVE_UNDERWEAR \\\"training pants\\\"\" change_vincent", + "Change_Diaper_Accept_Lavender": "*You show vincent a pair of lavender pullups. He looks unsure.*$3#$b#%You still change vincent into a pair of lavender pullups.#$b#They... like... for little girls! I don't like them!$2#$b#%Maybe Vincent would like a different kind of diaper?#$action ACTIONS CHANGE_DIAPER_OTHERS vincent \"lavender pullups\" ADD_DIALOG jodi \"Vincent was upset after you changed him last time. But i have to admit, those pullups are more absorbend than i thought! You may still try one of those, next time.___$_b___%\\\"It worked\\\", you think, looking at the baby print diaper you got handed.___$_action GIVE_UNDERWEAR \\\"baby print diaper\\\"\" change_vincent", + "Change_Diaper_Accept_BigKids": "*You show vincent a pair of big kid undies. He looks excited to get into them.*$0#$b#%You change vincent into a pair of big kid undies.#$b#I am super big now! *He looks exited* Have to tell jas!$1#$b#%You will probably hear no end of it when jodi finds out...#$action ACTIONS CHANGE_DIAPER_OTHERS vincent \"big kid undies\" ADD_DIALOG jodi \"What got into you? Normal underwear? What make you think that would not end in a catastrophy? They where so filthy i had to throw them away!___$_b___%Not that surprising, really.\" change_vincent", + "Change_Diaper_Accept_Dinos": "DINOS! *Vincent is immediatly taken by the design*$0#$b#%You change vincent into a pair of padded dinosaur undies.#$b#I am super big now! *He looks exited* Have to tell jas!$1##$b#%Vincent is happy, but jodi surly will not...#$action ACTIONS CHANGE_DIAPER_OTHERS vincent \"dinosaur undies\" ADD_DIALOG jodi \"If you wonder if the dino undies worked, you no longer have too. Here, you can have them back. I washed and repaired them. Just make sure to not put them on vincent again, please?___$_b___%Maybe next time?___$_action GIVE_UNDERWEAR \\\"dinosaur undies\\\"\" change_vincent", + "Change_Diaper_Refuse": "It's ok, i don't really need a change!$1#$b#%[NpcOnSlightlyWet: Vincent probably will be, for now.][NpcOnUsedBad: Looking Vincent waddle away in his filled pants, you feel much less certain about that than he is.]", + "Change_Diaper_Followup": "..." + } + } ] } \ No newline at end of file diff --git a/Regression/Regression Dialogue/manifest.json b/Regression/Regression Dialogue/manifest.json index 8a53fa8..2216ac3 100644 --- a/Regression/Regression Dialogue/manifest.json +++ b/Regression/Regression Dialogue/manifest.json @@ -10,7 +10,7 @@ }, "Dependencies": [ { - "UniqueID": "Zippity21.Regression", + "UniqueID": "Zippity21.Regression" } ] } \ No newline at end of file diff --git a/Regression/Regression.csproj b/Regression/Regression.csproj index 9d9edb4..605b1c6 100644 --- a/Regression/Regression.csproj +++ b/Regression/Regression.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -10,11 +10,15 @@ + + + PreserveNewest + PreserveNewest @@ -33,6 +37,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -60,7 +70,9 @@ - + + + diff --git a/Regression/config.json b/Regression/config.json index 13d689e..62adbc8 100644 --- a/Regression/config.json +++ b/Regression/config.json @@ -1,21 +1,33 @@ //Thanks to contributors: u/BabyKunoichi, u/abdlnikki, u/FurryDestiny //Thanks to alpha testers: u/zombiekarasu, u/dr_daddy, u/errycupid, u/rosebush413, u/mrnogee, u/crinklycuddles, u/vulpix77 { - "Wetting": true, - "Messing": true, - "Easymode": false, + "Wetting": true, // This activates poop and bowel events. + "Messing": true, // This activates pee and bladder events. + "Easymode": false, // Hunger and Thirst are refilled every morning and the wet beds dried. "PantsChangeRequiresHome": true, // If changing your pants (in case you soiled your cloth) requires you to be at home + "UnderwearChangeCauseExposure": true, // Changing your underwear, by yourself, requires you to undress, as such exposing yourself. With this option activated you need to change your diapers at home or away from people. "FriendshipPenaltyBladderMultiplier": 100, // How peeing in public impacts friendships. 100 is normal, 50 would be half, 200 double the impact. 0 deactivates loss of frienship for pee incidents "FriendshipPenaltyBowelMultiplier": 200, // How pooping in public impacts friendships. 100 is normal, 50 would be half, 200 double the impact. 0 deactivates loss of frienship for poop incidents - "AlwaysNoticeAccidents": true, - "Debug": false, - "ToiletGainMultiplier": 200, //0 would be no gain, 50 half as much, 200 twice as much. Only applies while daytime. - "NighttimeLossMultiplier": 50, //0 would be no loss, 50 half as much, 200 twice as much. Half may be more balanced, because otherwise there is no coming back. - "NighttimeGainMultiplier": 100, //0 would be no gain, 50 half as much, 200 twice as much - "GoingVoluntaryInUnderwearGainMultiplier": 0, //If you go in your pants on purpose, the continence gained should probably not be as high as making it to a toilet (+toilet multiplier) or at least on the floor. 0 would be no gain, 50 half as much, 200 twice as much. 0 is balanced as it doesn't reduce continence at least. - "BladderLossContinenceRate": 2, //in 1% increments. i.e. 5 = 5% loss per accident. 3% seams balanced - "BowelLossContinenceRate": 2, //in 1% increments. i.e. 5 = 5% loss per accident - "BladderGainContinenceRate": 2, //in 1% increments. i.e. 5 = 5% gain per success. 3% seams balanced, as it is probably doubled to 6% for potty runs (toilet multiplier). It's efford for the player. - "BowelGainContinenceRate": 2, //in 1% increments. i.e. 5 = 5% gain per success + "AlwaysNoticeAccidents": true, // Defines if you will notice accidents on low control values. + "Debug": false, // Allowes to spawn items, change potty training and displays debug related messages. + "NighttimeLossMultiplier": 50, //How serious the loss of potty training is at night, compared to daytime. Usually 50 (half). + "NighttimeGainMultiplier": 50, //How big the gains are if you stay dry/clean at night, compared to daytime. Usually 50 (half). + "InUnderwearOnPurposeMultiplier": 50, // How big of a negativ impact has an accident in underwear if it was on purpose?. Usually 50 (half) as much as an actual accident. + "BladderLossContinenceRate": 2, //2 is a 2% continence loss for MaxBladderCapacity accidents. + "BowelLossContinenceRate": 4, //3 is a 3% continence loss for MaxBowelCapacity accidents. + "BladderGainContinenceRate": 3, //3 is a 3% continence gain for making it to the toilet with a bladder that is at least half full. + "BowelGainContinenceRate": 4, //3 is a 3% continence gain for making it to the toilet with a bowel that is at least half full. + "MaxBladderCapacity": 600, // 600 is around 3 potty runs a day + "MaxBowelCapacity": 1000, // 1000 is around 1.5 potty runs a day, dependend on work (calorie intake) + "StartBladderContinence": 70, // A value (in percent) between 0 and 100, defines the starting (new game) bladder continence. Usually 70. + "StartBowelContinence": 90, // A value (in percent) between 0 and 100, defines the starting (new game) bowel continence. Usually 90. + "ReadSaveFiles": true, // This will activate reading of the (legacy) save files. This will also delete save files from the last day, if a new one starts. + "WriteSaveFiles": false, // This will activate writing of the (legacy) save files. It is recommended to disable this option. + "KeyPee": 112, // F1 - Key for peeing in underwear + "KeyPeeInToilet": 112, // F1 - If this is set to the same value than KeyPee, Shift has to be pressed in addition + "KeyPoop": 113, // F2 - Key for peeing in underwear + "KeyPoopInToilet": 113, // F2 - If this is set to the same value than KeyPoopInToilet, Shift has to be pressed in addition + "KeyGoInPants": 0, // Unbound - Pee and Poop in your pants + "KeyGoInToilet": 0, // Unbound - Pee and Poop in the toilet - If this is set to the same value than KeyGoInPants, Shift has to be pressed in addition "Lang": "en" } \ No newline at end of file diff --git a/Regression/en.json b/Regression/en.json index 5dd4a3d..7907690 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -1,1619 +1,2162 @@ { - "Jodi_Initial_Letter": [ "Dear @,^Welcome to town! Here are some veggies from the garden to tide you over while you move in. Your grandpa told me about your little problem, so I enclosed some supplies for you. Visit Pierre if you run out!^ <, Jodi" ], - "Food_Low": [ - "You're hungry.", - "Your stomach rumbles.", - "You're thinking about eating food.", - "You think about finding food.", - "You need some food." - ], - "Food_None": [ - "You're starving!", - "All you can think about is food! Better eat!", - "You're so hungry you can't think straight!" - ], - "Water_Low": [ - "You're getting pretty thirsty.", - "You could really use some water.", - "You're thinking about getting a drink.", - "You need a drink." - ], - "Water_None": [ - "You're dehydrated!", - "You're super thirsty! Get a drink right now!", - "You're so thirsty you can't think straight!" - ], - "Drink_Water_Source": [ - "You scoop up some water in a cup and drain it down." - ], - "Bladder_Yellow": [ - "You need to pee.", - "You should find somewhere to pee soon.", - "You feel like you might pee soon.", - "Your bladder is getting full." - ], - "Bladder_Orange": [ - "You really need to pee!", - "You're not sure how much longer you can hold your pee!", - "If you don't pee soon, you'll have an accident!", - "You start crossing your legs trying not to pee yourself!" - ], - "Bladder_Red": [ - "You can’t hold it anymore! You're about to pee yourself!", - "You have to pee so badly you start hopping around!", - "You feel a few drops of pee leak out into your $UNDERWEAR_NAME$!" - ], - "Bowels_Yellow": [ - "You need to poop.", - "You should find somewhere to poop soon.", - "You feel a rumble in your bowels.", - "It might be time to poop." - ], - "Bowels_Orange": [ - "You really need to poop!", - "If you don't find a place to poop soon, you'll mess yourself!", - "You're not sure how much longer you can hold your poop!" - ], - "Bowels_Red": [ - "You can feel the poop starting to push out!", - "You can’t hold it anymore! You're about to mess yourself!" - ], - "Bladder_Continence_Green": [ "You're pretty good at holding your pee." ], - "Bladder_Continence_Yellow": [ "You can mostly hold your pee it. Mostly." ], - "Bladder_Continence_Orange": [ "You're pretty bad at holding your pee." ], - "Bladder_Continence_Red": [ "You're close to being unable to hold your pee." ], - "Bladder_Continence_Min": [ "You're almost totally unable to hold your pee." ], - "Bowel_Continence_Green": [ "You pretty good at holding your poop." ], - "Bowel_Continence_Yellow": [ "You can hold you poop most of the time." ], - "Bowel_Continence_Orange": [ "You're pretty bad at holding your poop." ], - "Bowel_Continence_Red": [ "You're getting close to being unable to hold your poop." ], - "Bowel_Continence_Min": [ "You're almost totally unable to hold your poop." ], - "Pee_Voluntary": [ - "You drop your $UNDERWEAR_NAME$ and pee on the ground.", - "Moving your $UNDERWEAR_NAME$, you take a deep breath and empty your bladder.", - "Looking around sheepishly, you pull your $UNDERWEAR_NAME$ down and go right where you are!", - "You slide your $PANTS_NAME$ to your knees and let your pee splatter all over the ground.", - "You pull down your $PANTS_NAME$ and sprinkle on the ground.", - "You pull your $PANTS_NAME$ down and go on the ground.", - "You slide your $PANTS_NAME$ down, , and empty your bladder." - ], - "Poop_Voluntary": [ - "You slide your $PANTS_NAME$ down, squat, and empty your bowels.", - "Looking around nervously, you pull your $PANTS_NAME$ down and go number two right on the ground!", - "Undressing, you squat and let your poop pile out onto the ground.", - "You pull down your $PANTS_NAME$ and poop on the ground.", - "You slide your $PANTS_NAME$ to your knees, squat down, and gently push all your poop out." - ], - "Pee_Toilet": [ - "Sprinkling into the toilet, you breathe a sigh of relief.", - "You pee in the potty like a big .", - "You slide your $PANTS_NAME$ down, , and pee like a big .", - "You barely make it to the toilet. Any longer and you might have wet yourself!", - "You wee in the toilet. Good thing you were able to hold it until then!", - "You proudly pee in the toilet. Now you won't need a diaper!", - "You tinkle in the toilet. Your Mommy would be proud!", - "You undress and go number one in the toilet like a good ." - ], - "Poop_Toilet": [ - "As your poop slides out into the toilet, you start to relax. Whew, that felt good!", - "You slide your $PANTS_NAME$ to your knees, sit on the toilet, and poop like a big .", - "You poop in the potty like a big .", - "You poop in the toilet. Maybe now you won't mess yourself today!", - "You slide your $PANTS_NAME$ to your knees and poop in the toilet.", - "You proudly poop in the toilet. Now you won't need a diaper!", - "You poop in the toilet. Your Mommy would be proud!", - "You undress and go number two in the toilet like a good ." - ], - "Pee_Toilet_Attempt": [ - "You try to pee in the potty like a big , but nothing comes out.", - "You slide your $PANTS_NAME$ down, , and try to pee, but you can't." - ], - "Poop_Toilet_Attempt": [ - "You squirm a little as you try to poop in the toilet, but nothing comes out.", - "You try to poop in the potty like a big , but you can't.", - "You slide your $PANTS_NAME$ to your knees, sit on the toilet, and strain to poop, but nothing comes out." - ], - "Wet_Voluntary": [ - "You relax your bladder and pee gushes into your $UNDERWEAR_NAME$.", - "Your bladder tingles as you let go and warmth spreads out into your $UNDERWEAR_NAME$.", - "You take a deep breath and release your pee into your $UNDERWEAR_NAME$.", - "You glance around a little sheepishly as you deliberately pee your $UNDERWEAR_NAME$ like a little ." - ], - "Mess_Voluntary": [ - "You squat a little and empty your bowels into your $UNDERWEAR_NAME$.", - "You concentrate and push a warm load of poop into your $UNDERWEAR_NAME$.", - "You hope nobody notices as you deliberately let a big poop squeeze out into your $UNDERWEAR_NAME$." - ], - "Pee_Attempt": [ - "You pull down your $PANTS_NAME$ and relax your bladder, but nothing comes out.", - "You slide your $PANTS_NAME$ down, , and try to pee, but you can't." - ], - "Poop_Attempt": [ - "You pull down your $PANTS_NAME$ and try to poop, but you can't.", - "You slide your $PANTS_NAME$ to your knees, squat down, and strain to poop, but nothing comes out." - ], - "Wet_Attempt": [ - "You relax your bladder, but nothing comes out.", - "You try to pee in your $UNDERWEAR_NAME$, but you can't." - ], - "Mess_Attempt": [ - "You squat a little and strain, but nothing comes out.", - "You try to mess in your $UNDERWEAR_NAME$, but you can't." - ], - "Still_Soiled": [ - "You feel your $UNDERWEAR_NAME$ and blush at the sensation.", - "You feel like a little knowing that you're still in $UNDERWEAR_PREFIX$ $UNDERWEAR_NAME$.", - "You blush and smile warmly realizing you're wearing $UNDERWEAR_PREFIX$ $UNDERWEAR_NAME$.", - "You smell something stinky and your heart flutters as you realize you're still wearing $UNDERWEAR_PREFIX$ $UNDERWEAR_NAME$.", - "You feel your $UNDERWEAR_NAME$ squishing between your legs and smile to yourself.", - "You notice your sagging $UNDERWEAR_NAME$ snug and warm.", - "You notice you're waddling because your $UNDERWEAR_NAME$ .", - "You consider changing your $UNDERWEAR_NAME$ soon, but not right now. It's still warm", - "You press your hand into your squishy $UNDERWEAR_NAME$. You feel like a little baby knowing you .", - "You feel your $UNDERWEAR_NAME$. all !" - ], - "Wet_Accident": [ - "You bite your lip and take a sharp breath through your nose as your bladder gives in and you flood your $UNDERWEAR_NAME$.", - "You're helpless as pee streams into your $UNDERWEAR_NAME$.", - "You hope no one notices the pee pouring into your $UNDERWEAR_NAME$.", - "Your thumb finds its way into your mouth as you suddenly feel warmth spreading into your $UNDERWEAR_NAME$!", - "You hope your $UNDERWEAR_NAME$ doesn't leak as you realize you're wetting yourself.", - "You stop in your tracks as you start to go in your $UNDERWEAR_NAME$!", - "You give a sheepish smile as you realize the warmth spreading into your crotch is pee!", - "You when you realize you're suddenly wetting yourself!", - "With a faint hiss, warmth floods into your $UNDERWEAR_NAME$!", - "You press your hands to your crotch, feeling the warmth as the sudden flood of pee comes rushing out.", - "You're wetting your $UNDERWEAR_NAME$ like a little !", - "You give up trying to hold it any longer and your pee gushes out, flooding your $UNDERWEAR_NAME$.", - "You can't help but relax and let your pee spurt into your $UNDERWEAR_NAME$", - "Oopsies! You're wetting yourself!", - "You're wetting your $UNDERWEAR_NAME$! Oh well.", - "You notice a growing warmth before glancing down and realizing you're peeing in your $UNDERWEAR_NAME$!", - "Your $UNDERWEAR_NAME$ as you wet yourself. Your cheeks flush as you realize you're just a little ." - ], - "Mess_Accident": [ - "Your knees bend and your body bushes on its own as you find yourself pushing a warm load into your $UNDERWEAR_NAME$.", - "You realize you're suddenly filling the back of your $UNDERWEAR_NAME$! You heft your seat with a slight blush as your warm, soft muck squishes against you.", - "You sigh with relief and grin bashfully as the distinctive smell of poop begins to waft from your $UNDERWEAR_NAME$.", - "You bashfully cover your face as you fill your $UNDERWEAR_NAME$ with warm poop. After you're done, you realize your thumb found it's way into your mouth", - "With a faint crackling sound, your poop squeezes out into your $UNDERWEAR_NAME$.", - "You start squirming and push a heavy load of poop into your $UNDERWEAR_NAME$.", - "You're almost startled as you notice it. You're pooping yourself!", - "You don't want to hold your poop any more and release it into your $UNDERWEAR_NAME$.", - "You finally give in, and a heavy load of warm poop pushes into your $UNDERWEAR_NAME$.", - "You freeze up and look around sheepishly as your poop squishes out into your $UNDERWEAR_NAME$.", - "You're pooping in your pants!", - "You feel a warm mass spreading into your $UNDERWEAR_NAME$ and feel like a little .", - "You push on the back of your $UNDERWEAR_NAME$ as , giggling as it squishes around", - "Oopsies! Your $UNDERWEAR_NAME$ all messy now!", - "You don't try and stop it any longer! You're messing yourself!", - "You mess your $UNDERWEAR_NAME$ like a little baby !", - "Your $UNDERWEAR_NAME$ as you openly mess yourself.", - "You give up trying to hold it and sigh in relief as you mess your $UNDERWEAR_NAME$!" - ], - "Toilet_Night": [ - "You had to last night, and made it to the toilet$HOW_MANY_TIMES", - "You woke up to in the potty like a big last night$HOW_MANY_TIMES" - ], - "Wake_Up_Underwear_State": [ - "You wake up in $INSPECT_UNDERWEAR_NAME$." - ], - "Wet_Bed": [ - "You find that you leaked last night--your bed is all wet!", - "Your bed is cold and wet. You must have wet the bed last night!", - "You wet your bed like a little last night!", - "You wake up uncomfortable, lying in a puddle of cold pee.", - "Your covers are all wet. You need a diaper like a little !", - "Your pajamas are uncomfortable and wet. You realize you wet the bed last night!" - ], - "Messed_Bed": [ - "Starting to cry, you realize that you pooped< and peed> the bed like a baby!", - "Somebody needs a diaper! You messed your bed last night!", - "Your cheeks burn when you discover that your bed is all poopy!", - "You are humiliated to realize that you pooped< and peed> in your bed while you were sleeping!", - "Your poop overflowed into your bed last night!", - "You realize you must have messed your bed last night! Oh no!", - "You smell something stinky and realize you messed the bed last night!" - ], - "Spot_Washing_Bedding": [ - "You take your bedding to the river and rinse the part, but it was tiring and your bedding probably won't be dry until $BEDDING_DRYTIME$." - ], - "Washing_Bedding": [ - "You take your bedding to the river and wash it, but it was exhausting and your bedding probably won't be dry until $BEDDING_DRYTIME$." - ], - "Washing_Underwear": [ - "You wash your $UNDERWEAR_NAME$ in the water. will be dry tomorrow." - ], - "Overwashed_Underwear": [ - "You wash your $UNDERWEAR_NAME$ in the water. too worn out and fell apart!" - ], - "Bedding_Still_Wet": [ - "Your bedding won't be dry until $BEDDING_DRYTIME$!" - ], - "Cant_Remove": [ - "You try to pull down your $UNDERWEAR_NAME$, but you can't get it off without ruining it. Maybe you should change into something else? Or you could just use it..." - ], - "Pee_Overflow": [ - "Your $UNDERWEAR_NAME$ leaked! Your pants are all wet!", - "You start crying as you feel pee dribbling down your legs!", - "You turn red as you realize your pee is running down your legs!", - "You notice a wet spot on your $PANTS_NAME$ and realize your $UNDERWEAR_NAME$ leaked!", - "Your $UNDERWEAR_NAME$ couldn't hold the pee and it leaked out into your $PANTS_NAME$!", - "Your $UNDERWEAR_NAME$ overflowing! You're leaking into your pants." - ], - "Poop_Overflow": [ - "Your $UNDERWEAR_NAME$ blew out! Your pants are all poopy!", - "Turning bright red, you realize your pants are all messy now!", - "Your cheeks burn with shame when you discover your poop overflowed out into your $PANTS_NAME$.", - "You smell something really stinky and realize your poop overflowed into your $PANTS_NAME$!", - "You start crying as you feel a big log of poop squish out past your $UNDERWEAR_NAME$ and smear down your legs!", - "Oh no! Your $UNDERWEAR_NAME$ couldn't hold the poop and it came out into your $PANTS_NAME$!" - ], - "Debuff_Wet_Pants": [ - "Your pants are wet!", - "You wet your pants!", - "You peed your pants!" - ], - "Debuff_Messy_Pants": [ - "Your pants are messy!", - "Your pants are poopy!", - "You messed your pants!" - ], - "Villager_Reactions": { - "adult": { - "soiled_verynice": [ - "Aww, do you need me to change you out of your $UNDERWEAR_NAME$?", - "I think little $FARMERNAME$ needs diaper changed!", - "I know a little farmer who needs diaper changed!$1" - ], - "soiled_nice": [ - "You poor thing! Did you just yourself?", - "Does someone need a diaper change?" - ], - "soiled_mean": [ - "You <&really >might want to go change your pants." - ], - "ground": [ - "$FARMERNAME$! Living in the country doesn't make us barbarians!$3", - "That's not okay! Use a toilet!$3" - ], - "ground_attempt": [ - "$FARMERNAME$! What are you doing!$3" - ] - }, - "teen": { - "soiled_verynice": [ - "Awww, you're so cute when you're embarrassed!$1", - "Where's your Mommy $FARMERNAME$? I think you need a change." - ], - "soiled_nice": [ - "Did you just yourself $FARMERNAME$?", - "Just letting you know $FARMERNAME$, you should probably change your diaper soon." - ], - "soiled_mean": [ - "...$5", - "...Did you just...$2" - ], - "ground": [ - "Eww. Is that normal in the city?$5", - "What... Ugh!$5", - "Did you just on the ground? Gross!$5" - ], - "ground_attempt": [ - "What... Put your pants back on!$5" - ] - }, - "animal": { - "soiled_nice": [ - "...", - "???" - ], - "ground": [ - "<...&!!!>" - ], - "ground_attempt": [ - "<...&???>" - ] - }, - "abigail": { - "soiled_verynice": [ - "Want a change? #$b#I could change you, if you want!$h", - "Sometimes I just put on a diaper and sit around playing games all day. #$b#Maybe we could do that together sometime.$h", - "I think I'm pretty wet. #$b#Would you mind helping me change?", - "Let me help with that! Lay down for me.$h", - "Ewww, I think.... I think I pooped myself.$s #$b#...$s #$b#Could you... maybe change me?" - ], - "soiled_nice": [ - "$lWas that me? ...Oh! Nothing! Haha!", - "So, do you have a medical condition or something?", - "You might wanna change. Just incase someone else says something.", - "$lI might be into trying that diaper thing sometime.", - "Is changing too much of a chore? Sorry, rude question!", - "$l*Checks self quickly* Oh! Were you watching?!" - ], - "soiled_mean": [ - "I'm just..nevermind.", - "This is pretty awkward.", - "...Wow. Walking away now.", - "*Feels own backside quickly* Eww! That's gross! You shouldn't do that in public!", - "I thought only babies their pants! Grow up!", - "Did you just your pants? You need diapers!" - ] - }, - "haley": { - "soiled_verynice": [ - "$lI'm really glad you've gotten me into this whole diaper thing!", - "$hLooks like $UNDERWEAR_NAME$ a little now! How about a changing?", - "$sI think my diaper's starting to sag. Can you give me a hand?" - ], - "soiled_nice": [ - "$l $UNDERWEAR_NAME$ kind of cute. Where can I get ?", - "$hI think you might be leaking a little!" - ], - "soiled_mean": [ - "$uDiapers are NOT in fashion, and neither is your pants like a baby!", - "$uLike, eww. Why is everyone in this town so gross?!", - "$uI was gonna tell you to change your clothes because of how unstylish they are, but it looks like you need your diaper changed more, you big baby!" - ] - }, - "jodi": { - "soiled_verynice": [ - "%Jodi leans down to put a comforting hand on your back.#$b#You can tell me if you had a little accident $FARMERNAME$. It's nothing to be ashamed of.", - "You don't need to rush potty training if you're not ready yet.", - "It can be hard for little to remember to go potty sometimes. It's okay.", - "Oh goodness!$1", - "Awww, you're so cute when you're embarrassed!$1" - ], - "soiled_nice": [ - "$FARMERNAME$, I think you might need to go change.", - "You poor thing! Did you just yourself?" - ], - "soiled_mean": [ - "You might need to tap into those supplies I left you$4" - ] - }, - "sam": { - "soiled_verynice": [ - "#$p 102#Oh man, that was pretty hard to miss!$1|Man, you're just like Vincent.$1", - "Are you okay buddy?#$b#$y 'Do you want some help with that?_Yes please._Alright, go get a change and lie down for me. I'll clean you right up$3_Not yet!_Looks like the little wants to stay a bit longer!$1'", - "It's okay $FARMERNAME$. Accidents are nothing to be ashamed of.", - "Awwww, look at you go! That must have felt good.$4", - "Oh man, that was pretty hard to miss!$1", - "Good one!$1", - "Man, you're such a little baby sometimes.#$b#%Sam giggles a bit as he pats your squishy bottom.", - "Awww, did the little farmer have a little accident?", - "I bet I could get Mommy to go change you.$3#$b#I'm kidding I'm kidding!$1", - "Man, it looks like you really need diapers, don't you.", - "Oh wow, you really yourself!#$b#$y 'Can I feel it?_Yes._%Sam blushes as he presses his hand into your squishy diaper._No thank you._Okay, I won't.'" - ], - "soiled_nice": [ - "You might wanna change. Just incase someone else says something.$7", - "A-are you okay?$8", - "%Sam just blushes a as you yourself. You take note of how closely he watches the whole scene.", - "Oh man, I'm sorry. That can't feel good." - ], - "soiled_mean": [ - "I'm just..nevermind.$5", - "This is pretty awkward.$2", - "...Oh$2", - "You might want to take care of that...", - "#$p 102#You might want to take care of that...|Great, more potty issues to be witness to. Thanks.$5" - ] - }, - "penny": { - "soiled_verynice": [ - "$FARMERNAME$! You're your $UNDERWEAR_NAME$!$5#$b#Why didn't you tell me you needed the potty?$3#$b#*Sigh* It's okay, we can try again next time.", - "%Penny watches you with an eyebrow raised.#$b#Is there something you want to tell me @?$3", - "%Penny waits until you're all finished before tugging your waistband for a check.#$b#Looks like you didn't save anything for the potty little .$1", - "%You tug on Penny's sleeve for help to go potty right before your $UNDERWEAR_NAME$.#$b#Oh no you were so close!$3#$b#I'm not mad, I know you're trying. You'll get the hang of it really soon.", - "Did you have an accident in your $UNDERWEAR_NAME$ $FARMERNAME$?#$b#You have to tell me as soon as your body says you have to go potty, okay?$3", - "#$p 102#Did you have an accident in your $UNDERWEAR_NAME$ $FARMERNAME$?|You have the same potty face as Vincent.$1#$b#Do you need help getting changed like him too?#$b#%Penny tickles your tummy teasingly.", - "I saw that.$3#$b#$y 'Was that REALLY an accident?_Uh huh, I tried to hold it._Oh $FARMERNAME$, I know it's hard for you. I'm very proud of you for trying._I didn't wanna use the potty._$FARMERNAME$, I know it's hard for you, but you still have to try, okay?$3'", - "We're supposed to do that on the potty $FARMERNAME$. What happened?$3#$b#It's okay, I'm not angry. You're trying really hard. It's okay if you still have accidents sometimes.#$b# are easy to clean!$1" - ], - "soiled_nice": [ - "You might wanna change. Just incase someone else says something.", - "A-are you okay?$3", - "Do you need help making it to the potty?", - "I'm sorry. That can't feel good.$3" - ], - "soiled_mean": [ - "...$5", - "Uhmm...$2", - "...Oh$2", - "#$p 102#D-did you...|You too?$5" - ] - }, - "gus": { - "soiled_verynice": [ - "Couldn’t quite make it? That’s okay. Ain’t the worst mess I’ve seen ‘round here, trust me.$1", - "Looks like that was a relief, hah!$1", - "Couldn’t hold it any longer, eh?", - "Hoo boy, that’s gonna be a heck of a change.$1", - "That’s it, let it all on out.", - "Wow, you were really with that one.$1", - "Well, at least it feels good to take a load off...#$b#Even if it’s in your pants, yeah?$1", - "You makin’ your own fertilizer there $FARMERNAME$?", - "You got any clean diapers? I always keep some spare in back for ya, just in case, pal.$1#$b#Well, you and anyone else who happens to need one." - ], - "soiled_nice": [ - "You mind takin' care of that please?#$b#Thanks$1", - "When you gotta go I guess!$1", - "Couldn’t quite make it? That's alright, go get cleaned up. The Saloon will still be here when you get back.", - "I hope that smell’s a dirty diaper and not some rotting food in back…" - ], - "soiled_mean": [ - "You mind takin' care of that before it bothers anyone else buddy?$2", - "I have enough to clean up.$3" - ] - }, - "vincent": { - "soiled_verynice": [ - "#$p 102#%Vincent doesn't seem to notice what happened.|Mommy told me big kids are supposed to use the potty. #$b#I don't wanna be a big kid either!$1", - "#$p 102#%Vincent doesn't seem to notice what happened.|%Vincent watches you yourself and giggles.#$b#Good one!$1", - "#$p 102#%Vincent doesn't seem to notice what happened.|%You notice Vincent watching as you yourself.#$b#All better?", - "#$p 102#%Vincent doesn't seem to notice what happened.|%Vincent watches the whole scene curiously and giggles when you look over. #$b# You !$1", - "#$p 102#%Vincent doesn't seem to notice what happened.|If you want I could ask my Mommy to change you.#$b#No?#$b#That's okay, I like being too!$1", - "#$p 102#%Vincent doesn't seem to notice what happened.|$FARMERNAME$'s and I'm still dry!$1#$b#...#$b#Wait...$2" - ], - "soiled_nice": [ - "#$p 102#%Vincent doesn't seem to notice what happened.|Don't cry, Mommy says it's okay to have accidents sometimes.", - "#$p 102#%Vincent doesn't seem to notice what happened.|Don't worry $FARMERNAME$, I still do that too!", - "#$p 102#%Vincent doesn't seem to notice what happened.|Feel all better?", - "#$p 102#%Vincent doesn't seem to notice what happened.|It smells like you need a diaper change!" - ], - "soiled_mean": [ - "#$p 102#%Vincent doesn't seem to notice what happened.|%Vincent saw what happened and snickers at you.", - "#$p 102#%Vincent doesn't seem to notice what happened.|Was that an accident?", - "#$p 102#%Vincent doesn't seem to notice what happened.|Ha! Gross!$1", - "#$p 102#%Vincent doesn't seem to notice what happened.|$FARMERNAME$ just !$1", - "#$p 102#%Vincent doesn't seem to notice what happened.|Hah! I just watched you yourself!$1" - ], - "ground": [ - "#$p 102#%Vincent doesn't seem to notice what happened.|Ewww!$3", - "Ewww! Don't there!$3", - "#$p 102#%Vincent doesn't seem to notice what happened.|Hey everyone! $FARMERNAME$ just on the ground!$1" - ], - "ground_attempt": [ - "#$p 102#%Vincent doesn't seem to notice what happened.|Eww! Why are you trying to on on the ground?$3" - ] - }, - "jas": { - "soiled_verynice": [ - "#$p 102#%Jas doesn't seem to notice what happened.|Don't cry, it's okay for little s to have accidents sometimes.", - "#$p 102#%Jas doesn't seem to notice what happened.|Oh no, did you have an accident? That's okay, you can try again next time.", - "#$p 102#%Jas doesn't seem to notice what happened.|It's okay, I won't tell anyone you had an accident $FARMERNAME$", - "#$p 102#%Jas doesn't seem to notice what happened.|It's okay $FARMERNAME$, I still have accidents too.$1", - "#$p 102#%Jas doesn't seem to notice what happened.|I can see you waddling!$4", - "#$p 102#%Jas doesn't seem to notice what happened.|Did you have an accident? It's okay, once you're all clean you'll feel all better." - ], - "soiled_nice": [ - "#$p 102#%Jas doesn't seem to notice what happened.|*Giggles* Uh oh!$1", - "#$p 102#%Jas doesn't seem to notice what happened.|You're supposed to do that on the potty you know.$4", - "#$p 102#%Jas doesn't seem to notice what happened.|Do you need me to get Aunt Marnie? She always helps me when I have an accident.$3" - ], - "soiled_mean": [ - "#$p 102#%Jas doesn't seem to notice what happened.|Oh... gross...$3", - "#$p 102#%Jas doesn't seem to notice what happened.|Ewww$3", - "#$p 102#%Jas doesn't seem to notice what happened.|...$2" - ], - "ground": [ - "#$p 102#%Jas doesn't seem to notice what happened.|Ewww!$3", - "Ewww! Don't there!$3", - "#$p 102#%Jas doesn't seem to notice what happened.|...$2" - ], - "ground_attempt": [ - "#$p 102#%Jas doesn't seem to notice what happened.|Eww! Why are you trying to on on the ground?$3" - ] - } - }, + "Jodi_Initial_Letter": [ "Dear @,^Welcome to town! Here some snacks to tide you over while you move in. Your grandpa told me about your little problem, so I enclosed some supplies for you. Visit Pierre if you run out!^ <, Jodi" ], + "Food_Low": [ + "You're hungry.", + "Your stomach rumbles.", + "You're thinking about eating food.", + "You think about finding food.", + "You need some food." + ], + "Food_None": [ + "You're starving!", + "All you can think about is food! Better eat!", + "You're so hungry you can't think straight!" + ], + "Water_Low": [ + "You're getting pretty thirsty.", + "You could really use some water.", + "You're thinking about getting a drink.", + "You need a drink." + ], + "Water_None": [ + "You're dehydrated!", + "You're super thirsty! Get a drink right now!", + "You're so thirsty you can't think straight!" + ], + "Drink_Water_Source": [ + "You scoop up some water in a cup and drain it down." + ], + "Bladder_Green": [ + "You don't feel like you need to pee.", + "You're pretty sure your bladder is mostly empty." + ], + "Bladder_Yellow": [ + "You need to pee soon.", + "You should find somewhere to pee soon.", + "You feel like you might pee soon.", + "Your bladder is slowly getting full." + ], + "Bladder_Orange": [ + "You really need to pee!", + "You're not sure how much longer you can hold your pee!", + "If you don't pee soon, you'll have an accident!", + "You start crossing your legs trying not to pee yourself!" + ], + "Bladder_Red": [ + "You can’t hold it anymore! You're about to pee yourself!", + "You have to pee so badly you start hopping around!" + ], + "Bladder_Leak": [ + "You feel a little pee drip in your $UNDERWEAR_NAME$!", + "You feel a few drops of pee leak out into your $UNDERWEAR_NAME$!", + "While hopping around, trying not to pee yourself, a little escapes into your $UNDERWEAR_NAME$!", + "While crossing your legs, you wee your $UNDERWEAR_NAME$ a little!", + "Your $UNDERWEAR_NAME$ gets a little wet while you try to hold it a little longer!" + ], + "Bowels_Green": [ + "You don't feel like you need to poop.", + "You're pretty sure you can hold your poop for a while." + ], + "Bowels_Yellow": [ + "You need to poop.", + "You should find somewhere to poop soon.", + "You feel a rumble in your bowels.", + "It might be time to poop." + ], + "Bowels_Orange": [ + "You really need to poop!", + "If you don't find a place to poop soon, you'll mess yourself!", + "You're not sure how much longer you can hold your poop!" + ], + "Bowels_Red": [ + "You can feel the poop starting to push out!", + "You can’t hold it anymore! You're about to mess yourself!" + ], + "Bowels_Leak": [ + "Some poop slowly escapes your control, soiling your $UNDERWEAR_NAME$!", + "A little poop stains your $UNDERWEAR_NAME$!", + "While trying to hold it, you soil your $UNDERWEAR_NAME$ a little!", + "While trying your best to hold it, your $UNDERWEAR_NAME$ get a little messy!" + ], + "Bladder_Continence_Green": [ "You're pretty good at holding your pee." ], + "Bladder_Continence_Yellow": [ "You can mostly hold your pee it. Mostly." ], + "Bladder_Continence_Orange": [ "You're pretty bad at holding your pee." ], + "Bladder_Continence_Red": [ "You're close to being unable to hold your pee." ], + "Bladder_Continence_Min": [ "You're almost totally unable to hold your pee." ], + "Bowel_Continence_Green": [ "You pretty good at holding your poop." ], + "Bowel_Continence_Yellow": [ "You can hold you poop most of the time." ], + "Bowel_Continence_Orange": [ "You're pretty bad at holding your poop." ], + "Bowel_Continence_Red": [ "You're getting close to being unable to hold your poop." ], + "Bowel_Continence_Min": [ "You're almost totally unable to hold your poop." ], + "Pee_Voluntary": [ + "You drop your $UNDERWEAR_NAME$ and pee on the ground.", + "Moving your $UNDERWEAR_NAME$, you take a deep breath and empty your bladder.", + "Looking around sheepishly, you pull your $UNDERWEAR_NAME$ down and go right where you are!", + "You slide your $PANTS_NAME$ to your knees and let your pee splatter all over the ground.", + "You pull down your $PANTS_NAME$ and sprinkle on the ground.", + "You pull your $PANTS_NAME$ down and go on the ground.", + "You slide your $PANTS_NAME$ down, , and empty your bladder." + ], + "Poop_Voluntary": [ + "You slide your $PANTS_NAME$ down, squat, and empty your bowels.", + "Looking around nervously, you pull your $PANTS_NAME$ down and go number two right on the ground!", + "Undressing, you squat and let your poop pile out onto the ground.", + "You pull down your $PANTS_NAME$ and poop on the ground.", + "You slide your $PANTS_NAME$ to your knees, squat down, and gently push all your poop out." + ], + "Pee_Toilet": [ + "Sprinkling into the toilet, you breathe a sigh of relief.", + "You pee in the potty like a big .", + "You slide your $PANTS_NAME$ down, , and pee like a big .", + "You barely make it to the toilet. Any longer and you might have wet yourself!", + "You wee in the toilet. Good thing you were able to hold it until then!", + "You proudly pee in the toilet. Now you won't need a diaper!", + "You tinkle in the toilet. Your Mommy would be proud!", + "You undress and go number one in the toilet like a good ." + ], + "Poop_Toilet": [ + "As your poop slides out into the toilet, you start to relax. Whew, that felt good!", + "You slide your $PANTS_NAME$ to your knees, sit on the toilet, and poop like a big .", + "You poop in the potty like a big .", + "You poop in the toilet. Maybe now you won't mess yourself today!", + "You slide your $PANTS_NAME$ to your knees and poop in the toilet.", + "You proudly poop in the toilet. Now you won't need a diaper!", + "You poop in the toilet. Your Mommy would be proud!", + "You undress and go number two in the toilet like a good ." + ], + "Pee_Toilet_Attempt": [ + "You try to pee in the potty like a big , but nothing comes out.", + "You slide your $PANTS_NAME$ down, , and try to pee, but you can't." + ], + "Poop_Toilet_Attempt": [ + "You squirm a little as you try to poop in the toilet, but nothing comes out.", + "You try to poop in the potty like a big , but you can't.", + "You slide your $PANTS_NAME$ to your knees, sit on the toilet, and strain to poop, but nothing comes out." + ], + "Wet_Voluntary": [ + "You relax your bladder and pee gushes into your $UNDERWEAR_NAME$.", + "Your bladder tingles as you let go and warmth spreads out into your $UNDERWEAR_NAME$.", + "You take a deep breath and release your pee into your $UNDERWEAR_NAME$.", + "You glance around a little sheepishly as you deliberately pee your $UNDERWEAR_NAME$ like a little ." + ], + "Mess_Voluntary": [ + "You squat a little and empty your bowels into your $UNDERWEAR_NAME$.", + "You concentrate and push a warm load of poop into your $UNDERWEAR_NAME$.", + "You hope nobody notices as you deliberately let a big poop squeeze out into your $UNDERWEAR_NAME$." + ], + "Pee_Attempt": [ + "You pull down your $PANTS_NAME$ and relax your bladder, but nothing comes out.", + "You slide your $PANTS_NAME$ down, , and try to pee, but you can't." + ], + "Poop_Attempt": [ + "You pull down your $PANTS_NAME$ and try to poop, but you can't.", + "You slide your $PANTS_NAME$ to your knees, squat down, and strain to poop, but nothing comes out." + ], + "Wet_Attempt": [ + "You relax your bladder, but nothing comes out.", + "You try to pee in your $UNDERWEAR_NAME$, but you can't." + ], + "Mess_Attempt": [ + "You squat a little and strain, but nothing comes out.", + "You try to mess in your $UNDERWEAR_NAME$, but you can't." + ], + "Still_Soiled": [ + "You feel your $UNDERWEAR_LONGDESC$ and blush at the sensation.", + "You feel like a little knowing that you're still in $UNDERWEAR_LONGDESC$.", + "You blush and smile warmly realizing you're wearing $UNDERWEAR_LONGDESC$.", + "You smell something stinky and your heart flutters as you realize you're still wearing $UNDERWEAR_LONGDESC$.", + "You feel your $UNDERWEAR_LONGDESC$ squishing between your legs and smile to yourself.", + "You notice your sagging $UNDERWEAR_LONGDESC$ snug and warm.", + "You notice you're waddling because your $UNDERWEAR_LONGDESC$", + "You consider changing your $UNDERWEAR_LONGDESC$", + "You press your hand into your squishy $UNDERWEAR_LONGDESC$. You feel like a little baby in .", + "You feel your $UNDERWEAR_LONGDESC$. all squishy!" + ], + "Should_Change": [ + "You feel your $UNDERWEAR_LONGDESC$ and realize you should really get changed!", + "Your $UNDERWEAR_LONGDESC$ very heavy. Changie time!", + "Feeling your $UNDERWEAR_LONGDESC$ sagging, you think it's probably time for a diaper change!" + ], + "Wet_Accident": [ + "You bite your lip and take a sharp breath through your nose as your bladder gives in and you flood your $UNDERWEAR_NAME$.", + "You're helpless as pee streams into your $UNDERWEAR_NAME$.", + "You hope no one notices the pee pouring into your $UNDERWEAR_NAME$.", + "Your thumb finds its way into your mouth as you suddenly feel warmth spreading into your $UNDERWEAR_NAME$!", + "You hope your $UNDERWEAR_NAME$ doesn't leak as you realize you're wetting yourself.", + "You stop in your tracks as you start to go in your $UNDERWEAR_NAME$!", + "You give a sheepish smile as you realize the warmth spreading into your crotch is pee!", + "You when you realize you're suddenly wetting yourself!", + "With a faint hiss, warmth floods into your $UNDERWEAR_NAME$!", + "You press your hands to your crotch, feeling the warmth as the sudden flood of pee comes rushing out.", + "You're wetting your $UNDERWEAR_NAME$ like a little !", + "You give up trying to hold it any longer and your pee gushes out, flooding your $UNDERWEAR_NAME$.", + "You can't help but relax and let your pee spurt into your $UNDERWEAR_NAME$", + "Oopsies! You're wetting yourself!", + "You're wetting your $UNDERWEAR_NAME$! Oh well.", + "You notice a growing warmth before glancing down and realizing you're peeing in your $UNDERWEAR_NAME$!", + "Your $UNDERWEAR_NAME$ as you wet yourself. Your cheeks flush as you realize you're just a little ." + ], + "Mess_Accident": [ + "Your knees bend and your body bushes on its own as you find yourself pushing a warm load into your $UNDERWEAR_NAME$.", + "You realize you're suddenly filling the back of your $UNDERWEAR_NAME$! You heft your seat with a slight blush as your warm, soft muck squishes against you.", + "You sigh with relief and grin bashfully as the distinctive smell of poop begins to waft from your $UNDERWEAR_NAME$.", + "You bashfully cover your face as you fill your $UNDERWEAR_NAME$ with warm poop. After you're done, you realize your thumb found it's way into your mouth", + "With a faint crackling sound, your poop squeezes out into your $UNDERWEAR_NAME$.", + "You start squirming and push a heavy load of poop into your $UNDERWEAR_NAME$.", + "You're almost startled as you notice it. You're pooping yourself!", + "You don't want to hold your poop any more and release it into your $UNDERWEAR_NAME$.", + "You finally give in, and a heavy load of warm poop pushes into your $UNDERWEAR_NAME$.", + "You freeze up and look around sheepishly as your poop squishes out into your $UNDERWEAR_NAME$.", + "You're pooping in your pants!", + "You feel a warm mass spreading into your $UNDERWEAR_NAME$ and feel like a little .", + "You push on the back of your $UNDERWEAR_NAME$ as , giggling as it squishes around", + "Oopsies! Your $UNDERWEAR_NAME$ all messy now!", + "You don't try and stop it any longer! You're messing yourself!", + "You mess your $UNDERWEAR_NAME$ like a little baby !", + "Your $UNDERWEAR_NAME$ as you openly mess yourself.", + "You give up trying to hold it and sigh in relief as you mess your $UNDERWEAR_NAME$!" + ], + "Diaper_Change_Dialog": [ + "#$q dirty_change_yes/dirty_change_no Diaper_Change_Followup#Do you want to get your $INSPECT_UNDERWEAR_NAME_NO_PREFIX$ changed like a toddler?#$r dirty_change_yes 1 Diaper_Change_Accept#Nod.#$r dirty_change_yes 1 Diaper_Change_Accept#Please?#$r dirty_change_no -1 Diaper_Change_Refuse#Noooo!#$r dirty_change_no 0 Diaper_Change_Refuse#Shake your head." + ], + "Change_Other_Dialog": [ + "#$q change_other_yes/change_other_no Change_Diaper_Followup#Do you help $NPC_NAME$ getting out of $NPC_INSPECT_UNDERWEAR_NAME$?", + "#$q change_other_yes/change_other_no Change_Diaper_Followup#$NPC_NAME$ has $NPC_INSPECT_UNDERWEAR_NAME$ in $NPC_HIS_HER$ $NPC_PANTS_NAME$. Do you change $NPC_HIM_HER$?" + ], + "Night": { + "Toilet_Night": [ + "You had to last night and made it $TOILET_TIMES_TOTAL to the toilet", + "You woke up $TOILET_ONCE_TWICE_TOTAL to in the potty like a big last night", + "You had to get up $TOILET_TIMES_TOTAL to at night" + ], + "Sleep_All_Night": [ + "You didn't wake up once this night", + "You slept like a baby", + "You dreamt of making it to the potty at night", + "In your dreams you fought the potty monster", + "Not once you felt the need to get up tonight" + ], + "Accident_At_Night": [ + "you yourself $ACCIDENT_TIMES_MULTIPLE_TOTALlike a toddler", + "you yourself $ACCIDENT_TIMES_MULTIPLE_TOTALlike the little bed you are" + ], + "Underwear_Stuck": [ + "but you felt protected in your $UNDERWEAR_NAME$", + "but you didn't want to rip off your $UNDERWEAR_NAME$" + ] + }, - "Change": [ - "You change into $PANTS_PREFIX$ clean $PANTS_NAME$ and $INSPECT_UNDERWEAR_NAME$." - //***"You take off your soiled and put on $UNDERWEAR_PREFIX$ clean $UNDERWEAR_NAME$." - ], - "Change_Destroyed": [ - "You ruined your $UNDERWEAR_NAME$ when taking off. So you throw away." - ], - "Change_Requires_Pants": [ - "You don't have another pair of $PANTS_NAME$ here to change into. You probably need to go home first." - ], - "PeekWaistband": [ - "You peek inside your waistband and see" - ], - "LookPants": [ - "You look down and see" - ], - "Underwear_Clean": "clean $UNDERWEAR_DESC$", - "Underwear_Drying": "drying $UNDERWEAR_DESC$", - "Underwear_Wet": [ //Chosen based on diaper wetness, applied after Underwear_Messy. Words in brackets only show if underwear is also messy. - "slightly damp $UNDERWEAR_DESC$", - "somewhat wet $UNDERWEAR_DESC$", - "very wet $UNDERWEAR_DESC$", - "drenched $UNDERWEAR_DESC$", - "dripping wet $UNDERWEAR_DESC$" - ], - "Underwear_Messy": [ //Chosen based on diaper messiness, applied before Underwear_Wet. Words in brackets are only used if underwear is also wet. - "slightly poopy $UNDERWEAR_DESC$", - "somewhat poopy $UNDERWEAR_DESC$", - "poopy $UNDERWEAR_DESC$", - "$UNDERWEAR_DESC$ filled with poop", - "$UNDERWEAR_DESC$ with poop squishing out" - ], - "Consumables": { - // - //Working on creating entries for every consumable. - //Water values are arbitrary, but should be accurate to each other relatively. Poisons mean vomitting, indigestion, and other issues, therefore poisonous items cause a loss to calories and water. - // - //Crops - //With a lot of these, I looked up the calorie count for an average size or average amount for small items like berries, then rounded out the numbers. For balance, some really small numbers are unnaturally high. For grains, I went with half a cup of grains. All items are assumed to undergo basic cooking if necesary to make edible, such as with potatoes. - // - //Veggies - // - "Amaranth": { - "name": "Amaranth", - "waterContent": 0, - "calorieContent": 350 //Half cup Amaranth, made as simple bread or cooked directly like rice - }, - "Artichoke": { - "name": "Artichoke", - "waterContent": 200, - "calorieContent": 150 //Two large artichokes, raw - }, - "Beet": { - "name": "Beet", - "waterContent": 25, - "calorieContent": 140 //Four beets, raw - }, - "Bok Choy": { - "name": "Bok Choy", - "waterContent": 75, - "calorieContent": 110 //One head of bok choy, raw - }, - "Corn": { - "name": "Corn", - "waterContent": 25, - "calorieContent": 190 //One large ear of sweet corn, simply cooked - }, - "Eggplant": { - "name": "Eggplant", - "waterContent": 50, - "calorieContent": 150 //One large Eggplant, simply cooked - }, - "Fiddlehead Fern": { - "name": "Fiddlehead Fern", - "waterContent": 25, - "calorieContent": 140 //Four fiddleheads, raw - }, - "Garlic": { - "name": "Garlic", - "waterContent": 25, - "calorieContent": 50 //One large head of garlic, raw - }, - "Green Bean": { - "name": "Green Bean", - "waterContent": 25, - "calorieContent": 160 //Four large greenbeans, raw or simply cooked - }, - "Hops": { - "name": "Hops", - "waterContent": 25, - "calorieContent": 350 //Half cup of hops, can't find a calorie count since people don't actually eat hops, so just using Amaranth's - }, - "Kale": { - "name": "Kale", - "waterContent": 25, - "calorieContent": 100 //Enough kale leaves to match a head of lettuce, raw - }, - "Parsnip": { - "name": "Parsnip", - "waterContent": 25, - "calorieContent": 150 //Two parsnips, raw - }, - "Potato": { - "name": "Potato", - "waterContent": 25, - "calorieContent": 180 //One large potato, 'baked' - }, - "Radish": { - "name": "Radish", - "waterContent": 25, - "calorieContent": 100 //20 radishes at 5calories each, raw. According to every source I can find, a one inch wide radish only contains 1.9 calories. This doesn't seem right, so I bumped it up. - }, - "Red Cabbage": { - "name": "Red Cabbage", - "waterContent": 75, - "calorieContent": 350 //One large head of red cabbage, raw - }, - "Taro Root": { - "name": "Taro Root", - "waterContent": 50, - "calorieContent": 500 //One small taro root (1pound), cooked simply. IRL, Normal taro root, harvested after 8-10 months, is 2-4 pounds. - }, - "Tomato": { - "name": "Tomato", - "waterContent": 100, - "calorieContent": 140 //Four large tomatoes, raw - }, - "Unmill Rice": { - "name": "Unmill Rice", - "waterContent": 25, - "calorieContent": 350 //Half cup, cooked simply - }, - "Yam": { - "name": "Yam", - "waterContent": 25, - "calorieContent": 180 //One Large yam, cooked simply - }, - // - //Fruit - // - "Apple": { - "name": "Apple", - "waterContent": 100, - "calorieContent": 120 //One large apple, raw - }, - "Apricot": { - "name": "Apricot", - "waterContent": 100, - "calorieContent": 100 //Four apricots, raw - }, - "Banana": { - "name": "Banana", - "waterContent": 50, - "calorieContent": 130 //One large banana, raw - }, - "Blackberry": { - "name": "Blackberry", - "waterContent": 50, - "calorieContent": 140 //Two cups of blackberries, raw - }, - "Blueberry": { - "name": "Blueberry", - "waterContent": 50, - "calorieContent": 170 //Two cups of blueberries, raw - }, - "Cactus Fruit": { - "name": "Cactus Fruit", - "waterContent": 100, - "calorieContent": 120 //Two large fruits, raw - }, - "Cherry": { - "name": "Cherry", - "waterContent": 50, - "calorieContent": 150 //Two cups of cherries, raw - }, - "Cranberries": { - "name": "Cranberries", - "waterContent": 50, - "calorieContent": 100 //Two cups of cranberries, raw - }, - "Crystal Fruit": { - "name": "Crystal Fruit", - "waterContent": 150, - "calorieContent": 350 //One large crystal fruit. Fantasy item, so I get to dictate it. >:3 - }, - "Grape": { - "name": "Grape", - "waterContent": 100, - "calorieContent": 220 //Two cups of grapes, raw - }, - "Hot Pepper": { - "name": "Hot Pepper", - "waterContent": -500, - "calorieContent": 100 //Four cups of Jalapenos to barely make it to 100. Have some water ready. - }, - "Mango": { - "name": "Mango", - "waterContent": 100, - "calorieContent": 135 //One Mango, raw - }, - "Melon": { - "name": "Melon", - "waterContent": 125, - "calorieContent": 500 //One large honeydew melon as reference for the stardew melon, raw - }, - "Orange": { - "name": "Orange", - "waterContent": 100, - "calorieContent": 100 //One large orange, raw - }, - "Peach": { - "name": "Peach", - "waterContent": 100, - "calorieContent": 130 //Two peaches, raw - }, - "Pineapple": { - "name": "Pineapple", - "waterContent": 125, - "calorieContent": 300 //One large pineapple, raw. Your mouth is gonna tingle after eating this. - }, - "Pomegranate": { - "name": "Pomegranate", - "waterContent": 50, - "calorieContent": 130 //One large pomegranate, raw - }, - "Qi Fruit": { - "name": "Qi Fruit", - "waterContent": 500, - "calorieContent": 1000 //Qi Fruit? We get to cultivate now? Well, in the cultivator novels, Qi Fruit tends to be able to 'sustain the martial artist for a week' and such. - }, - "Salmonberry": { - "name": "Salmonberry", - "waterContent": 25, - "calorieContent": 150 //Two cups of salmonberries, raw - }, - "Spice Berry": { - "name": "Spice Berry", - "waterContent": -25, - "calorieContent": 180 //Two cups of spice berries, raw - }, - "Starfruit": { - "name": "Starfruit", - "waterContent": 125, - "calorieContent": 400 //RL starfruits are about 40 calories each; this fruit seems to be quite different from those, though - }, - "Strawberry": { - "name": "Strawberry", - "waterContent": 50, - "calorieContent": 100 //Two cups of strawberries, raw - }, - "Wild Plum": { - "name": "Wild Plum", - "waterContent": 50, - "calorieContent": 120 //Four plums, raw - }, - // - //Flower - // - "Blue Jazz": { - "name": "Blue Jazz", - "waterContent": 25, - "calorieContent": 50 - }, - "Crocus": { - "name": "Crocus", - "waterContent": 25, - "calorieContent": 50 - }, - "Fairy Rose": { - "name": "Fairy Rose", - "waterContent": 25, - "calorieContent": 50 - }, - "Poppy": { - "name": "Poppy", - "waterContent": 25, - "calorieContent": 50 - }, - "Summer Spangle": { - "name": "Summer Spangle", - "waterContent": 25, - "calorieContent": 50 - }, - "Sunflower": { - "name": "Sunflower", - "waterContent": 25, - "calorieContent": 200 //Sunflower seeds are boosting this over other flowers - }, - "Sweet Pea": { - "name": "Sweet Pea", - "waterContent": 25, - "calorieContent": 50 - }, - "Tulip": { - "name": "Tulip", - "waterContent": 25, - "calorieContent": 50 - }, - // - //Forage - // - "Cave Carrot": { - "name": "Cave Carrot", - "waterContent": 25, - "calorieContent": 120 //Four large carrots, raw - }, - "Chanterelle": { - "name": "Chanterelle", - "waterContent": 25, - "calorieContent": 50 //Two cups of chanterelle. These things are worse than kale for calories... - }, - "Common Mushroom": { - "name": "Common Mushroom", - "waterContent": 25, - "calorieContent": 100 //Two cups of Shiitake, raw - }, - "Daffodil": { - "name": "Daffodil", - "waterContent": 25, - "calorieContent": 50 - }, - "Dandelion": { - "name": "Dandelion", - "waterContent": 25, - "calorieContent": 60 - }, - "Ginger": { - "name": "Ginger", - "waterContent": -250, //IIRC, straight ginger root causes burning sensations on mucous membranes, like the throat, so let's up the demand for water a little.... - "calorieContent": 80 //One cup ginger root, raw - }, - "Hazelnut": { - "name": "Hazelnut", - "waterContent": 0, - "calorieContent": 425 //Half cup of Hazelnuts. They're also called filberts, lol. - }, - "Holly": { - "name": "Holly", //Don't eat Holly, it's poisonous. - "waterContent": -1500, - "calorieContent": -1250 - }, - "Leek": { - "name": "Leek", //Must... Not... Spin... - "waterContent": 25, - "calorieContent": 110 //Two leeks, raw - }, - "Magma Cap": { - "name": "Magma Cap", - "waterContent": -1500, - "calorieContent": 1500 //With all the energy it's absorbed, there's plenty for you to use... Assuming you can quench your newfound thirst. - }, - "Morel": { - "name": "Morel", - "waterContent": 25, - "calorieContent": 40 //Two cups of morels. And I thought the chanterelles were bad... - }, - "Purple Mushroom": { - "name": "Purple Mushroom", - "waterContent": 25, - "calorieContent": 750 //Half of magmacap - }, - "Red Mushroom": { - "name": "Red Mushroom", //Don't eat this toadstool, unless you want to turn into a tanuki! - "waterContent": -500, - "calorieContent": -1000 - }, - "Sap": { - "name": "Sap", //....Why can we eat this? Why would we want to eat this? At least the mushrooms and holly make since, because 'mistaken identity'. What edible thing are you mistaking tree sap as? - "waterContent": -200, - "calorieContent": -100 - }, - "Snow Yam": { - "name": "Snow Yam", - "waterContent": 25, - "calorieContent": 180 //One Large yam, cooked simply - }, - "Spring Onion": { - "name": "Spring Onion", - "waterContent": 25, - "calorieContent": 800 //One hundred large scallions, only because this is the "starter" food - }, - "Wild Horseradish": { - "name": "Wild Horseradish", - "waterContent": -250, //This is wasabi's crappy tasting cousin, but the spice is still there. Corrected to -250 from -2500 - "calorieContent": 115 //One cup of raw horseradish, about the size of a normal prepared root. - }, - "Winter Root": { - "name": "Winter Root", - "waterContent": 25, - "calorieContent": 300 //Since Winter Root is a tuber, I just picked a random one. Winged bean tuber it is! Half cup sized tubers. - }, - // - //Animal Drops - // - "Duck Egg": { - "name": "Duck Egg", - "waterContent": 50, - "calorieContent": 80 //One 'USDA medium' egg - }, - "Egg": { - "name": "Egg", - "waterContent": 50, - "calorieContent": 80 //One 'USDA medium' egg - }, - "Goat Milk": { - "name": "Goat Milk", - "waterContent": 470, //16oz ~ 490mL. Did rounding because the numbers don't have to be perfectly accurate. - "calorieContent": 340 //16oz of goat milk - }, - "Golden Egg": { - "name": "Golden Egg", - "waterContent": 50, - "calorieContent": 360 //One 'USDA medium' gold flake lined egg - }, - "L. Goat Milk": { - "name": "L. Goat Milk", - "waterContent": 3785, //Description is a gallon of milk; 1 gallon = 3785mL - "calorieContent": 2700 //It's a gallon of milk, lots of calories.... Plus side, the babs can actually live off milk. - }, - "Large Egg": { - "name": "Large Egg", - "waterContent": 75, - "calorieContent": 130 //One 'USDA extra-large' egg - }, - "Large Milk": { - "name": "Large Milk", - "waterContent": 3785, - "calorieContent": 2400 - }, - "Milk": { - "name": "Milk", - "waterContent": 470, - "calorieContent": 300 - }, - "Ostrich Egg": { - "name": "Ostrich Egg", - "waterContent": 200, - "calorieContent": 2000 - }, - "Truffle": { - "name": "Truffle", - "waterContent": 25, - "calorieContent": 70 //One whole, raw truffle. I feel sorry for the poor soul eating this... - }, - "Void Egg": { - "name": "Void Egg", - "waterContent": 50, - "calorieContent": 360 // One 'USDA jumbo' void egg - }, - // - //Cooking - //Will try looking up calorie counts for similar items. The rest will be done by adding ingredient calories and see how it looks. - "Algae Soup": { - "name": "Algae Soup", - "waterContent": 660, - "calorieContent": 760 - }, - "Artichoke Dip": { - "name": "Artichoke Dip", - "waterContent": 200, - "calorieContent": 900 //2cups - }, - "Autumn's Bounty": { - "name": "Autumn's Bounty", //1 whole extra large pumpkin makes about 36cups of cooked pumpkin. 1 cup is about 100 calories. Assuming not oversized pumpkins, 24 cups of cooked pumpkin seems fine. - "waterContent": 0, - "calorieContent": 2580 - }, - "Baked Fish": { - "name": "Baked Fish", - "waterContent": 0, - "calorieContent": 660 - }, - "Banana Pudding": { - "name": "Banana Pudding", - "waterContent": 590, - "calorieContent": 1000 //2cups - }, - "Bean Hotpot": { - "name": "Bean Hotpot", - "waterContent": 0, - "calorieContent": 600 //4cups - }, - "Blackberry Cobbler": { - "name": "Blackberry Cobbler", - "waterContent": 0, - "calorieContent": 2500 //About 4cups filling and one cup crust - }, - "Blueberry Tart": { - "name": "Blueberry Tart", - "waterContent": 0, - "calorieContent": 520 //About 2cups in volume - }, - "Bread": { - "name": "Bread", - "waterContent": 0, - "calorieContent": 900 //Calories in standard baguette - }, - "Bruschetta": { - "name": "Bruschetta", - "waterContent": 0, - "calorieContent": 1200 //Big piece, but it uses an entire loaf of bread, so... - }, - "Cheese Cauliflower": { - "name": "Cheese Cauliflower", - "waterContent": "000", - "calorieContent": 540 //4 cups - }, - "Chocolate Cake": { - "name": "Chocolate Cake", - "waterContent": 250, - "calorieContent": 28800 //A three tier cake with icing would be about 18 pounds(288oz), according to a baker's website. Have fun filling your pamps. - }, - "Chowder": { - "name": "Chowder", - "waterContent": 150, - "calorieContent": 640 //4 cups - }, - "Coleslaw": { - "name": "Coleslaw", - "waterContent": 25, - "calorieContent": 1000 //4 cups - }, - "Complete Breakfast": { - "name": "Complete Breakfast", - "waterContent": 25, - "calorieContent": 1700 - }, - "Cookie": { - "name": "Cookie", - "waterContent": 25, - "calorieContent": 850 //A dozen cookies, because they're so delicious. - }, - "Crab Cakes": { - "name": "Crab Cakes", - "waterContent": 25, - "calorieContent": 880 //8 2in wide 3/4inch tall crab cakes. - }, - "Cranberry Candy": { - "name": "Cranberry Candy", //This item's sprite looks like juice, and is made with apples, so just using cranberry apple juice as reference - "waterContent": 470, - "calorieContent": 320 //16oz - }, - "Cranberry Sauce": { - "name": "Cranberry Sauce", - "waterContent": 25, - "calorieContent": 880 //2 cups - }, - "Crispy Bass": { - "name": "Crispy Bass", //An average bass weighs about five pounds. Roughly 1/3 of the weight of a large fish is good for typical fish meat. That's still a lot of meat to eat in one sitting. - "waterContent": 25, - "calorieContent": 1800 //six fillets on each side, about 150calories per bass fillet at that size - }, - "Dish O' The Sea": { - "name": "Dish O' The Sea", //Canned or not, sardines are still super salty. Eating a pile of straight sardines sounds painful. At least the hashbrowns don't need any extra salt. - "waterContent": -750, - "calorieContent": 750 - }, - "Eggplant Parmesan": { - "name": "Eggplant Parmesan", - "waterContent": 75, - "calorieContent": 1240 //4 cups - }, - "Escargot": { - "name": "Escargot", - "waterContent": 125, - "calorieContent": 520 //16 normal sized escargot snails; just pretending SDV snails are bigger because magic and meteors. lol. - }, - "Farmer's Lunch": { - "name": "Farmer's Lunch", - "waterContent": 75, - "calorieContent": 1500 - }, - "Fiddlehead Risotto": { - "name": "Fiddlehead Risotto", - "waterContent": 120, - "calorieContent": 1360 //2 cups - }, - "Fish Stew": { - "name": "Fish Stew", //Wait... Fish stew literally contains no fish, only only arthropods and mollusks o.o - "waterContent": 280, - "calorieContent": 840 //4 cups - }, - "Fish Taco": { - "name": "Fish Taco", - "waterContent": 120, - "calorieContent": 1600 //One face sized taco, just to make sure calorie count is greater than ingredient sum - }, - "Fried Calamari": { - "name": "Fried Calamari", - "waterContent": 50, - "calorieContent": 800 //"4 cups", I assume not packed - }, - "Fried Eel": { - "name": "Fried Eel", - "waterContent": 150, - "calorieContent": 1300 //4 cups - }, - "Fried Egg": { - "name": "Fried Egg", - "waterContent": 25, - "calorieContent": 160 //Double eggs, because incetivizing processing - }, - "Fried Mushroom": { - "name": "Fried Mushroom", - "waterContent": 50, - "calorieContent": 500 //6cups - }, - "Fruit Salad": { - "name": "Fruit Salad", - "waterContent": 100, - "calorieContent": 880 //8 cups fruit salad; indgredient sum is 770 - }, - "Ginger Ale": { - "name": "Ginger Ale", - "waterContent": 470, - "calorieContent": 160 //16oz - }, - "Glazed Yams": { - "name": "Glazed Yams", - "waterContent": 50, - "calorieContent": 400 //4cups - }, - "Hashbrowns": { - "name": "Hashbrowns", - "waterContent": 50, - "calorieContent": 350 //4cups - }, - "Ice Cream": { - "name": "Ice Cream", - "waterContent": 125, - "calorieContent": 350 //One cone, double scoop - }, - "Life Elixir": { - "name": "Life Elixir", //"Restores health to full." ....Then why do some foods restore more health than this? - "waterContent": 235, //8oz - "calorieContent": 2000 //Delicious, Nutritious, magic world health potions! - }, - "Lobster Bisque": { - "name": "Lobster Bisque", - "waterContent": 250, - "calorieContent": 1100 //4 cup - }, - "Lucky Lunch": { - "name": "Lucky Lunch", //ngl, this recipe is a little off putting to me... Sea cucumber is really slimy, cooked or not, unless it's way overcooked and tastes terrible. - "waterContent": 100, - "calorieContent": 1000 //1 slimy sea cucumber taco - }, - "Magic Rock Candy": { - "name": "Magic Rock Candy", - "waterContent": "000", - "calorieContent": 2500 //Pure, unadulterated magic rainbow sugar crystals. - }, - "Maki Roll": { - "name": "Maki Roll", - "waterContent": 0, - "calorieContent": 800 //4 rolls. - }, - "Mango Sticky Rice": { - "name": "Mango Sticky Rice", - "waterContent": 0, - "calorieContent": 920 //4 cups - }, - "Maple Bar": { - "name": "Maple Bar", //Weird name for a maple donut, but okay. - "waterContent": 0, - "calorieContent": 600 //One doughnut, apparently - }, - "Miner's Treat": { - "name": "Miner's Treat", - "waterContent": 0, - "calorieContent": 1000 //Extra large lollipop, just to stay higher than sum of ingredients - }, - "Oil": { - "name": "Oil", - "waterContent": 0, - "calorieContent": 120 //1 tablespoon. Seriously. - }, - "Oil of Garlic": { - "name": "Oil of Garlic", - "waterContent": 0, - "calorieContent": 125 //1 tablespoon - }, - "Omelet": { - "name": "Omelet", //Can it really be called an omelette without cheese? - "waterContent": 0, - "calorieContent": 450 //4 medium egg omelette - }, - "Pale Broth": { - "name": "Pale Broth", - "waterContent": 660, - "calorieContent": 760 //copy of algae soup - }, - "Pancakes": { - "name": "Pancakes", - "waterContent": 0, - "calorieContent": 400 //4 4inch pancakes - }, - "Parsnip Soup": { - "name": "Parsnip Soup", - "waterContent": 500, - "calorieContent": 640 //4 cups of parsnip cream soup - }, - "Pepper Poppers": { - "name": "Pepper Poppers", - "waterContent": 0, - "calorieContent": 800 //12 poppers - }, - "Piña Colada": { - "name": "Piña Colada", - "waterContent": 235, - "calorieContent": 420 //8oz - }, - "Pink Cake": { - "name": "Pink Cake", - "waterContent": 0, - "calorieContent": 1900 //An entire cake. Fewer calories than I expected, tbh. - }, - "Pizza": { - "name": "Pizza", - "waterContent": 0, - "calorieContent": 1840 //A 12" cheese pizza - }, - "Plum Pudding": { - "name": "Plum Pudding", - "waterContent": 0, - "calorieContent": 1000 //Apparently Plum Puddings are measured in loafs? - }, - "Poi": { - "name": "Poi", - "waterContent": 300, - "calorieContent": 1080 //4 cups - }, - "Poppyseed Muffin": { - "name": "Poppyseed Muffin", - "waterContent": 25, - "calorieContent": 670 //1 muffin - }, - "Pumpkin Pie": { - "name": "Pumpkin Pie", - "waterContent": 50, - "calorieContent": 2500 //1 pie - }, - "Pumpkin Soup": { - "name": "Pumpkin Soup", - "waterContent": 1250, - "calorieContent": 870 //8 cups - }, - "Radish Salad": { - "name": "Radish Salad", - "waterContent": 50, - "calorieContent": 600 - }, - "Red Plate": { - "name": "Red Plate", - "waterContent": 150, - "calorieContent": 600 - }, - "Rhubarb Pie": { - "name": "Rhubarb Pie", - "waterContent": 150, - "calorieContent": 3530 //1 pie. Why is it so much worse than other pies? - }, - "Rice": { - "name": "Rice", - "waterContent": 50, - "calorieContent": 400 //2 cups cooked white rice - }, - "Rice Pudding": { - "name": "Rice Pudding", - "waterContent": 100, - "calorieContent": 1200 //4 cups - }, - "Roasted Hazelnuts": { - "name": "Roasted Hazelnuts", - "waterContent": 50, - "calorieContent": 1440 //1 cup of roasted hazelnuts - }, - "Roots Platter": { - "name": "Roots Platter", - "waterContent": 50, - "calorieContent": 750 - }, - "Salad": { - "name": "Salad", - "waterContent": 50, - "calorieContent": 600 - }, - "Salmon Dinner": { - "name": "Salmon Dinner", - "waterContent": 100, - "calorieContent": 1400 - }, - "Sashimi": { - "name": "Sashimi", - "waterContent": 75, - "calorieContent": 800 - }, - "Seafoam Pudding": { - "name": "Seafoam Pudding", //pudding made from fish and squid ink? I love seafood, but even this seems too much... - "waterContent": 150, - "calorieContent": 1160 //4 cups of generic pudding - }, - "Shrimp Cocktail": { - "name": "Shrimp Cocktail", - "waterContent": 150, - "calorieContent": 550 //Boosted to exceed ingredient sum - }, - "Spaghetti": { - "name": "Spaghetti", - "waterContent": 100, - "calorieContent": 1200 //4 cups - }, - "Spicy Eel": { - "name": "Spicy Eel", - "waterContent": -250, - "calorieContent": 1300 //fried eel copy - }, - "Squid Ink Ravioli": { - "name": "Squid Ink Ravioli", - "waterContent": 100, - "calorieContent": 1200 //4 cups - }, - "Stir Fry": { - "name": "Stir Fry", - "waterContent": 50, - "calorieContent": 800 //4 cups stirfry veggies on rice - }, - "Strange Bun": { - "name": "Strange Bun", //Sea slug and burnt hair mayonaise.... Yum.... - "waterContent": 50, - "calorieContent": 800 - }, - "Stuffing": { - "name": "Stuffing", - "waterContent": 50, - "calorieContent": 1400 //4 cups - }, - "Sugar": { - "name": "Sugar", //Beets UOM is 4 beets per item to get calorie. 1 beet has about 6g sugar, 20 24g per 1 item. Therefore, 8g of sugar per 1 sugar item. - "waterContent": 0, - "calorieContent": 35 - }, - "Super Meal": { - "name": "Super Meal", - "waterContent": 100, - "calorieContent": 560 //4 cups 'super foods salad' - }, - "Survivor Burger": { - "name": "Survivor Burger", - "waterContent": 50, - "calorieContent": 1400 //4 veggie burgers - }, - "Tom Kha Soup": { - "name": "Tom Kha Soup", - "waterContent": 250, - "calorieContent": 1040 //8 cups - }, - "Tortilla": { - "name": "Tortilla", - "waterContent": 25, - "calorieContent": 150 //1 large tortilla, what can be made from 1 large ear of corn - }, - "Triple Shot Espresso": { - "name": "Triple Shot Espresso", - "waterContent": 115, //4 oz - "calorieContent": 0 - }, - "Tropical Curry": { - "name": "Tropical Curry", - "waterContent": 240, - "calorieContent": 960 //4 cups coconut pineapple thai curry - }, - "Trout Soup": { - "name": "Trout Soup", - "waterContent": 240, - "calorieContent": 800 //4 cups - }, - "Vegetable Medley": { - "name": "Vegetable Medley", - "waterContent": 75, - "calorieContent": 550 - }, - "Wheat Flour": { - "name": "Wheat Flour", - "waterContent": 0, - "calorieContent": 400 //half cup - }, - "Cola": { - "name": "Cola", - "waterContent": 240, - "calorieContent": 100 - }, - "Espresso": { - "name": "Espresso", - "waterContent": 44, - "calorieContent": 3 - }, - "Coffee": { - "name": "Coffee", - "waterContent": 240, - "calorieContent": 1 - }, - "Wine": { - "name": "Wine", - "waterContent": 148, - "calorieContent": 123 - }, - "Beer": { - "name": "Beer", - "waterContent": 355, - "calorieContent": 154 - }, - "Tea": { - "name": "Tea", - "waterContent": 240, - "calorieContent": 2 - }, - "Juice": { - "name": "Juice", - "waterContent": 240, - "calorieContent": 114 - } - }, - "Underwear_Options": { - "bed": { - "name": "bed", - "description": "cozy bed", - "absorbency": 2500.0, - "containment": 1000.0, - "spriteIndex": -1, - "price": 0, - "washable": true, - "plural": false, - "dryingTime": 2400, - "removable": false, - "durability": -1 - }, - "blue jeans": { - "name": "blue jeans", - "description": "sturdy blue jeans", - "absorbency": 300.0, - "containment": 60.0, - "spriteIndex": -1, - "price": 2000, - "washable": true, - "plural": true, - "dryingTime": 600, - "removable": true, - "durability": -1 - }, - "black thong": { - "name": "black thong", - "description": "lacy black thong", - "absorbency": 75.0, - "containment": 60.0, - "spriteIndex": 0, - "price": 10, - "washable": true, - "plural": false, - "dryingTime": 300, - "removable": true, - "durability": 4 - }, - "polka dot panties": { - "name": "polka dot panties", - "description": "simple white panties with pink polka dots", - "absorbency": 150.0, - "containment": 100.0, - "spriteIndex": 1, - "price": 10, - "washable": true, - "plural": true, - "dryingTime": 400, - "removable": true, - "durability": 4 - }, - "big kid undies": { - "name": "big kid undies", - "description": "cotton undies for big kids only", - "absorbency": 150.0, - "containment": 115.0, - "spriteIndex": 2, - "price": 10, - "washable": true, - "plural": true, - "dryingTime": 400, - "removable": true, - "durability": 4 - }, - "dinosaur undies": { - "name": "dinosaur undies", - "description": "green undies covered in adorable dinosaurs", - "absorbency": 150.0, - "containment": 115.0, - "spriteIndex": 3, - "price": 10, - "washable": true, - "plural": true, - "dryingTime": 400, - "removable": true, - "durability": 4 - }, - "lavender pullup": { - "name": "lavender pullup", - "description": "soft and snug flowery lavender pullup", - "absorbency": 600.0, - "containment": 170.0, - "spriteIndex": 4, - "price": 25, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": true, - "durability": 0 - }, - "training pants": { - "name": "training pants", - "description": "thin cloth potty training pants that look like big kid undies", - "absorbency": 600.0, - "containment": 120.0, - "spriteIndex": 5, - "price": 25, - "washable": true, - "plural": true, - "dryingTime": 600, - "removable": true, - "durability": 5 - }, - "Joja diaper": { - "name": "Joja diaper", - "description": "thin white plastic diaper from JojaMart", - "absorbency": 1200.0, - "containment": 300.0, - "spriteIndex": 6, - "price": 50, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": false, - "durability": 0 - }, - "baby print diaper": { - "name": "baby print diaper", - "description": "little soft and crinkly fresh-scented baby print diaper. Its a bit small, but you can fit", - "absorbency": 1500.0, - "containment": 1000.0, - "spriteIndex": 7, - "price": 75, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": false, - "durability": 0 - }, - "Cloth diaper": { - "name": "Cloth diaper", - "description": "thick and soft white cloth diaper", - "absorbency": 2000.0, - "containment": 1500.0, - "spriteIndex": 8, - "price": 500, - "washable": true, - "plural": false, - "dryingTime": 800, - "removable": true, - "durability": 8 - }, - "space diaper": { - "name": "space diaper", - "description": "very thick and soft blue plastic diaper with spaceship designs", - "absorbency": 2700.0, - "containment": 2700.0, - "spriteIndex": 9, - "price": 100, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": false, - "durability": 0 - }, - "pawprint diaper": { - "name": "pawprint diaper", - "description": "puffy plastic diaper with cute animal prints and fade-when-wet little paws", - "absorbency": 2700.0, - "containment": 2700.0, - "spriteIndex": 10, - "price": 100, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": false, - "durability": 0 - }, - "heart diaper": { - "name": "heart diaper", - "description": "very thick and soft pink plastic diaper with a large fade-when-wet heart on the front", - "absorbency": 3000.0, - "containment": 3000.0, - "spriteIndex": 11, - "price": 120, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": false, - "durability": 0 - } - } + "Wake_Up_Underwear_State": [ + "You wake up in $INSPECT_UNDERWEAR_NAME$." + ], + "Wet_Bed": [ + "You find that you leaked last night--your bed is all wet!", + "Your bed is cold and wet. You must have wet the bed last night!", + "You wet your bed like a little last night!", + "You wake up uncomfortable, lying in a puddle of cold pee.", + "Your covers are all wet. You need a diaper like a little !", + "Your pajamas are uncomfortable and wet. You realize you wet the bed last night!" + ], + "Messed_Bed": [ + "Starting to cry, you realize that you pooped< and peed> the bed like a baby!", + "Somebody needs a diaper! You messed your bed last night!", + "Your cheeks burn when you discover that your bed is all poopy!", + "You are humiliated to realize that you pooped< and peed> in your bed while you were sleeping!", + "Your poop overflowed into your bed last night!", + "You realize you must have messed your bed last night! Oh no!", + "You smell something stinky and realize you messed the bed last night!" + ], + "Spot_Washing_Bedding": [ + "You take your bedding to the river and rinse the part, but it was tiring and your bedding probably won't be dry until $BEDDING_DRYTIME$." + ], + "Washing_Bedding": [ + "You take your bedding to the river and wash it, but it was exhausting and your bedding probably won't be dry until $BEDDING_DRYTIME$." + ], + "Washing_Underwear": [ + "You wash your $UNDERWEAR_NAME$ in the water. will be dry tomorrow." + ], + "Overwashed_Underwear": [ + "You wash your $UNDERWEAR_NAME$ in the water. too worn out and fell apart!" + ], + "Bedding_Still_Wet": [ + "Your bedding won't be dry until $BEDDING_DRYTIME$!" + ], + "Cant_Remove": [ + "You try to pull down your $UNDERWEAR_NAME$, but you can't get it off without ruining it. Maybe you should change into something else? Or you could just use it..." + ], + "Pee_Overflow": [ + "Your $UNDERWEAR_NAME$ leaked! Your pants are all wet!", + "You start crying as you feel pee dribbling down your legs!", + "You turn red as you realize your pee is running down your legs!", + "You notice a wet spot on your $PANTS_NAME$ and realize your $UNDERWEAR_NAME$ leaked!", + "Your $UNDERWEAR_NAME$ couldn't hold the pee and it leaked out into your $PANTS_NAME$!", + "Your $UNDERWEAR_NAME$ overflowing! You're leaking into your pants." + ], + "Poop_Overflow": [ + "Your $UNDERWEAR_NAME$ blew out! Your pants are all poopy!", + "Turning bright red, you realize your pants are all messy now!", + "Your cheeks burn with shame when you discover your poop overflowed out into your $PANTS_NAME$.", + "You smell something really stinky and realize your poop overflowed into your $PANTS_NAME$!", + "You start crying as you feel a big log of poop squish out past your $UNDERWEAR_NAME$ and smear down your legs!", + "Oh no! Your $UNDERWEAR_NAME$ couldn't hold the poop and it came out into your $PANTS_NAME$!" + ], + "Debuff_Wet_Pants": [ + "Your pants are wet!", + "You wet your pants!", + "You peed your pants!" + ], + "Debuff_Messy_Pants": [ + "Your pants are messy!", + "Your pants are poopy!", + "You messed your pants!" + ], + "Potty_Dialogs": { + "vincent": { + "pee": { + "pre": { + "success": [ + + ], + "fail": [ + "Hu?", + "Oh.", + "...", + "Wha?" + ] + }, + "post": { + "success": [ + + ], + "fail": [ + "*hehe*", + "...warm", + "...nice", + "mmm!" + ] + } + }, + "poop": { + "pre": { + "success:": [ + + ], + "fail": [ + "Nnnn... Nnnf..", + "Hmm?", + "Tummy ache", + "Oww... Hmmnh..." + ] + }, + "post": { + "success": [ + + ], + "fail": [ + "*giggles*", + "hehe...", + "...warm", + "...nice", + "'m done now!", + "'s ok now!", + "finished!", + "all good now!" + ] + } + } + }, + "jas": { + "pee": { + "pre": { + "success": [ + "have go go, now!", + "going potty!", + "? oh!", + "pee-pee!", + "'s number 1" + ], + "fail": [ + "need to...", + "i have to..", + "pee-peeee...", + "wha... oh", + "i think..." + ] + }, + "post": { + "success": [ + "big girl!", + "yey!", + "big!", + "made it to the potty!" + ], + "fail": [ + "uh-oh...", + "...uh", + "aww...", + "but... 'm big girl...", + "i... didn't...", + "don't need to go now", + "... wet", + "to late now..." + ] + } + }, + "poop": { + "pre": { + "success": [ + "have to go, now!", + "number 2!", + "help! quick!", + "need to go!", + "can i... please?!" + ], + "fail": [ + "nnnumber... nnh...", + "2, numb.. hnnn...", + "Mr... Mrs... nff...", + "Ow... ummh...", + "nnneed to-uh...", + "No, ooho, nnnff...", + "Have to gooooh..." + ] + }, + "post": { + "success": [ + "Big!", + "Made it to the potty! All on my own!" + ], + "fail": [ + "poopie!", + "'nnnh 'naht suppose too", + "...iiihh...", + "eeek... aww...", + "nooh... icky pants", + "don't have to anymore", + "'s ok now...", + "wasn't me" + ] + } + } + }, + "sam": { + "pee": { + "pre": { + "success": [ + + ], + "fail": [ + "...", + "fff..", + "..." + ] + }, + "post": { + "success": [ + + ], + "fail": [ + "...", + "hu!", + "mmm...", + "no, i'm fine!" + ] + } + }, + "poop": { + "pre": { + "success": [ + + ], + "fail": [ + "uh...", + "nnn..." + ] + }, + "post": { + "success": [ + + ], + "fail": [ + "*cough*", + "*caugh* fff...", + "uuh...", + "nnn...", + "oh, i just was thinking.", + "sorry, what?" + ] + } + } + }, + "abigail": { + "pee": { + "pre": { + "success": [ + + ], + "fail": [ + "..." + ] + }, + "post": { + "success": [ + + ], + "fail": [ + "...", + "hu..." + ] + } + }, + "poop": { + "pre": { + "success": [ + + ], + "fail": [ + "uh...", + "nnn..." + ] + }, + "post": { + "success": [ + + ], + "fail": [ + "*giggles*", + "uuh...", + "nnnf..." + ] + } + } + } + }, + "Villager_Underwear_Options": { + "vincent": { + "baby print diaper": { + "friendship": "20", + "dialog_key": "Change_Diaper_Accept_BabyPrint", + "observerfriendship": "friend_Jodi_10" + }, + "lavender pullups": { + "friendship": "-20", + "dialog_key": "Change_Diaper_Accept_Lavender", + "observerfriendship": "friend_Jodi_-5" + }, + "training pants": { + "friendship": "10", + "dialog_key": "Change_Diaper_Accept_Training", + "observerfriendship": "friend_Jodi_-10" + }, + "big kid undies": { + "friendship": "10", + "dialog_key": "Change_Diaper_Accept_BigKids", + "observerfriendship": "friend_Jodi_-40" + }, + "dinosaur undies": { + "friendship": "15", + "dialog_key": "Change_Diaper_Accept_Dinos", + "observerfriendship": "friend_Jodi_-20" + } + }, + "jas": { + "baby print diaper": { + "friendship": "-30", + "dialog_key": "Change_Diaper_Accept_BabyPrint", + "observerfriendship": "friend_Marnie_-10" + }, + "lavender pullups": { + "friendship": "30", + "dialog_key": "Change_Diaper_Accept_Lavender", + "observerfriendship": "friend_Marnie_20" + }, + "training pants": { + "friendship": "30", + "dialog_key": "Change_Diaper_Accept_Training", + "observerfriendship": "friend_Marnie_25" + }, + "big kid undies": { + "friendship": "10", + "dialog_key": "Change_Diaper_Accept_BigKids", + "observerfriendship": "friend_Marnie_-20" + }, + "dinosaur undies": { + "friendship": "-30", + "dialog_key": "Change_Diaper_Accept_Dinos", + "observerfriendship": "friend_Marnie_-15" + } + }, + "sam": { + "baby print diaper": { + "friendship": "15", + "dialog_key": "Change_Diaper_Accept_BabyPrint", + "observerfriendship": "friend_Jodi_10" + }, + "training pants": { + "friendship": "10", + "dialog_key": "Change_Diaper_Accept_Training", + "observerfriendship": "friend_Jodi_10" + }, + "big kid undies": { + "friendship": "-20", + "dialog_key": "Change_Diaper_Accept_BigKids", + "observerfriendship": "friend_Jodi_15" + }, + "joja diaper": { + "friendship": "10", + "dialog_key": "Change_Diaper_Accept_Joja", + "observerfriendship": "friend_Jodi_5" + }, + "heart diaper": { + "friendship": "30", + "dialog_key": "Change_Diaper_Accept_HeartDiaper", + "observerfriendship": "friend_Jodi_15" + } + } + }, + "Villager_Friendship_Modifier": { + // ground: going go on the ground, successfully peeing/pooping there + // ground_attempt: trying to go on the ground, but nothing comes out + // soiled: successfully peeing/pooping in your pants + // dirty: having dirty cloth (wet/poopy pants). NPC usually don't talk to you if you are filthy + "adult": { + "ground": 2.0, + "ground_attempt": 1.0, + "soiled": 1.0, + "dirty": 0.3 + }, + "teen": { + "ground": 1.5, + "ground_attempt": 0.5, + "soiled": 1.0, + "dirty": 0.1 + }, + "kid": { + "ground": 1.0, + "ground_attempt": 0.25, + "soiled": 0, + "dirty": 0 + }, + "animal": { + "ground": 0, + "ground_attempt": 0, + "soiled": 0, + "dirty": 0 + }, + "abigail": { + "ground": 1.0, + "ground_attempt": 0.5, + "soiled": 0, + "dirty": 0.1 + }, + "jodi": { + "ground": 1.0, + "ground_attempt": 0.5, + "soiled": 0, + "dirty": 0 + }, + "sam": { + "ground": 2.0, + "ground_attempt": 1.0, + "soiled": 0, + "dirty": 0.1 + }, + "penny": { + "ground": 1.0, + "ground_attempt": 0.5, + "soiled": 0, + "dirty": 0.05 + }, + "jas": { + "ground": 1.0, + "ground_attempt": 0.5, + "soiled": 0, + "dirty": 0 + } + }, + "Villager_Reactions": { + "adult": { + "soiled_verynice": [ + "Aww, do you need me to change you out of your $UNDERWEAR_NAME$?$l", + "I think little $FARMERNAME$ needs diaper changed!$h", + "I know a little farmer who needs diaper changed!$h" + ], + "soiled_nice": [ + "You poor thing! Did you just yourself?$s", + "Does someone need a diaper change?$h" + ], + "soiled_mean": [ + "You <&really >might want to go change your pants.$3" + ], + "dirty": [ + "You might want to get changed first." + ], + "ground": [ + "$FARMERNAME$! Living in the country doesn't make us barbarians!$3", + "That's not okay! Use a toilet!$3" + ], + "ground_attempt": [ + "$FARMERNAME$! What are you doing!$3", + "This is... have some shame!$3" + ] + }, + "teen": { + "soiled_verynice": [ + "Awww, you're so cute when you're embarrassed!$1", + "Where's your Mommy $FARMERNAME$? I think you need a change." + ], + "soiled_nice": [ + "Did you just yourself $FARMERNAME$?", + "Just letting you know $FARMERNAME$, you should probably change your diaper soon." + ], + "soiled_mean": [ + "...$5", + "...Did you just...$2" + ], + "dirty": [ + "Your pants are all... ...." + ], + "ground": [ + "Eww. Is that normal in the city?$5", + "What... Ugh!$5", + "Did you just on the ground? Gross!$5" + ], + "ground_attempt": [ + "What... Put your pants back on!$5", + "Hey ${man^girl}, i can see everything!$5" + ] + }, + "kid": { + "general": [ + "Not now! 'M playing!", + "Playing?", + "... Yes?" + ], + "soiled_verynice": [ + "*Giggles* Uh oh!$1" + ], + "soiled_nice": [ + "*Giggles* Uh oh!$1" + ], + "soiled_mean": [ + "Oh... gross...$3", + "Ewww$3", + "...$2", + "Ha ha! You yourself!" + ], + "dirty": [ + "Pants !" + ], + "ground": [ + "Ewww!$3", + "Ewww! Don't there!$3", + "...$2" + ], + "ground_attempt": [ + "Eww!$3", + "Eww! I can see your $UNDERWEAR_NAME$!$3" + ] + }, + "animal": { + "soiled_nice": [ + "...", + "???" + ], + "ground": [ + "<...&!!!>" + ], + "ground_attempt": [ + "<...&???>" + ] + }, + "abigail": { + "general_offer_change": [ + "You need a change?#$b#$query !DIAPER_USED#Aww...|$GETTING_CHANGED_DIALOG$" + ], + "soiled_verynice": [ + "Want a change? #$b#I could change you, if you want?$h$GETTING_CHANGED_DIALOG$", + "Sometimes I just put on a diaper and sit around playing games all day. #$b#Maybe we could do that together sometime.$h", + "I think I'm pretty wet. #$b#Would you mind helping me change?#$b#$CHANGE_OTHER_DIALOG$", + "Let me help with that! Lay down for me.$h$GETTING_CHANGED_DIALOG$", + "Ewww, I think.... I think I pooped myself.$s #$b#...$s #$b#Could you... maybe change me?#$b#$CHANGE_OTHER_DIALOG$" + ], + "soiled_nice": [ + "$lWas that me? ...Oh! Nothing! Haha!", + "So, do you have a medical condition or something?", + "You might wanna change. Just incase someone else says something.", + "$lI might be into trying that diaper thing sometime.", + "Is changing too much of a chore? Sorry, rude question!", + "$l*Checks self quickly* Oh! Were you watching?!" + ], + "soiled_mean": [ + "I'm just..nevermind.", + "This is pretty awkward.", + "...Wow. Walking away now.", + "*Feels own backside quickly* Eww! That's gross! You shouldn't do that in public!", + "Did you just your pants? Wow..." + ], + "dirty_offer_change": [ + "$p dirty_change_no# Uh, ok! $1| You kind of dirty @. I can give a diaper if you need one. Where i got them from? Oh, ah, haha...$l$GETTING_CHANGED_DIALOG$" + ] + }, + "haley": { + "soiled_verynice": [ + "$lI'm really glad you've gotten me into this whole diaper thing!", + "$hLooks like $UNDERWEAR_NAME$ a little now!", + "$sI think my diaper's starting to sag. Can you give me a hand?" + ], + "soiled_nice": [ + "$l $UNDERWEAR_NAME$ kind of cute. Where can I get ?", + "$hI think you might be leaking a little!" + ], + "soiled_mean": [ + "$uDiapers are NOT in fashion, and neither is your pants like a baby!", + "$uLike, eww. Why is everyone in this town so gross?!", + "$uI was gonna tell you to change your clothes because of how unstylish they are, but it looks like you need your diaper changed more, you big baby!" + ] + }, + "maru": { + "general_offer_change": [ + "Everything dry?#$b#$query !DIAPER_USED#Hmm... but come back if that changes.|$GETTING_CHANGED_DIALOG$" + ], + "soiled_verynice": [ + "Again? Sure, you know the drill...$l$GETTING_CHANGED_DIALOG$" + ], + "soilded_nice": [ + "Lets be professional about this. Lie down on the bed for me please?$0$GETTING_CHANGED_DIALOG$" + ], + "soiled_mean": [ + "Incontinence i guess?$4" + ], + "dirty_offer_change": [ + "You will catch a cold, or worse. Let's get the cloth off!$1$GETTING_CHANGED_DIALOG$g" + ] + }, + "sam": { + "general_offer_change": [ + "Wait a second, i know that look!#$b#%Sam checks your diaper#$b#$query !DIAPER_USED#I guess later than.|$GETTING_CHANGED_DIALOG$", + "%You put your hand in sams pants. He blushes a lot while you check him.$9#$b#$query !DIAPER_USED \"sam\"#He is wearing $NPC_PANTS_NAME$ and $NPC_INSPECT_UNDERWEAR_NAME$.|$CHANGE_OTHER_DIALOG$" + ], + "soiled_verynice": [ + "#$p 102#Oh man, that was pretty hard to miss!$1|Man, you're just like Vincent.$1#$GETTING_CHANGED_DIALOG$", + "Are you okay buddy?#$b#Do you want some help with that? $GETTING_CHANGED_DIALOG$", + "It's okay $FARMERNAME$. Accidents are nothing to be ashamed of.", + "Awwww, look at you go! That must have felt good.$4", + "Oh man, that was pretty hard to miss!$1", + "Good one!$1", + "Man, you're such a little baby sometimes.#$b#%Sam giggles a bit as he pats your squishy bottom.#$b#Need help with that? $GETTING_CHANGED_DIALOG$", + "Awww, did the little farmer have a little accident?", + "I bet I could get Mommy to go change you.$3#$b#I'm kidding I'm kidding!$1", + "Man, it looks like you really need diapers, don't you.", + "Oh wow, you really yourself! Can I feel it?#$b#$y 'Yes._*Sam blushes as he presses his hand into your squishy diaper*_No thank you._Okay, I won't.'" + ], + "soiled_nice": [ + "You might wanna change. Just incase someone else says something.$7", + "A-are you okay?$8", + "%Sam just blushes a as you yourself. You take note of how closely he watches the whole scene.", + "Oh man, I'm sorry. That can't feel good." + ], + "soiled_mean": [ + "I'm just..nevermind.$5", + "This is pretty awkward.$2", + "...Oh$2", + "You might want to take care of that...", + "#$p 102#You might want to take care of that...|Great, more potty issues to be witness to. Thanks.$5" + ], + "dirty_offer_change": [ + "Oh man. Can't let you catch a cold, mum would kill me.$9#$b#Where are vincents diapers again?$1$GETTING_CHANGED_DIALOG$" + ] + }, + "penny": { + "general_offer_change": [ + "Did my big forgot about the potty again?#$b#%Penny checks your diaper#$b#$query !DIAPER_USED#Good !|$GETTING_CHANGED_DIALOG$" + ], + "general_fallback": [ + "%Maybe you should get to know Penny better first!" + ], + "soiled_verynice": [ + "$FARMERNAME$! You're your $UNDERWEAR_NAME$!$5#$b#Why didn't you tell me you needed the potty?$3#$b#*Sigh* It's okay, we can try again next time.", + "%Penny watches you with an eyebrow raised.#$b#Is there something you want to tell me @?$3$GETTING_CHANGED_DIALOG$", + "%Penny waits until you're all finished before tugging your waistband for a check.#$b#Looks like you didn't save anything for the potty little .$1", + "%You tug on Penny's sleeve for help to go potty right before your $UNDERWEAR_NAME$.#$b#Oh no you were so close!$3#$b#I'm not mad, I know you're trying. You'll get the hang of it really soon.", + "Did you have an accident in your $UNDERWEAR_NAME$ $FARMERNAME$?#$b#You have to tell me as soon as your body says you have to go potty, okay?$3", + "#$p 102#Did you have an accident in your $UNDERWEAR_NAME$ $FARMERNAME$?|You have the same potty face as Vincent.$1#$b#Do you need help getting changed like him too?#$b#%Penny tickles your tummy teasingly.", + "I saw that.$3#$b#$y 'Was that REALLY an accident?_Uh huh, I tried to hold it._Oh $FARMERNAME$, I know it's hard for you. I'm very proud of you for trying._I didn't wanna use the potty._$FARMERNAME$, I know it's hard for you, but you still have to try, okay?$3'", + "We're supposed to do that on the potty $FARMERNAME$. What happened?$3#$b#It's okay, I'm not angry. You're trying really hard. It's okay if you still have accidents sometimes.#$b# are easy to clean!$1$GETTING_CHANGED_DIALOG$" + ], + "soiled_nice": [ + "You might wanna change. Just incase someone else says something.", + "A-are you okay?$3", + "Do you need help making it to the potty?", + "I'm sorry. That can't feel good.$3" + ], + "soiled_mean": [ + "...$5", + "Uhmm...$2", + "...Oh$2", + "#$p 102#D-did you...|You too?$5" + ], + "dirty_offer_change": [ + "Oh you poor little ! Didn't someone not remember the potty again? Lets get you out of your wet cloth and in a warm diaper!$1$GETTING_CHANGED_DIALOG$" + ] + }, + "gus": { + "soiled_verynice": [ + "Couldn’t quite make it? That’s okay. Ain’t the worst mess I’ve seen ‘round here, trust me.$1", + "Looks like that was a relief, hah!$1", + "Couldn’t hold it any longer, eh?", + "Hoo boy, that’s gonna be a heck of a change.$1", + "That’s it, let it all on out.", + "Wow, you were really with that one.$1", + "Well, at least it feels good to take a load off...#$b#Even if it’s in your pants, yeah?$1", + "You makin’ your own fertilizer there $FARMERNAME$?", + "You got any clean diapers? I always keep some spare in back for ya, just in case, pal.$1#$b#Well, you and anyone else who happens to need one." + ], + "soiled_nice": [ + "You mind takin' care of that please?#$b#Thanks$1", + "When you gotta go I guess!$1", + "Couldn’t quite make it? That's alright, go get cleaned up. The Saloon will still be here when you get back.", + "I hope that smell’s a dirty diaper and not some rotting food in back…" + ], + "soiled_mean": [ + "You mind takin' care of that before it bothers anyone else buddy?$2", + "I have enough to clean up.$3" + ], + "dirty_offer_change": [ + "Oh dear! Had trouble getting there again? As promissed, i have some reserves lying around, just in case!$1$GETTING_CHANGED_DIALOG$" + ] + }, + "jodi": { + "general_offer_change": [ + "You need a change?#$b#%Jodi checks your $INSPECT_UNDERWEAR_NAME_NO_PREFIX$.#$b#$query !DIAPER_USED_BAD#[OnClean: Look at that! You are completly clean! How did that happen?][OnSlightlyWet: You only a little wet. Come back when you had another of your \"accidents\". *wink*]|$GETTING_CHANGED_DIALOG$" + ], + "soiled_verynice": [ + "%Jodi leans down to put a comforting hand on your back.#$b#You can tell me if you had a little accident $FARMERNAME$. It's nothing to be ashamed of.", + "You don't need to rush potty training if you're not ready yet.#$b#You need help?$GETTING_CHANGED_DIALOG$", + "It can be hard for little to remember to go potty sometimes. It's okay.#$b#Need a change?$GETTING_CHANGED_DIALOG$", + "Oh goodness!$1", + "Awww, you're so cute when you're embarrassed!$1#$b#Comeon, lets get you in some new Diapers!$GETTING_CHANGED_DIALOG$" + ], + "soiled_nice": [ + "$FARMERNAME$, I think you might need to go change.", + "You poor thing! Did you just yourself?" + ], + "soiled_mean": [ + "You might need to tap into those supplies I left you$4" + ], + "dirty_offer_change": [ + "$p dirty_change_no# No leaks! $3| Aww, come here @, no crying! This things happen! We can make one of Vincents diapers fit and there are some pants from sam that you could borrow!$1$GETTING_CHANGED_DIALOG$" + ] + }, + "vincent": { + "general_offer_change": [ + "%You wonder if Vincent might need a change. You quickly check and find $NPC_INSPECT_UNDERWEAR_NAME$.#$b#$query !DIAPER_USED \"vincent\"#No changies! Wanna play more!$3|$CHANGE_OTHER_DIALOG$" + ], + "soiled_verynice": [ + "Mommy told me big kids are supposed to use the potty. #$b#I don't wanna be a big kid either!$1", + "%Vincent watches you yourself and giggles.#$b#Good one!$1", + "%You notice Vincent watching as you yourself.#$b#All better?", + "%Vincent watches the whole scene curiously and giggles when you look over. #$b# You !$1", + "If you want I could ask my Mommy to change you.#$b#No?#$b#That's okay, I like being too!$1", + "$FARMERNAME$'s and I'm still dry!$1#$b#...#$b#Wait, am i?$2" + ], + "soiled_nice": [ + "Don't cry, Mommy says it's okay to have accidents sometimes.", + "Don't worry $FARMERNAME$, I still do that too!", + "Feel all better?", + "It smells like you need a diaper change!", + "I kney it! It does happen to bigs too!" + ], + "soiled_mean": [ + "%Vincent saw what happened and snickers at you.", + "Was that an accident?", + "Ha! Gross!$1", + "$FARMERNAME$ just !$1", + "Hah! I just watched you yourself!$1" + ], + "ground": [ + "Ewww!$3", + "Ewww! Don't there!$3", + "Hey! $FARMERNAME$ did on the ground!$1" + ] + }, + "jas": { + "general_offer_change": [ + "%You wonder if Jas might need a change. You quickly check and find $NPC_INSPECT_UNDERWEAR_NAME$.#$b#$query !DIAPER_USED \"jas\"#Wha? No, 'm a big girl now! See? Clean!$3|$CHANGE_OTHER_DIALOG$" + ], + "soiled_verynice": [ + "Don't cry, it's okay for little s to have accidents sometimes.", + "Oh no, did you have an accident? That's okay, you can try again next time.", + "It's okay, I won't tell anyone you had an accident $FARMERNAME$", + "It's okay $FARMERNAME$, I still have accidents too.$1", + "I can see you waddling!$4", + "Did you have an accident? It's okay, once you're all clean you'll feel all better." + ], + "soiled_nice": [ + "*Giggles* Uh oh!$1", + "You're supposed to do that on the potty you know.$4", + "Do you need me to get Aunt Marnie? She always helps me when I have an accident.$3" + ], + "soiled_mean": [ + "Oh... gross...$3", + "Ewww$3", + "...$3" + ], + "ground": [ + "Ewww!$3", + "Ewww! Don't there!$3", + "...$3" + ] + } + }, + + "Change": [ + "You change into $PANTS_PREFIX$ clean $PANTS_NAME$ and $INSPECT_UNDERWEAR_NAME$.", + "You get changed into $PANTS_PREFIX$ $PANTS_NAME$ and $INSPECT_UNDERWEAR_NAME$." + //***"You take off your soiled and put on $UNDERWEAR_PREFIX$ clean $UNDERWEAR_NAME$." + ], + "Change_Destroyed": [ + "You ruined your $UNDERWEAR_NAME$ when taking off. So you throw away.", + "$UNDERWEAR_NAME$ ruined, so you throw away." + ], + "Change_Other_Destroyed": [ + "$NPC_NAME$s $NPC_INSPECT_UNDERWEAR_NAME_NO_PREFIX$ ruined, so you throw away." + ], + "Getting_Changed_Destroyed": [ + "Your $INSPECT_UNDERWEAR_NAME_NO_PREFIX$ ruined and thrown away for you." + ], + "Change_Requires_Pants": [ + "You don't have another pair of $PANTS_NAME$ here to change into. You probably need to go home first." + ], + "Change_Requires_Home": [ + "Dirty pants have to be changed at home." + ], + "Change_At_Home": [ + "You change yourself into another pair of $PANTS_NAME$." + ], + "PeekWaistband": [ + "You peek inside your waistband and see" + ], + "LookPants": [ + "You look down and see" + ], + "Underwear_Clean": "clean $UNDERWEAR_DESC$", + "Underwear_Drying": "drying $UNDERWEAR_DESC$", + "EasyMode_On": "Easy Mode on. Hunger and Thirst are refilled every morning and the wet beds dried.", + "EasyMode_Off": "Easy Mode off. Hunger and Thirst are never refilled and wet beds dry slowly.", + "Underwear_Wet": [ //Chosen based on diaper wetness, applied after Underwear_Messy. Words in brackets only show if underwear is also messy. + "slightly damp $UNDERWEAR_DESC$", + "somewhat wet $UNDERWEAR_DESC$", + "very wet $UNDERWEAR_DESC$", + "drenched $UNDERWEAR_DESC$", + "dripping wet $UNDERWEAR_DESC$" + ], + "Underwear_Messy": [ //Chosen based on diaper messiness, applied before Underwear_Wet. Words in brackets are only used if underwear is also wet. + "slightly poopy $UNDERWEAR_DESC$", + "somewhat poopy $UNDERWEAR_DESC$", + "poopy $UNDERWEAR_DESC$", + "$UNDERWEAR_DESC$ filled with poop", + "$UNDERWEAR_DESC$ with poop squishing out" + ], + "Consumables": { + // + // + //Working on creating entries for every consumable. + //Water values are arbitrary, but should be accurate to each other relatively. Poisons mean vomitting, indigestion, and other issues, therefore poisonous items cause a loss to calories and water. + // + //Crops + //With a lot of these, I looked up the calorie count for an average size or average amount for small items like berries, then rounded out the numbers. For balance, some really small numbers are unnaturally high. For grains, I went with half a cup of grains. All items are assumed to undergo basic cooking if necesary to make edible, such as with potatoes. + + // Floximo (comment): I appriciate all the work that has gone into making it realistic, but in terms of gameplay its disastrous. + // Harvesting a plot that gives us resources worth 200 coins and making it value 1/40 of the daily calorie intake after 8 days of growing is not fun or challenging, it is unbalanced. + // The assumtion should be that it is reasonable to harvest and store an amount of food that can feed at least 4 people over the winter (usual family size). That means 1 artichoke or 1 corn is not an ear but a yield of a garden plot (so more like 10 to 20 times that) + // We also assume we eat things cooked. Days are very short, so this assumtion should be a given as reasonable. + // In any case, this manual list is not archiving any goal, not realism, not balance, not fun or easy of maintainance. In fact it also fails on being complete and as such causes issues in anything imaginable. As such we try to get Energy/Health values from the game instead. + + //Veggies + // + "Amaranth": { + "name": "Amaranth", + "waterContent": 0, + "calorieContent": 350 //Half cup Amaranth, made as simple bread or cooked directly like rice + }, + "Artichoke": { + "name": "Artichoke", + "waterContent": 200, + "calorieContent": 150 //Two large artichokes, raw + }, + "Beet": { + "name": "Beet", + "waterContent": 25, + "calorieContent": 140 //Four beets, raw + }, + "Bok Choy": { + "name": "Bok Choy", + "waterContent": 75, + "calorieContent": 110 //One head of bok choy, raw + }, + "Corn": { + "name": "Corn", + "waterContent": 25, + "calorieContent": 190 //One large ear of sweet corn, simply cooked + }, + "Eggplant": { + "name": "Eggplant", + "waterContent": 50, + "calorieContent": 150 //One large Eggplant, simply cooked + }, + "Fiddlehead Fern": { + "name": "Fiddlehead Fern", + "waterContent": 25, + "calorieContent": 140 //Four fiddleheads, raw + }, + "Garlic": { + "name": "Garlic", + "waterContent": 25, + "calorieContent": 50 //One large head of garlic, raw + }, + "Green Bean": { + "name": "Green Bean", + "waterContent": 25, + "calorieContent": 160 //Four large greenbeans, raw or simply cooked + }, + "Hops": { + "name": "Hops", + "waterContent": 25, + "calorieContent": 350 //Half cup of hops, can't find a calorie count since people don't actually eat hops, so just using Amaranth's + }, + "Kale": { + "name": "Kale", + "waterContent": 25, + "calorieContent": 100 //Enough kale leaves to match a head of lettuce, raw + }, + "Parsnip": { + "name": "Parsnip", + "waterContent": 25, + "calorieContent": 150 //Two parsnips, raw + }, + "Potato": { + "name": "Potato", + "waterContent": 25, + "calorieContent": 180 //One large potato, 'baked' + }, + "Radish": { + "name": "Radish", + "waterContent": 25, + "calorieContent": 100 //20 radishes at 5calories each, raw. According to every source I can find, a one inch wide radish only contains 1.9 calories. This doesn't seem right, so I bumped it up. + }, + "Red Cabbage": { + "name": "Red Cabbage", + "waterContent": 75, + "calorieContent": 350 //One large head of red cabbage, raw + }, + "Taro Root": { + "name": "Taro Root", + "waterContent": 50, + "calorieContent": 500 //One small taro root (1pound), cooked simply. IRL, Normal taro root, harvested after 8-10 months, is 2-4 pounds. + }, + "Tomato": { + "name": "Tomato", + "waterContent": 100, + "calorieContent": 140 //Four large tomatoes, raw + }, + "Unmill Rice": { + "name": "Unmill Rice", + "waterContent": 25, + "calorieContent": 350 //Half cup, cooked simply + }, + "Yam": { + "name": "Yam", + "waterContent": 25, + "calorieContent": 180 //One Large yam, cooked simply + }, + // + //Fruit + // + "Apple": { + "name": "Apple", + "waterContent": 100, + "calorieContent": 120 //One large apple, raw + }, + "Apricot": { + "name": "Apricot", + "waterContent": 100, + "calorieContent": 100 //Four apricots, raw + }, + "Banana": { + "name": "Banana", + "waterContent": 50, + "calorieContent": 130 //One large banana, raw + }, + "Blackberry": { + "name": "Blackberry", + "waterContent": 50, + "calorieContent": 140 //Two cups of blackberries, raw + }, + "Blueberry": { + "name": "Blueberry", + "waterContent": 50, + "calorieContent": 170 //Two cups of blueberries, raw + }, + "Cactus Fruit": { + "name": "Cactus Fruit", + "waterContent": 100, + "calorieContent": 120 //Two large fruits, raw + }, + "Cherry": { + "name": "Cherry", + "waterContent": 50, + "calorieContent": 150 //Two cups of cherries, raw + }, + "Cranberries": { + "name": "Cranberries", + "waterContent": 50, + "calorieContent": 100 //Two cups of cranberries, raw + }, + "Crystal Fruit": { + "name": "Crystal Fruit", + "waterContent": 150, + "calorieContent": 350 //One large crystal fruit. Fantasy item, so I get to dictate it. >:3 + }, + "Grape": { + "name": "Grape", + "waterContent": 100, + "calorieContent": 220 //Two cups of grapes, raw + }, + "Hot Pepper": { + "name": "Hot Pepper", + "waterContent": -500, + "calorieContent": 100 //Four cups of Jalapenos to barely make it to 100. Have some water ready. + }, + "Mango": { + "name": "Mango", + "waterContent": 100, + "calorieContent": 135 //One Mango, raw + }, + "Melon": { + "name": "Melon", + "waterContent": 125, + "calorieContent": 500 //One large honeydew melon as reference for the stardew melon, raw + }, + "Orange": { + "name": "Orange", + "waterContent": 100, + "calorieContent": 100 //One large orange, raw + }, + "Peach": { + "name": "Peach", + "waterContent": 100, + "calorieContent": 130 //Two peaches, raw + }, + "Pineapple": { + "name": "Pineapple", + "waterContent": 125, + "calorieContent": 300 //One large pineapple, raw. Your mouth is gonna tingle after eating this. + }, + "Pomegranate": { + "name": "Pomegranate", + "waterContent": 50, + "calorieContent": 130 //One large pomegranate, raw + }, + "Qi Fruit": { + "name": "Qi Fruit", + "waterContent": 500, + "calorieContent": 1000 //Qi Fruit? We get to cultivate now? Well, in the cultivator novels, Qi Fruit tends to be able to 'sustain the martial artist for a week' and such. + }, + "Salmonberry": { + "name": "Salmonberry", + "waterContent": 25, + "calorieContent": 150 //Two cups of salmonberries, raw + }, + "Spice Berry": { + "name": "Spice Berry", + "waterContent": -25, + "calorieContent": 180 //Two cups of spice berries, raw + }, + "Starfruit": { + "name": "Starfruit", + "waterContent": 125, + "calorieContent": 400 //RL starfruits are about 40 calories each; this fruit seems to be quite different from those, though + }, + "Strawberry": { + "name": "Strawberry", + "waterContent": 50, + "calorieContent": 100 //Two cups of strawberries, raw + }, + "Wild Plum": { + "name": "Wild Plum", + "waterContent": 50, + "calorieContent": 120 //Four plums, raw + }, + // + //Flower + // + "Blue Jazz": { + "name": "Blue Jazz", + "waterContent": 25, + "calorieContent": 50 + }, + "Crocus": { + "name": "Crocus", + "waterContent": 25, + "calorieContent": 50 + }, + "Fairy Rose": { + "name": "Fairy Rose", + "waterContent": 25, + "calorieContent": 50 + }, + "Poppy": { + "name": "Poppy", + "waterContent": 25, + "calorieContent": 50 + }, + "Summer Spangle": { + "name": "Summer Spangle", + "waterContent": 25, + "calorieContent": 50 + }, + "Sunflower": { + "name": "Sunflower", + "waterContent": 25, + "calorieContent": 200 //Sunflower seeds are boosting this over other flowers + }, + "Sweet Pea": { + "name": "Sweet Pea", + "waterContent": 25, + "calorieContent": 50 + }, + "Tulip": { + "name": "Tulip", + "waterContent": 25, + "calorieContent": 50 + }, + // + //Forage + // + "Cave Carrot": { + "name": "Cave Carrot", + "waterContent": 25, + "calorieContent": 120 //Four large carrots, raw + }, + "Chanterelle": { + "name": "Chanterelle", + "waterContent": 25, + "calorieContent": 50 //Two cups of chanterelle. These things are worse than kale for calories... + }, + "Common Mushroom": { + "name": "Common Mushroom", + "waterContent": 25, + "calorieContent": 100 //Two cups of Shiitake, raw + }, + "Daffodil": { + "name": "Daffodil", + "waterContent": 25, + "calorieContent": 50 + }, + "Dandelion": { + "name": "Dandelion", + "waterContent": 25, + "calorieContent": 60 + }, + "Ginger": { + "name": "Ginger", + "waterContent": -250, //IIRC, straight ginger root causes burning sensations on mucous membranes, like the throat, so let's up the demand for water a little.... + "calorieContent": 80 //One cup ginger root, raw + }, + "Hazelnut": { + "name": "Hazelnut", + "waterContent": 0, + "calorieContent": 425 //Half cup of Hazelnuts. They're also called filberts, lol. + }, + "Holly": { + "name": "Holly", //Don't eat Holly, it's poisonous. + "waterContent": -1500, + "calorieContent": -1250 + }, + "Leek": { + "name": "Leek", //Must... Not... Spin... + "waterContent": 25, + "calorieContent": 110 //Two leeks, raw + }, + "Magma Cap": { + "name": "Magma Cap", + "waterContent": -1500, + "calorieContent": 1500 //With all the energy it's absorbed, there's plenty for you to use... Assuming you can quench your newfound thirst. + }, + "Morel": { + "name": "Morel", + "waterContent": 25, + "calorieContent": 40 //Two cups of morels. And I thought the chanterelles were bad... + }, + "Purple Mushroom": { + "name": "Purple Mushroom", + "waterContent": 25, + "calorieContent": 750 //Half of magmacap + }, + "Red Mushroom": { + "name": "Red Mushroom", //Don't eat this toadstool, unless you want to turn into a tanuki! + "waterContent": -500, + "calorieContent": -1000 + }, + "Sap": { + "name": "Sap", //....Why can we eat this? Why would we want to eat this? At least the mushrooms and holly make since, because 'mistaken identity'. What edible thing are you mistaking tree sap as? + "waterContent": -200, + "calorieContent": -100 + }, + "Snow Yam": { + "name": "Snow Yam", + "waterContent": 25, + "calorieContent": 180 //One Large yam, cooked simply + }, + "Spring Onion": { + "name": "Spring Onion", + "waterContent": 25, + "calorieContent": 500 //Reduced from 700 to 500 - One hundred large scallions, only because this is the "starter" food + }, + "Field Snack": { + "name": "Field Snack", + "waterContent": 10, + "calorieContent": 700 //Old reliable, easily craftable by the player, worth little and gives a good buff. "starter" food + }, + "Wild Horseradish": { + "name": "Wild Horseradish", + "waterContent": -250, //This is wasabi's crappy tasting cousin, but the spice is still there. Corrected to -250 from -2500 + "calorieContent": 115 //One cup of raw horseradish, about the size of a normal prepared root. + }, + "Winter Root": { + "name": "Winter Root", + "waterContent": 25, + "calorieContent": 300 //Since Winter Root is a tuber, I just picked a random one. Winged bean tuber it is! Half cup sized tubers. + }, + // + //Animal Drops + // + "Duck Egg": { + "name": "Duck Egg", + "waterContent": 50, + "calorieContent": 80 // A hand full of eggs, its worth + }, + "Egg": { + "name": "Egg", + "waterContent": 50, + "calorieContent": 80 //One 'USDA medium' egg + }, + "Goat Milk": { + "name": "Goat Milk", + "waterContent": 470, //16oz ~ 490mL. Did rounding because the numbers don't have to be perfectly accurate. + "calorieContent": 340 //16oz of goat milk + }, + "Golden Egg": { + "name": "Golden Egg", + "waterContent": 50, + "calorieContent": 360 //One 'USDA medium' gold flake lined egg + }, + "L. Goat Milk": { + "name": "L. Goat Milk", + "waterContent": 3785, //Description is a gallon of milk; 1 gallon = 3785mL + "calorieContent": 2700 //It's a gallon of milk, lots of calories.... Plus side, the babs can actually live off milk. + }, + "Large Egg": { + "name": "Large Egg", + "waterContent": 75, + "calorieContent": 130 //One 'USDA extra-large' egg + }, + "Large Milk": { + "name": "Large Milk", + "waterContent": 3785, + "calorieContent": 2400 + }, + "Milk": { + "name": "Milk", + "waterContent": 470, + "calorieContent": 300 + }, + "Ostrich Egg": { + "name": "Ostrich Egg", + "waterContent": 200, + "calorieContent": 2000 + }, + "Truffle": { + "name": "Truffle", + "waterContent": 25, + "calorieContent": 70 //One whole, raw truffle. I feel sorry for the poor soul eating this... + }, + "Void Egg": { + "name": "Void Egg", + "waterContent": 50, + "calorieContent": 360 // One 'USDA jumbo' void egg + }, + // + //Cooking + //Will try looking up calorie counts for similar items. The rest will be done by adding ingredient calories and see how it looks. + "Algae Soup": { + "name": "Algae Soup", + "waterContent": 660, + "calorieContent": 760 + }, + "Artichoke Dip": { + "name": "Artichoke Dip", + "waterContent": 200, + "calorieContent": 900 //2cups + }, + "Autumn's Bounty": { + "name": "Autumn's Bounty", //1 whole extra large pumpkin makes about 36cups of cooked pumpkin. 1 cup is about 100 calories. Assuming not oversized pumpkins, 24 cups of cooked pumpkin seems fine. + "waterContent": 0, + "calorieContent": 2580 + }, + "Baked Fish": { + "name": "Baked Fish", + "waterContent": 0, + "calorieContent": 660 + }, + "Banana Pudding": { + "name": "Banana Pudding", + "waterContent": 590, + "calorieContent": 1000 //2cups + }, + "Bean Hotpot": { + "name": "Bean Hotpot", + "waterContent": 0, + "calorieContent": 600 //4cups + }, + "Blackberry Cobbler": { + "name": "Blackberry Cobbler", + "waterContent": 0, + "calorieContent": 2500 //About 4cups filling and one cup crust + }, + "Blueberry Tart": { + "name": "Blueberry Tart", + "waterContent": 0, + "calorieContent": 520 //About 2cups in volume + }, + "Bread": { + "name": "Bread", + "waterContent": 0, + "calorieContent": 900 //Calories in standard baguette + }, + "Bruschetta": { + "name": "Bruschetta", + "waterContent": 0, + "calorieContent": 1200 //Big piece, but it uses an entire loaf of bread, so... + }, + "Cheese Cauliflower": { + "name": "Cheese Cauliflower", + "waterContent": "000", + "calorieContent": 540 //4 cups + }, + "Chocolate Cake": { + "name": "Chocolate Cake", + "waterContent": 250, + "calorieContent": 28800 //A three tier cake with icing would be about 18 pounds(288oz), according to a baker's website. Have fun filling your pamps. + }, + "Chowder": { + "name": "Chowder", + "waterContent": 150, + "calorieContent": 640 //4 cups + }, + "Coleslaw": { + "name": "Coleslaw", + "waterContent": 25, + "calorieContent": 1000 //4 cups + }, + "Complete Breakfast": { + "name": "Complete Breakfast", + "waterContent": 25, + "calorieContent": 1700 + }, + "Cookie": { + "name": "Cookie", + "waterContent": 25, + "calorieContent": 850 //A dozen cookies, because they're so delicious. + }, + "Crab Cakes": { + "name": "Crab Cakes", + "waterContent": 25, + "calorieContent": 880 //8 2in wide 3/4inch tall crab cakes. + }, + "Cranberry Candy": { + "name": "Cranberry Candy", //This item's sprite looks like juice, and is made with apples, so just using cranberry apple juice as reference + "waterContent": 470, + "calorieContent": 320 //16oz + }, + "Cranberry Sauce": { + "name": "Cranberry Sauce", + "waterContent": 25, + "calorieContent": 880 //2 cups + }, + "Crispy Bass": { + "name": "Crispy Bass", //An average bass weighs about five pounds. Roughly 1/3 of the weight of a large fish is good for typical fish meat. That's still a lot of meat to eat in one sitting. + "waterContent": 25, + "calorieContent": 1800 //six fillets on each side, about 150calories per bass fillet at that size + }, + "Dish O' The Sea": { + "name": "Dish O' The Sea", //Canned or not, sardines are still super salty. Eating a pile of straight sardines sounds painful. At least the hashbrowns don't need any extra salt. + "waterContent": -750, + "calorieContent": 750 + }, + "Eggplant Parmesan": { + "name": "Eggplant Parmesan", + "waterContent": 75, + "calorieContent": 1240 //4 cups + }, + "Escargot": { + "name": "Escargot", + "waterContent": 125, + "calorieContent": 520 //16 normal sized escargot snails; just pretending SDV snails are bigger because magic and meteors. lol. + }, + "Farmer's Lunch": { + "name": "Farmer's Lunch", + "waterContent": 75, + "calorieContent": 1500 + }, + "Fiddlehead Risotto": { + "name": "Fiddlehead Risotto", + "waterContent": 120, + "calorieContent": 1360 //2 cups + }, + "Fish Stew": { + "name": "Fish Stew", //Wait... Fish stew literally contains no fish, only only arthropods and mollusks o.o + "waterContent": 280, + "calorieContent": 840 //4 cups + }, + "Fish Taco": { + "name": "Fish Taco", + "waterContent": 120, + "calorieContent": 1600 //One face sized taco, just to make sure calorie count is greater than ingredient sum + }, + "Fried Calamari": { + "name": "Fried Calamari", + "waterContent": 50, + "calorieContent": 800 //"4 cups", I assume not packed + }, + "Fried Eel": { + "name": "Fried Eel", + "waterContent": 150, + "calorieContent": 1300 //4 cups + }, + "Fried Egg": { + "name": "Fried Egg", + "waterContent": 25, + "calorieContent": 160 //Double eggs, because incetivizing processing + }, + "Fried Mushroom": { + "name": "Fried Mushroom", + "waterContent": 50, + "calorieContent": 500 //6cups + }, + "Fruit Salad": { + "name": "Fruit Salad", + "waterContent": 100, + "calorieContent": 880 //8 cups fruit salad; indgredient sum is 770 + }, + "Ginger Ale": { + "name": "Ginger Ale", + "waterContent": 470, + "calorieContent": 160 //16oz + }, + "Glazed Yams": { + "name": "Glazed Yams", + "waterContent": 50, + "calorieContent": 400 //4cups + }, + "Hashbrowns": { + "name": "Hashbrowns", + "waterContent": 50, + "calorieContent": 350 //4cups + }, + "Ice Cream": { + "name": "Ice Cream", + "waterContent": 125, + "calorieContent": 350 //One cone, double scoop + }, + "Life Elixir": { + "name": "Life Elixir", //"Restores health to full." ....Then why do some foods restore more health than this? + "waterContent": 235, //8oz + "calorieContent": 2000 //Delicious, Nutritious, magic world health potions! + }, + "Lobster Bisque": { + "name": "Lobster Bisque", + "waterContent": 250, + "calorieContent": 1100 //4 cup + }, + "Lucky Lunch": { + "name": "Lucky Lunch", //ngl, this recipe is a little off putting to me... Sea cucumber is really slimy, cooked or not, unless it's way overcooked and tastes terrible. + "waterContent": 100, + "calorieContent": 1000 //1 slimy sea cucumber taco + }, + "Magic Rock Candy": { + "name": "Magic Rock Candy", + "waterContent": "000", + "calorieContent": 2500 //Pure, unadulterated magic rainbow sugar crystals. + }, + "Maki Roll": { + "name": "Maki Roll", + "waterContent": 0, + "calorieContent": 800 //4 rolls. + }, + "Mango Sticky Rice": { + "name": "Mango Sticky Rice", + "waterContent": 0, + "calorieContent": 920 //4 cups + }, + "Maple Bar": { + "name": "Maple Bar", //Weird name for a maple donut, but okay. + "waterContent": 0, + "calorieContent": 600 //One doughnut, apparently + }, + "Miner's Treat": { + "name": "Miner's Treat", + "waterContent": 0, + "calorieContent": 1000 //Extra large lollipop, just to stay higher than sum of ingredients + }, + "Oil": { + "name": "Oil", + "waterContent": 0, + "calorieContent": 120 //1 tablespoon. Seriously. + }, + "Oil of Garlic": { + "name": "Oil of Garlic", + "waterContent": 0, + "calorieContent": 125 //1 tablespoon + }, + "Omelet": { + "name": "Omelet", //Can it really be called an omelette without cheese? + "waterContent": 0, + "calorieContent": 450 //4 medium egg omelette + }, + "Pale Broth": { + "name": "Pale Broth", + "waterContent": 660, + "calorieContent": 760 //copy of algae soup + }, + "Pancakes": { + "name": "Pancakes", + "waterContent": 0, + "calorieContent": 400 //4 4inch pancakes + }, + "Parsnip Soup": { + "name": "Parsnip Soup", + "waterContent": 500, + "calorieContent": 640 //4 cups of parsnip cream soup + }, + "Pepper Poppers": { + "name": "Pepper Poppers", + "waterContent": 0, + "calorieContent": 800 //12 poppers + }, + "Piña Colada": { + "name": "Piña Colada", + "waterContent": 235, + "calorieContent": 420 //8oz + }, + "Pink Cake": { + "name": "Pink Cake", + "waterContent": 0, + "calorieContent": 1900 //An entire cake. Fewer calories than I expected, tbh. + }, + "Pizza": { + "name": "Pizza", + "waterContent": 0, + "calorieContent": 1840 //A 12" cheese pizza + }, + "Plum Pudding": { + "name": "Plum Pudding", + "waterContent": 0, + "calorieContent": 1000 //Apparently Plum Puddings are measured in loafs? + }, + "Poi": { + "name": "Poi", + "waterContent": 300, + "calorieContent": 1080 //4 cups + }, + "Poppyseed Muffin": { + "name": "Poppyseed Muffin", + "waterContent": 25, + "calorieContent": 670 //1 muffin + }, + "Pumpkin Pie": { + "name": "Pumpkin Pie", + "waterContent": 50, + "calorieContent": 2500 //1 pie + }, + "Pumpkin Soup": { + "name": "Pumpkin Soup", + "waterContent": 1250, + "calorieContent": 870 //8 cups + }, + "Radish Salad": { + "name": "Radish Salad", + "waterContent": 50, + "calorieContent": 600 + }, + "Red Plate": { + "name": "Red Plate", + "waterContent": 150, + "calorieContent": 600 + }, + "Rhubarb Pie": { + "name": "Rhubarb Pie", + "waterContent": 150, + "calorieContent": 3530 //1 pie. Why is it so much worse than other pies? + }, + "Rice": { + "name": "Rice", + "waterContent": 50, + "calorieContent": 400 //2 cups cooked white rice + }, + "Rice Pudding": { + "name": "Rice Pudding", + "waterContent": 100, + "calorieContent": 1200 //4 cups + }, + "Roasted Hazelnuts": { + "name": "Roasted Hazelnuts", + "waterContent": 50, + "calorieContent": 1440 //1 cup of roasted hazelnuts + }, + "Roots Platter": { + "name": "Roots Platter", + "waterContent": 50, + "calorieContent": 750 + }, + "Salad": { + "name": "Salad", + "waterContent": 50, + "calorieContent": 600 + }, + "Salmon Dinner": { + "name": "Salmon Dinner", + "waterContent": 100, + "calorieContent": 1400 + }, + "Sashimi": { + "name": "Sashimi", + "waterContent": 75, + "calorieContent": 800 + }, + "Seafoam Pudding": { + "name": "Seafoam Pudding", //pudding made from fish and squid ink? I love seafood, but even this seems too much... + "waterContent": 150, + "calorieContent": 1160 //4 cups of generic pudding + }, + "Shrimp Cocktail": { + "name": "Shrimp Cocktail", + "waterContent": 150, + "calorieContent": 550 //Boosted to exceed ingredient sum + }, + "Spaghetti": { + "name": "Spaghetti", + "waterContent": 100, + "calorieContent": 1200 //4 cups + }, + "Spicy Eel": { + "name": "Spicy Eel", + "waterContent": -250, + "calorieContent": 1300 //fried eel copy + }, + "Squid Ink Ravioli": { + "name": "Squid Ink Ravioli", + "waterContent": 100, + "calorieContent": 1200 //4 cups + }, + "Stir Fry": { + "name": "Stir Fry", + "waterContent": 50, + "calorieContent": 800 //4 cups stirfry veggies on rice + }, + "Strange Bun": { + "name": "Strange Bun", //Sea slug and burnt hair mayonaise.... Yum.... + "waterContent": 50, + "calorieContent": 800 + }, + "Stuffing": { + "name": "Stuffing", + "waterContent": 50, + "calorieContent": 1400 //4 cups + }, + "Sugar": { + "name": "Sugar", //Beets UOM is 4 beets per item to get calorie. 1 beet has about 6g sugar, 20 24g per 1 item. Therefore, 8g of sugar per 1 sugar item. + "waterContent": 0, + "calorieContent": 35 + }, + "Super Meal": { + "name": "Super Meal", + "waterContent": 100, + "calorieContent": 560 //4 cups 'super foods salad' + }, + "Survivor Burger": { + "name": "Survivor Burger", + "waterContent": 50, + "calorieContent": 1400 //4 veggie burgers + }, + "Tom Kha Soup": { + "name": "Tom Kha Soup", + "waterContent": 250, + "calorieContent": 1040 //8 cups + }, + "Tortilla": { + "name": "Tortilla", + "waterContent": 25, + "calorieContent": 150 //1 large tortilla, what can be made from 1 large ear of corn + }, + "Triple Shot Espresso": { + "name": "Triple Shot Espresso", + "waterContent": 115, //4 oz + "calorieContent": 0 + }, + "Tropical Curry": { + "name": "Tropical Curry", + "waterContent": 240, + "calorieContent": 960 //4 cups coconut pineapple thai curry + }, + "Trout Soup": { + "name": "Trout Soup", + "waterContent": 240, + "calorieContent": 800 //4 cups + }, + "Vegetable Medley": { + "name": "Vegetable Medley", + "waterContent": 75, + "calorieContent": 550 + }, + "Wheat Flour": { + "name": "Wheat Flour", + "waterContent": 0, + "calorieContent": 400 //half cup + }, + "Cola": { + "name": "Cola", + "waterContent": 240, + "calorieContent": 100 + }, + "Espresso": { + "name": "Espresso", + "waterContent": 44, + "calorieContent": 8 + }, + "Coffee": { + "name": "Coffee", + "waterContent": 240, + "calorieContent": 50 + }, + "Wine": { + "name": "Wine", + "waterContent": 148, + "calorieContent": 123 + }, + "Beer": { + "name": "Beer", + "waterContent": 355, + "calorieContent": 154 + }, + "Tea": { + "name": "Tea", + "waterContent": 240, + "calorieContent": 2 + }, + "Juice": { + "name": "Juice", + "waterContent": 240, + "calorieContent": 114 + } + }, + "Underwear_Options": { + "bed": { + "name": "bed", + "description": "cozy bed", + "absorbency": 2500.0, + "containment": 1000.0, + "spriteIndex": -1, + "price": 0, + "washable": true, + "plural": false, + "dryingTime": 2400, + "removable": false, + "durability": -1 + }, + "blue jeans": { + "name": "blue jeans", + "description": "sturdy blue jeans", + "absorbency": 400.0, + "containment": 600.0, + "spriteIndex": -1, + "price": 2000, + "washable": true, + "plural": true, + "dryingTime": 600, + "removable": true, + "durability": -1 + }, + "legs": { + "name": "legs", + "description": "your two legs", + "absorbency": 10.0, + "containment": 10.0, + "spriteIndex": -1, + "price": 2000, + "washable": true, + "plural": true, + "dryingTime": 600, + "removable": false, + "durability": -1 + }, + "black thong": { + "name": "black thong", + "description": "lacy black thong, not absorbend or durable", + "absorbency": 75.0, + "containment": 75.0, + "spriteIndex": 0, + "price": 120, + "washable": false, + "plural": false, + "dryingTime": 300, + "removable": true, + "durability": 1 + }, + "polka dot panties": { + "name": "polka dot panties", + "description": "simple white panties with pink polka dots", + "absorbency": 120.0, + "containment": 350.0, + "spriteIndex": 1, + "price": 50, + "washable": true, + "plural": true, + "dryingTime": 300, + "removable": true, + "durability": 3 + }, + "big kid undies": { + "name": "big kid undies", + "description": "cotton undies for big kids only", + "absorbency": 120.0, + "containment": 350.0, + "spriteIndex": 2, + "price": 30, + "washable": true, + "plural": true, + "dryingTime": 300, + "removable": true, + "durability": 4 + }, + "dinosaur undies": { + "name": "dinosaur undies", + "description": "green, lightly padded undies covered in adorable dinosaurs", + "absorbency": 400.0, + "containment": 600.0, + "spriteIndex": 3, + "price": 45, + "washable": true, + "plural": true, + "dryingTime": 500, + "removable": true, + "durability": 8 + }, + "lavender pullups": { + "name": "lavender pullups", + "description": "thick, soft and snug disposable flowery lavender pullups", + "absorbency": 1550.0, + "containment": 1400.0, + "spriteIndex": 4, + "price": 20, + "washable": false, + "plural": false, + "dryingTime": 0, + "removable": true, + "durability": 0 + }, + "training pants": { + "name": "training pants", + "description": "thin cloth potty training pants that look similar to big kid undies", + "absorbency": 850.0, + "containment": 1400.0, + "spriteIndex": 5, + "price": 60, + "washable": true, + "plural": true, + "dryingTime": 600, + "removable": true, + "durability": 6 + }, + "joja diaper": { + "name": "joja diaper", + "description": "thin white and cheap plastic diaper from JojaMart", + "absorbency": 1800.0, + "containment": 1400.0, + "spriteIndex": 6, + "price": 15, + "washable": false, + "plural": false, + "dryingTime": 0, + "removable": false, + "durability": 0 + }, + "baby print diaper": { + "name": "baby print diaper", + "description": "little soft and crinkly fresh-scented disposable baby print diaper, made for big children. Its a bit small, but you can fit", + "absorbency": 1500.0, + "containment": 1200.0, + "spriteIndex": 7, + "price": 12, + "washable": false, + "plural": false, + "dryingTime": 0, + "removable": false, + "durability": 0 + }, + "cloth diaper": { + "name": "cloth diaper", + "description": "thick and soft white cloth diaper", + "absorbency": 1400.0, + "containment": 2600.0, + "spriteIndex": 8, + "price": 60, + "washable": true, + "plural": false, + "dryingTime": 1000, + "removable": false, // washable was redefined as the ability to take it off and wash. Removable controls if you can quickly get out of it (pull-up) + "durability": 6 + }, + "space diaper": { + "name": "space diaper", + "description": "very thick and soft blue plastic diaper with spaceship designs", + "absorbency": 2700.0, + "containment": 2800.0, + "spriteIndex": 9, + "price": 30, + "washable": false, + "plural": false, + "dryingTime": 0, + "removable": false, + "durability": 0 + }, + "pawprint diaper": { + "name": "pawprint diaper", + "description": "puffy plastic diaper with cute animal prints and fade-when-wet little paws", + "absorbency": 2700.0, + "containment": 2700.0, + "spriteIndex": 10, + "price": 35, + "washable": false, + "plural": false, + "dryingTime": 0, + "removable": false, + "durability": 0 + }, + "heart diaper": { + "name": "heart diaper", + "description": "extremly thick and soft pink plastic diaper with a large fade-when-wet heart on the front", + "absorbency": 3400.0, + "containment": 3500.0, + "spriteIndex": 11, + "price": 50, + "washable": false, + "plural": false, + "dryingTime": 0, + "removable": false, + "durability": 0 + } + } } diff --git a/doorstop_config.ini b/doorstop_config.ini new file mode 100644 index 0000000..f851ad6 --- /dev/null +++ b/doorstop_config.ini @@ -0,0 +1,39 @@ +# General options for Unity Doorstop +[General] + +# Enable Doorstop? +enabled = true + +# Path to the assembly to load and execute +# NOTE: The entrypoint must be of format `static void Doorstop.Entrypoint.Start()` +target_assembly=BepInEx\core\BepInEx.Preloader.dll + +# If true, Unity's output log is redirected to \output_log.txt +redirect_output_log = true + +# Overrides the default boot.config file path +boot_config_override = + +# If enabled, DOORSTOP_DISABLE env var value is ignored +# USE THIS ONLY WHEN ASKED TO OR YOU KNOW WHAT THIS MEANS +ignore_disable_switch = true + +# Options specific to running under Unity Mono runtime +[UnityMono] + +# Overrides default Mono DLL search path +# Sometimes it is needed to instruct Mono to seek its assemblies from a different path +# (e.g. mscorlib is stripped in original game) +# This option causes Mono to seek mscorlib and core libraries from a different folder before Managed +# Original Managed folder is added as a secondary folder in the search path +# To specify multiple paths, separate them with semicolons (;) +dll_search_path_override = + +# If true, Mono debugger server will be enabled +debug_enabled = false + +# When debug_enabled is true, specifies the address to use for the debugger server +debug_address = 127.0.0.1:10000 + +# If true and debug_enabled is true, Mono debugger server will suspend the game execution until a debugger is attached +debug_suspend = false \ No newline at end of file diff --git a/winhttp.dll b/winhttp.dll new file mode 100644 index 0000000..9a48b80 Binary files /dev/null and b/winhttp.dll differ