From daf09332115e9bf0c4d5d191f3a0b283c9a56164 Mon Sep 17 00:00:00 2001 From: Proximitron Date: Thu, 5 Dec 2024 00:41:23 +0100 Subject: [PATCH 1/9] Major patch, balancing pass, potty training behaviours (leaking) and fixes for shops --- Regression/PrimevalTitmouse/Animations.cs | 116 ++- Regression/PrimevalTitmouse/Body.cs | 807 ++++++++++++------- Regression/PrimevalTitmouse/Config.cs | 4 + Regression/PrimevalTitmouse/Data.cs | 12 +- Regression/PrimevalTitmouse/Mail.cs | 11 +- Regression/PrimevalTitmouse/Regression.cs | 67 +- Regression/PrimevalTitmouse/Strings.cs | 168 ++-- Regression/Regression Dialogue/Content.json | 2 +- Regression/Regression Dialogue/manifest.json | 2 +- Regression/Regression.csproj | 2 +- Regression/config.json | 4 + Regression/en.json | 172 ++-- doorstop_config.ini | 39 + winhttp.dll | Bin 0 -> 26112 bytes 14 files changed, 896 insertions(+), 510 deletions(-) create mode 100644 doorstop_config.ini create mode 100644 winhttp.dll diff --git a/Regression/PrimevalTitmouse/Animations.cs b/Regression/PrimevalTitmouse/Animations.cs index 65d6979..bf07542 100644 --- a/Regression/PrimevalTitmouse/Animations.cs +++ b/Regression/PrimevalTitmouse/Animations.cs @@ -39,13 +39,13 @@ internal static class Animations 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; @@ -111,9 +111,6 @@ public static void AnimateDryingBedding(Body 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"); @@ -138,6 +135,8 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) else Say(Animations.GetData().Mess_Accident, b); + Animations.GetWho().doEmote(12, false); + if (b.IsFishing() || !Animations.GetWho().canMove) return; // We skip the actual animations if nessesary //Animations.GetWho().forceCanMove(); //Animations.GetWho().completelyStopAnimatingOrDoingAction(); Animations.GetWho().jitterStrength = 1.0f; @@ -145,7 +144,6 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) Animations.GetWho().freezePause = poopAnimationTime; Animations.GetWho().canMove = false; - Animations.GetWho().doEmote(12, false); } public static void AnimateMessingEnd(Body b) { @@ -154,13 +152,16 @@ public static void AnimateMessingEnd(Body b) 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)); } + public static void AnimateMessingMinor(Body b) + { + Animations.Say(Animations.GetData().Bowels_Leak, b); + ((Character)Animations.GetWho()).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; @@ -171,7 +172,7 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) return; } - if (!inUnderwear) + if (!inUnderwear) { if (b.InToilet(inUnderwear)) Animations.Say(Animations.GetData().Pee_Toilet, b); @@ -188,6 +189,8 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) else Animations.Say(Animations.GetData().Wet_Accident, b); + // We skip the actual animations if nessesary + if (b.IsFishing() || !Animations.GetWho().canMove) return; //Animations.GetWho().forceCanMove(); //Animations.GetWho().completelyStopAnimatingOrDoingAction(); Animations.GetWho().jitterStrength = 0.5f; @@ -195,6 +198,12 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) Animations.GetWho().canMove = false; ((Character)Animations.GetWho()).doEmote(28, false); } + public static void AnimateWettingMinor(Body b) + { + Animations.Say(Animations.GetData().Bladder_Leak, b); + ((Character)Animations.GetWho()).doEmote(28, false); + } + public static void AnimateWettingEnd(Body b) { @@ -232,8 +241,8 @@ 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; + if (!(first | second) || !b.IsAllowedResource(IncidentType.PEE) && !b.IsAllowedResource(IncidentType.POOP)) + return; string toiletMsg = Strings.ReplaceAndOr(Strings.RandString(Animations.GetData().Toilet_Night), first, second, "&"); if (b.numAccidentPooAtNight == 0 && b.numAccidentPeeAtNight == 0) @@ -244,7 +253,8 @@ public static void AnimateNight(Body b) { 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 + } + else { toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", ", but you still woke up$HOW_MANY_TIMES"); } @@ -285,7 +295,10 @@ public static void AnimatePoopAttempt(Body b, bool inUnderwear) 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(Animations.GetData().Still_Soiled); + + baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.name, true)); + Animations.Say(baseString, b); } public static void AnimateWashingUnderwear(Container c) @@ -309,31 +322,48 @@ public static void CheckPants(Body b) b.pants.plural = true; Animations.Say(Animations.GetData().LookPants[0] + " " + Strings.DescribeUnderwear(b.pants, null) + ".", b); } + public static bool WarnCurrentThreshold(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; + + Animations.Warn(messages[index]); + return true; + } + return false; + } 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) + { + float newFullness = b.bladderFullness / b.bladderCapacity; + + bool pottyMessage = false; + if (newFullness > (1 - b.bladderContinence)) + { + pottyMessage = WarnCurrentThreshold(Body.WETTING_THRESHOLDS, Body.WETTING_MESSAGES, newFullness, false); // index offset is 1, because we want the current, not next message + } + if (!pottyMessage) Warn(Body.WETTING_MESSAGE_GREEN); + + newFullness = b.bowelFullness / b.bowelCapacity; + pottyMessage = false; + if (newFullness > (1 - b.bowelContinence)) + { + pottyMessage = WarnCurrentThreshold(Body.MESSING_THRESHOLDS, Body.MESSING_MESSAGES, newFullness, false); // index offset is 1, because we want the current, not next message } + if (!pottyMessage) Warn(Body.MESSING_MESSAGE_GREEN); } public static void CheckUnderwear(Body b) { @@ -351,12 +381,12 @@ public static void DrawUnderwearIcon(Container c, int x, int y) ((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, (string)null, -1, (string[])null, (Item)null, 0, null, -1, -1, -1, 1f, (CraftingRecipe)null); + } } private static void EndDrinking(Farmer who) @@ -379,7 +409,7 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over int radius = 3; bool someoneNoticed = true; - float actualLoss = -(baseFriendshipLoss/100); + float actualLoss = -(baseFriendshipLoss / 100); //If we are messing, increase the radius of noticeability (stinky) // OLD: Double how much friendship we lose (mess is gross) @@ -480,7 +510,7 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over if (Regression.config.Debug) Animations.Say(string.Format("{0} ({1}) changed friendship from {2} by {3}.", npc.Name, npc.Age, heartLevelForNpc, 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) Animations.GetWho().changeFriendship(finalLossValue, npc); diff --git a/Regression/PrimevalTitmouse/Body.cs b/Regression/PrimevalTitmouse/Body.cs index 0a29af3..5180e61 100644 --- a/Regression/PrimevalTitmouse/Body.cs +++ b/Regression/PrimevalTitmouse/Body.cs @@ -3,9 +3,11 @@ using StardewValley; using StardewValley.Buffs; using StardewValley.Locations; +using StardewValley.Minigames; using StardewValley.Tools; using System; using System.Reflection; +using static PrimevalTitmouse.Container; namespace PrimevalTitmouse { @@ -13,30 +15,33 @@ namespace PrimevalTitmouse public class Body { //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 requiredCaloriesPerDay = 3000f; // I adjusted it from 3500 to 3000, because the farmer still eats half the farm every day 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 //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. + private static readonly float maxBladderCapacity = Regression.config.MaxBladderCapacity; //about 600mL => changed to 800mL as player will start with lower bladder by default + private static readonly float minBladderContinence = 0.3f; // 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 maxBowelCapacity = (requiredCaloriesPerDay*foodToBowelConversion) / 2f / 1200f * Regression.config.MaxBowelCapacity; // The last 2 numbers usually end up as / 1200 * 1200 (cancle eachother out) to make configuration easier to understand + private static readonly float minBowelContinence = 0.3f; // 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 }; + private 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.5f, 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.5f, 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 }; @@ -48,11 +53,9 @@ public class Body //Things that describe an individual public int bedtime = 0; - public float bladderCapacity = maxBladderCapacity; - public float bladderContinence = 1f; + public float bladderContinence = Math.Min(1f, Math.Max(minBowelContinence, Regression.config.StartBladderContinence / 100f)); public float bladderFullness = 0f; - public float bowelCapacity = maxBowelCapacity; - public float bowelContinence = 1f; + public float bowelContinence = Math.Min(1f, Math.Max(minBowelContinence, Regression.config.StartBowelContinence / 100f)); public float bowelFullness = 0f; public float hunger = 0f; public float thirst = 0f; @@ -66,34 +69,170 @@ public class Body public int numAccidentPeeAtNight = 0; 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); + } + } + 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 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; @@ -114,61 +253,44 @@ 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) + if (fullness >= capacity) { - Wet(voluntary: false, inUnderwear: true); - newFullness = bladderFullness / maxBladderCapacity; - //Otherwise, calculate the new value - } 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 : bladderContinence / (4f * newFullness)) > Regression.rnd.NextDouble()) + if (!isSleeping) { - Warn(1-oldFullness, 1-newFullness, WETTING_THRESHOLDS, WETTING_MESSAGES, false); + if (MinorAccident(type)) return; } - } - } - - //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) - { - Mess(voluntary: false, inUnderwear: true); + Accident(type, voluntary: false, 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); } } } @@ -185,12 +307,12 @@ public void AddFood(float amount, float conversionRatio = 1f) //Convert food lost into poo at half rate if (amount < 0 && hunger < requiredCaloriesPerDay) - AddBowel(amount * -1f * conversionRatio * foodToBowelConversion); + AddResource(IncidentType.POOP, amount * -1f * 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; } @@ -222,12 +344,12 @@ public void AddWater(float amount, float conversionRatio = 1f) //Convert water lost into pee at half rate if (amount < 0 && thirst < requiredWaterPerDay) - AddBladder(amount * -1f * conversionRatio * waterToBladderConversion); + AddResource(IncidentType.PEE, amount * -1f * 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,78 +373,49 @@ 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); - - //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; + //Change of bladder capacity is no longer nessesary. Handled by getter. if (Regression.config.Debug) - Animations.Say(string.Format("Bowel continence changed from {0} to {1}, bowel capacity now {2}", previousContinence, bowelContinence, bowelCapacity), (Body)null); + Animations.Say(string.Format("{0} continence changed by {1} to {2}, {0} capacity now {3}", type == IncidentType.POOP ? "Bowel": "Bladder", previousContinence, GetContinence(type), GetCapacity(type)), (Body)null); - //Inform about major changes - Warn(previousContinence, bowelContinence, BOWEL_CONTINENCE_THRESHOLDS, BOWEL_CONTINENCE_MESSAGES, true); + //Warn that we may be losing control + 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) { Container oldUnderwear = this.underwear; - if (!oldUnderwear.removable) + if (!oldUnderwear.removable && !oldUnderwear.washable) Animations.Warn(Regression.t.Change_Destroyed, this); this.underwear = container; - pants = CreateNewPants(); - CleanPants(); + ChangePants(); Animations.Say(Regression.t.Change, this); return oldUnderwear; } + public void ChangePants() + { + pants = CreateNewPants(); + CleanPants(); + } public StardewValley.Objects.Clothing GetPantsStardew() { @@ -336,17 +429,13 @@ public Container CreateNewPants() { var myPants = GetPantsStardew(); Container newPants; - Regression.t.Underwear_Options.TryGetValue("blue jeans", out newPants); + Regression.t.Underwear_Options.TryGetValue(myPants == null ? "legs" : "blue jeans", out newPants); var newObject = new Container(newPants); + if (myPants != null) { - newObject.name = myPants.displayName; - newObject.description = myPants.description; - } - else - { - newObject.name = "Legs"; - newObject.description = "Your two Legs"; + newObject.name = myPants.displayName.ToLower(); + newObject.description = myPants.description.ToLower(); } return newObject; } @@ -382,16 +471,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() @@ -432,40 +521,151 @@ public bool InPlaceWithPants() { return Game1.currentLocation is FarmHouse; } + public bool IsTryingToHoldIt(IncidentType type, float vsAmount) + { + float capacity; + float used; + switch (type) + { + case IncidentType.PEE: + capacity = underwear.absorbency; + used = underwear.wetness; + break; + case IncidentType.POOP: + capacity = underwear.containment; + used = underwear.messiness; + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } - public void Mess(bool voluntary = false, bool inUnderwear = true) + if (!underwear.removable) return false; // If we don't have pants or training pants, there is no point + if(used > 300) 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.pants.AddPee(this.underwear.AddPee(amount))); + } + else + { + _ = this.pants.AddPee(this.underwear.AddPee(amount)); + } + break; + case IncidentType.POOP: + if (isSleeping) + { + _ = this.bed.AddPoop(this.pants.AddPoop(this.underwear.AddPoop(amount))); + } + else + { + _ = this.pants.AddPoop(this.underwear.AddPoop(amount)); + } + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + + } + // Minor accidents (leaking) can happen before failure and is usually not causing someone else to notice + public void AccidentMinor(IncidentType type) { - numPottyPooAtNight = 0; - numAccidentPooAtNight = 0; + if (isSleeping) return; + + + } + public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear = true) + { + float attemptThreshold = GetAttemptThreshold(type); + float capacity = GetCapacity(type); + float fullness = GetFullness(type); + float continence = GetContinence(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 = continence - (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++) { //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; + bool lclVoluntary = voluntary || Regression.rnd.NextDouble() < (double)continence; + 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 { @@ -473,75 +673,195 @@ public void Mess(bool voluntary = false, bool inUnderwear = true) bowelFullness -= amountToLose; 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++; + ChangeContinence(type, CalculateContinenceLossOrGain(type, voluntary, inUnderwear, amountToLose / maxCapacity)); // maxCapacity is correct, for balancing reasons + AddAccidentFromFullness(type, amountToLose); + numAccident++; } } } - 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, -this.bowelFullness); } + FinalizeAccident(type, voluntary, true, attemptOnly); // Trying in your underwear is different, people might be acting differently } + } } + public void Mess(bool voluntary = false, bool inUnderwear = true) + { + Accident(IncidentType.POOP,voluntary,inUnderwear); + } + public void StartAccident(IncidentType type, bool voluntary = false, bool inUnderwear = true) + { + switch (type) + { + 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()); + } + float attemptThreshold = GetAttemptThreshold(type); + float fullness = GetFullness(type); - public void StartMessing(bool voluntary = false, bool inUnderwear = true) + if (fullness < attemptThreshold) + { + 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()); + } + } + else + { + 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(this); + break; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + // 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) { - if (!Regression.config.Messing) - return; + float fullness = GetFullness(type); - if (bowelFullness < GetBowelAttemptThreshold()) + int rate; + if (voluntary) { - Animations.AnimatePoopAttempt(this, inUnderwear); + rate = type == IncidentType.POOP ? Regression.config.BowelGainContinenceRate : Regression.config.BladderGainContinenceRate; } else { + rate = type == IncidentType.POOP ? Regression.config.BowelLossContinenceRate : Regression.config.BladderLossContinenceRate; + } - //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); + //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) + return -0.01f * rate * percentLost * situationMultiplier(voluntary, inUnderwear); + else if (fullness > GetTrainingThreshold(type)) + return 0.01f * rate * percentLost * situationMultiplier(voluntary, inUnderwear); + else + { + return 0f; } - - Animations.AnimateMessingEnd(this); + } + 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, true, inUnderwear, pants.messiness > 0.0, false); - if (pants.messiness <= 0.0 || !inUnderwear) + _ = Animations.HandleVillager(this, type == IncidentType.POOP, inUnderwear, dirt > 0, false); + if (attemptOnly || dirt <= 0.0 || !inUnderwear) return; - HandlePoopOverflow(); + HandleOverflow(type); } - private void HandlePoopOverflow() + private void HandleOverflow(IncidentType type) { if (isSleeping) return; + 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, Animations.peeAnimationTime); + + int defenseReduction = -Math.Max(Math.Min((int)(pants.wetness / pants.absorbency * 10.0), 10), 1); + + Buff buff = new Buff(id: WET_DEBUFF, displayName: "Wet", effects: new BuffEffects() + { + Defense = { defenseReduction } + }) + { + description = string.Format("{0} {1} Defense.", Strings.RandString(Regression.t.Debuff_Wet_Pants), defenseReduction), + millisecondsDuration = 1080000, + glow = pants.messiness != 0.0 ? Color.Brown : Color.Yellow + }; + if (Game1.player.hasBuff(WET_DEBUFF)) + this.RemoveBuff(WET_DEBUFF); + Game1.player.applyBuff(buff); + } + + private void _HandlePoopOverflow() + { 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; @@ -579,125 +899,9 @@ public float situationMultiplier(bool voluntary, bool inUnderwear) return multiplier; } - public void StartWetting(bool voluntary = false, bool inUnderwear = true) - { - - if ((double)bladderFullness < GetBladderAttemptThreshold()) - { - Animations.AnimatePeeAttempt(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.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); - } - - Animations.AnimateWettingEnd(this); - if (!this.InToilet(inUnderwear)) - _ = Animations.HandleVillager(this, false, inUnderwear, pants.wetness > 0.0, false); - if ((pants.wetness <= 0.0 || !inUnderwear)) - return; - HandlePeeOverflow(); - } - private void HandlePeeOverflow() - { - if (isSleeping) - return; - - Animations.Write(Regression.t.Pee_Overflow, this, Animations.peeAnimationTime); - - int defenseReduction = -Math.Max(Math.Min((int)(pants.wetness / pants.absorbency * 10.0), 10), 1); - - Buff buff = new Buff(id: WET_DEBUFF, displayName: "Wet", effects: new BuffEffects() - { - Defense = { defenseReduction } - }) - { - description = string.Format("{0} {1} Defense.", Strings.RandString(Regression.t.Debuff_Wet_Pants), defenseReduction), - millisecondsDuration = 1080000, - glow = pants.messiness != 0.0 ? Color.Brown : Color.Yellow - }; - if (Game1.player.hasBuff(WET_DEBUFF)) - this.RemoveBuff(WET_DEBUFF); - Game1.player.applyBuff(buff); - } - public void Wet(bool voluntary = false, bool inUnderwear = true) { - 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 - 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; - } - 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 - { - StartWetting(voluntary, false); - if (underwear.removable) { - if (bladderFullness >= GetBladderAttemptThreshold()) - { - this.bladderFullness = 0.0f; - } - } - } - if (bladderFullness < 0) bladderFullness = 0; + Accident(IncidentType.PEE,voluntary,inUnderwear); } public void HandleMorning() @@ -733,6 +937,8 @@ public void HandleMorning() Animations.AnimateMorning(this); bed.Wash(); + pants = CreateNewPants(); + CleanPants(); } public void HandleNight() @@ -843,4 +1049,9 @@ public void Consume(string itemName) } } } + public enum IncidentType + { + PEE, + POOP + } } diff --git a/Regression/PrimevalTitmouse/Config.cs b/Regression/PrimevalTitmouse/Config.cs index 37caef8..f9a1764 100644 --- a/Regression/PrimevalTitmouse/Config.cs +++ b/Regression/PrimevalTitmouse/Config.cs @@ -20,5 +20,9 @@ public class Config public int BowelLossContinenceRate; public int BladderGainContinenceRate; public int BowelGainContinenceRate; + public int MaxBladderCapacity; + public int MaxBowelCapacity; + public int StartBladderContinence; + public int StartBowelContinence; } } diff --git a/Regression/PrimevalTitmouse/Data.cs b/Regression/PrimevalTitmouse/Data.cs index effebf6..23f1867 100644 --- a/Regression/PrimevalTitmouse/Data.cs +++ b/Regression/PrimevalTitmouse/Data.cs @@ -11,21 +11,27 @@ 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_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; @@ -52,6 +58,8 @@ public class Data public string[] Toilet_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; diff --git a/Regression/PrimevalTitmouse/Mail.cs b/Regression/PrimevalTitmouse/Mail.cs index afbbd9d..5496642 100644 --- a/Regression/PrimevalTitmouse/Mail.cs +++ b/Regression/PrimevalTitmouse/Mail.cs @@ -23,13 +23,14 @@ 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)); // it needs definitly a bit of food at the start + //initialSupplies.Add(new Underwear("pawprint diaper", 0.0f, 0.0f, 40)); + 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" //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/Regression.cs b/Regression/PrimevalTitmouse/Regression.cs index e3c24be..5da1cca 100644 --- a/Regression/PrimevalTitmouse/Regression.cs +++ b/Regression/PrimevalTitmouse/Regression.cs @@ -33,6 +33,9 @@ public class Regression : Mod const float timeInTick = (1f/43f); //One second realtime ~= 1/43 hours in game public override void Entry(IModHelper h) { + //var harmony = new Harmony("com.primevaltitmouse.regression"); + //harmony.PatchAll(); + help = h; monitor = Monitor; config = Helper.ReadConfig(); @@ -269,25 +272,27 @@ 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; } @@ -311,9 +316,18 @@ private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) case SButton.F7: Animations.CheckContinence(body); break; + case SButton.F8: + Animations.CheckPottyFeeling(body); + break; case SButton.F9: config.Debug = !config.Debug; break; + case SButton.F10: + body.MinorAccident(IncidentType.PEE); + break; + case SButton.F11: + body.MinorAccident(IncidentType.POOP); + break; } } } @@ -361,14 +375,14 @@ private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) if(Game1.currentLocation is SeedShop) { //The seed shop does not sell the Joja diaper - availableUnderwear.Remove("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"); + availableUnderwear.Add("joja diaper"); + availableUnderwear.Add("cloth diaper"); underwearAvailableAtShop = true; } @@ -378,7 +392,7 @@ private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) { Underwear underwear = new Underwear(type, 0.0f, 0.0f, 1); currentShopMenu.forSale.Add(underwear); - currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, 999)); + currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, StardewValley.Menus.ShopMenu.infiniteStock)); } } } @@ -418,6 +432,39 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) //Handle a Left Click 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.ChangePants(); + 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; @@ -439,7 +486,7 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) { 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 @@ -447,7 +494,7 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) Underwear underwear = new Underwear(container.name, container.wetness, container.messiness, 1); //If the underwear returned is not removable, destroy it - if (!container.removable) { } + if (!container.removable && !container.washable) { } //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)) { diff --git a/Regression/PrimevalTitmouse/Strings.cs b/Regression/PrimevalTitmouse/Strings.cs index 6c26a52..a8a16a4 100644 --- a/Regression/PrimevalTitmouse/Strings.cs +++ b/Regression/PrimevalTitmouse/Strings.cs @@ -6,105 +6,107 @@ 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 = Strings.ReplaceOptional(Strings.t.Underwear_Messy[index].Replace("$UNDERWEAR_DESC$", newValue), (double) num1 > 0.0); - break; + newValue = !u.IsDrying() ? Strings.t.Underwear_Clean.Replace("$UNDERWEAR_DESC$", newValue) : Strings.t.Underwear_Drying.Replace("$UNDERWEAR_DESC$", newValue); } - } - } - 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) + else { - 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; + 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; + } + } + } } - } - } - } - return u.GetPrefix() + " " + newValue; + if (noPrefix) return newValue; + return u.GetPrefix() + " " + newValue; } 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); - } + { + 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; + 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) + { + 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" : ""); + } - public static string ReplaceOr(string str, bool first, string splitChar = "/") - { - return new Regex("<([^>" + splitChar + "]*)" + splitChar + "([^>]*)>").Replace(str, first ? "$1" : "$2"); - } + 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("blue jeans"); - list.Remove("bed"); - return list; + 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/Regression Dialogue/Content.json b/Regression/Regression Dialogue/Content.json index 08311c5..ebc0c09 100644 --- a/Regression/Regression Dialogue/Content.json +++ b/Regression/Regression Dialogue/Content.json @@ -35,6 +35,6 @@ "LogName": "Jas", "Action": "Include", "FromFile": "Dialogue/NPCs/Jas.json" - }, + } ] } \ 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..64d4aea 100644 --- a/Regression/Regression.csproj +++ b/Regression/Regression.csproj @@ -60,7 +60,7 @@ - + diff --git a/Regression/config.json b/Regression/config.json index 13d689e..9a93dfe 100644 --- a/Regression/config.json +++ b/Regression/config.json @@ -17,5 +17,9 @@ "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 + "MaxBladderCapacity": 600, // 600 is around 3 potty runs a day + "MaxBowelCapacity": 1200, // 1200 is around 1.5 potty runs a day + "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. "Lang": "en" } \ No newline at end of file diff --git a/Regression/en.json b/Regression/en.json index 5dd4a3d..77160f7 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -26,11 +26,15 @@ "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.", + "You need to pee soon.", "You should find somewhere to pee soon.", "You feel like you might pee soon.", - "Your bladder is getting full." + "Your bladder is slowly getting full." ], "Bladder_Orange": [ "You really need to pee!", @@ -40,8 +44,18 @@ ], "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$!" + "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.", @@ -58,6 +72,12 @@ "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." ], @@ -141,16 +161,16 @@ "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 !" + "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$ soon, but not right now. It's still warm", + "You press your hand into your squishy $UNDERWEAR_LONGDESC$. You feel like a little baby in .", + "You feel your $UNDERWEAR_LONGDESC$. all squishy!" ], "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$.", @@ -518,6 +538,12 @@ "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" ], @@ -526,7 +552,8 @@ ], "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$", @@ -1449,8 +1476,8 @@ "blue jeans": { "name": "blue jeans", "description": "sturdy blue jeans", - "absorbency": 300.0, - "containment": 60.0, + "absorbency": 400.0, + "containment": 600.0, "spriteIndex": -1, "price": 2000, "washable": true, @@ -1459,91 +1486,104 @@ "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", + "description": "lacy black thong, not absorbend or durable", "absorbency": 75.0, - "containment": 60.0, + "containment": 75.0, "spriteIndex": 0, - "price": 10, - "washable": true, + "price": 100, + "washable": false, "plural": false, "dryingTime": 300, "removable": true, - "durability": 4 + "durability": 1 }, "polka dot panties": { "name": "polka dot panties", "description": "simple white panties with pink polka dots", - "absorbency": 150.0, - "containment": 100.0, + "absorbency": 120.0, + "containment": 350.0, "spriteIndex": 1, - "price": 10, + "price": 50, "washable": true, "plural": true, - "dryingTime": 400, + "dryingTime": 300, "removable": true, - "durability": 4 + "durability": 3 }, "big kid undies": { "name": "big kid undies", "description": "cotton undies for big kids only", - "absorbency": 150.0, - "containment": 115.0, + "absorbency": 120.0, + "containment": 350.0, "spriteIndex": 2, - "price": 10, + "price": 40, "washable": true, "plural": true, - "dryingTime": 400, + "dryingTime": 300, "removable": true, "durability": 4 }, "dinosaur undies": { "name": "dinosaur undies", - "description": "green undies covered in adorable dinosaurs", - "absorbency": 150.0, - "containment": 115.0, + "description": "green, lightly padded undies covered in adorable dinosaurs", + "absorbency": 400.0, + "containment": 600.0, "spriteIndex": 3, - "price": 10, + "price": 35, "washable": true, "plural": true, - "dryingTime": 400, + "dryingTime": 500, "removable": true, - "durability": 4 + "durability": 8 }, "lavender pullup": { - "name": "lavender pullup", - "description": "soft and snug flowery lavender pullup", - "absorbency": 600.0, - "containment": 170.0, + "name": "lavender pullups", + "description": "thick, soft and snug disposable flowery lavender pullups", + "absorbency": 1550.0, + "containment": 1400.0, "spriteIndex": 4, "price": 25, "washable": false, - "plural": false, + "plural": true, "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, + "description": "thin cloth potty training pants that look similar to big kid undies", + "absorbency": 850.0, + "containment": 1400.0, "spriteIndex": 5, - "price": 25, + "price": 80, "washable": true, "plural": true, "dryingTime": 600, "removable": true, - "durability": 5 + "durability": 6 }, - "Joja diaper": { + "joja diaper": { "name": "Joja diaper", - "description": "thin white plastic diaper from JojaMart", - "absorbency": 1200.0, - "containment": 300.0, + "description": "thin white and cheap plastic diaper from JojaMart", + "absorbency": 1100.0, + "containment": 1400.0, "spriteIndex": 6, - "price": 50, + "price": 30, "washable": false, "plural": false, "dryingTime": 0, @@ -1552,9 +1592,9 @@ }, "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", + "description": "little soft and crinkly fresh-scented disposable baby print diaper. Its a bit small, but you can fit", "absorbency": 1500.0, - "containment": 1000.0, + "containment": 1200.0, "spriteIndex": 7, "price": 75, "washable": false, @@ -1563,24 +1603,24 @@ "removable": false, "durability": 0 }, - "Cloth diaper": { + "cloth diaper": { "name": "Cloth diaper", "description": "thick and soft white cloth diaper", - "absorbency": 2000.0, - "containment": 1500.0, + "absorbency": 1400.0, + "containment": 2600.0, "spriteIndex": 8, - "price": 500, + "price": 260, "washable": true, "plural": false, - "dryingTime": 800, - "removable": true, - "durability": 8 + "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": 2700.0, + "containment": 2800.0, "spriteIndex": 9, "price": 100, "washable": false, @@ -1604,11 +1644,11 @@ }, "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, + "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": 120, + "price": 140, "washable": false, "plural": false, "dryingTime": 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 0000000000000000000000000000000000000000..9a48b80e089e539008469469bbb40fa3715a227e GIT binary patch literal 26112 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 Wz5ONIL}WfHJC Date: Thu, 5 Dec 2024 13:43:15 +0100 Subject: [PATCH 2/9] "Field Snacks" as starting food --- Regression/PrimevalTitmouse/Mail.cs | 4 +++- Regression/en.json | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Regression/PrimevalTitmouse/Mail.cs b/Regression/PrimevalTitmouse/Mail.cs index 5496642..35e8815 100644 --- a/Regression/PrimevalTitmouse/Mail.cs +++ b/Regression/PrimevalTitmouse/Mail.cs @@ -23,7 +23,9 @@ public static void CheckMail() initialSupplies = new(); letterShown = false; //Always give turnips and diapers - initialSupplies.Add(new StardewValley.Object("399", 40, false, -1, 0)); // it needs definitly a bit of food at the start + //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", 0.0f, 0.0f, 5)); // training pants are washable, they might be a good start equipment and are "not that great" //If we're in Hard mode, also give pull-up. diff --git a/Regression/en.json b/Regression/en.json index 77160f7..964dd17 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -915,7 +915,12 @@ "Spring Onion": { "name": "Spring Onion", "waterContent": 25, - "calorieContent": 800 //One hundred large scallions, only because this is the "starter" food + "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", From 94f7738ad283255c46adb20089ffb55ebfc1349d Mon Sep 17 00:00:00 2001 From: Proximitron Date: Sat, 7 Dec 2024 01:17:33 +0100 Subject: [PATCH 3/9] Partly multiplayer compatible, reworked entire save system to be backward compatible and use modStorage --- Regression/PrimevalTitmouse/Animations.cs | 12 +- Regression/PrimevalTitmouse/Body.cs | 271 ++++++++++----- Regression/PrimevalTitmouse/Config.cs | 2 + Regression/PrimevalTitmouse/Container.cs | 389 +++++++++++++++++----- Regression/PrimevalTitmouse/Data.cs | 1 + Regression/PrimevalTitmouse/Mail.cs | 2 +- Regression/PrimevalTitmouse/Regression.cs | 110 +++--- Regression/PrimevalTitmouse/Strings.cs | 21 +- Regression/PrimevalTitmouse/Underwear.cs | 111 ++++-- Regression/config.json | 4 +- Regression/en.json | 15 +- 11 files changed, 679 insertions(+), 259 deletions(-) diff --git a/Regression/PrimevalTitmouse/Animations.cs b/Regression/PrimevalTitmouse/Animations.cs index bf07542..04d39b7 100644 --- a/Regression/PrimevalTitmouse/Animations.cs +++ b/Regression/PrimevalTitmouse/Animations.cs @@ -297,10 +297,16 @@ public static void AnimateStillSoiled(Body b) { string baseString = Strings.RandString(Animations.GetData().Still_Soiled); - baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.name, true)); + baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); Animations.Say(baseString, b); } + public static void AnimateShouldChange(Body b) + { + string baseString = Strings.RandString(Animations.GetData().Should_Change); + baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); + Animations.Say(baseString, b); + } public static void AnimateWashingUnderwear(Container c) { if (c.MarkedForDestroy()) @@ -317,7 +323,7 @@ public static void AnimateWashingUnderwear(Container c) public static void CheckPants(Body b) { StardewValley.Objects.Clothing pants = b.GetPantsStardew(); - b.pants.name = pants.displayName; + b.pants.displayName = pants.displayName; b.pants.description = pants.displayName; b.pants.plural = true; Animations.Say(Animations.GetData().LookPants[0] + " " + Strings.DescribeUnderwear(b.pants, null) + ".", b); @@ -591,7 +597,7 @@ public static Microsoft.Xna.Framework.Rectangle UnderwearRectangle(Container c, } else { - if (!c.IsDrying()) + if (!c.drying) { if ((double)c.messiness <= .0f) { diff --git a/Regression/PrimevalTitmouse/Body.cs b/Regression/PrimevalTitmouse/Body.cs index 5180e61..da1249f 100644 --- a/Regression/PrimevalTitmouse/Body.cs +++ b/Regression/PrimevalTitmouse/Body.cs @@ -4,9 +4,11 @@ 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 @@ -14,11 +16,16 @@ 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 - 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 = 3000f; // I adjusted it from 3500 to 3000, because the farmer still eats half the farm every day - private static readonly float requiredWaterPerDay = 8000f; //8oz glasses: every 20min for 8 hours + every 40 min for 8 hour + 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 private static readonly float maxBladderCapacity = Regression.config.MaxBladderCapacity; //about 600mL => changed to 800mL as player will start with lower bladder by default @@ -26,8 +33,8 @@ public class Body 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 / 1200f * Regression.config.MaxBowelCapacity; // The last 2 numbers usually end up as / 1200 * 1200 (cancle eachother out) to make configuration easier to understand + private static readonly float foodToBowelConversion = 0.5f; // lowered from 0.67f to 0.5f to make the numbers smaller (too much poop) and bowel capacity / 1.5f (1000f in total) + private static readonly float maxBowelCapacity = (requiredCaloriesPerDay*foodToBowelConversion) / 1.5f / 1000f * Regression.config.MaxBowelCapacity; // The last 2 numbers usually end up as / 1200 * 1200 (cancle eachother out) to make configuration easier to understand private static readonly float minBowelContinence = 0.3f; // Also describes capacity as changes are linear //Setup Thresholds and messages @@ -51,22 +58,114 @@ public class Body private static readonly string WET_DEBUFF = "Regression.Wet"; private static readonly int wakeUpPenalty = 4; + 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 bladderContinence = Math.Min(1f, Math.Max(minBowelContinence, Regression.config.StartBladderContinence / 100f)); - public float bladderFullness = 0f; - public float bowelContinence = Math.Min(1f, Math.Max(minBowelContinence, Regression.config.StartBowelContinence / 100f)); - 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 @@ -92,12 +191,49 @@ public float bowelCapacity //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) @@ -400,21 +536,14 @@ public void ChangeContinence(IncidentType type, float percent = 0.01f) } //Put on underwear and clean pants - private Container ChangeUnderwear(Container container) + private void ChangeUnderwear(Container container) { - Container oldUnderwear = this.underwear; - if (!oldUnderwear.removable && !oldUnderwear.washable) - Animations.Warn(Regression.t.Change_Destroyed, this); - this.underwear = container; - - ChangePants(); + this.underwear.ResetToDefault(container); Animations.Say(Regression.t.Change, this); - return oldUnderwear; } - public void ChangePants() + public void ChangeUnderwear(Underwear uw) { - pants = CreateNewPants(); - CleanPants(); + ChangeUnderwear(uw.container); } public StardewValley.Objects.Clothing GetPantsStardew() @@ -425,34 +554,19 @@ public StardewValley.Objects.Clothing GetPantsStardew() return pants; } - public Container CreateNewPants() + public void ResetPants() { var myPants = GetPantsStardew(); - Container newPants; - Regression.t.Underwear_Options.TryGetValue(myPants == null ? "legs" : "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.ToLower(); - newObject.description = myPants.description.ToLower(); + pants.displayName = myPants.displayName.ToLower(); + pants.description = myPants.description.ToLower(); } - 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 @@ -491,7 +605,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) @@ -521,23 +635,16 @@ 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 bool IsTryingToHoldIt(IncidentType type, float vsAmount) { - float capacity; - float used; - switch (type) - { - case IncidentType.PEE: - capacity = underwear.absorbency; - used = underwear.wetness; - break; - case IncidentType.POOP: - capacity = underwear.containment; - used = underwear.messiness; - break; - default: - throw new Exception("Not implemented: type " + type.ToString()); - } + 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 > 300) return false; // If the underwear is already heavily used, we stop trying @@ -646,7 +753,7 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear //So roll the dice each time >:) //: Give stamina penalty every time you get up to go potty. Since you disrupted sleep. int numIncidentAmount = (int)((fullness - attemptThreshold) / capacity); - float additionalAmount = continence - (numIncidentAmount * capacity); + float additionalAmount = fullness - (numIncidentAmount * capacity); int numAccident = 0; int numPotty = 0; @@ -669,13 +776,16 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear } else { - numPotty++; - bowelFullness -= amountToLose; if (!underwear.removable) //Certain underwear can't be taken off to use the toilet (ie diapers) { + numAccident++; ChangeContinence(type, CalculateContinenceLossOrGain(type, voluntary, inUnderwear, amountToLose / maxCapacity)); // maxCapacity is correct, for balancing reasons AddAccidentFromFullness(type, amountToLose); - numAccident++; + } + else + { + numPotty++; + ChangeFullness(type, -amountToLose); } } } @@ -907,11 +1017,11 @@ public void Wet(bool voluntary = false, bool inUnderwear = true) public void HandleMorning() { isSleeping = false; + var dryingTime = 0; if (Regression.config.Easymode) { hunger = 0; thirst = 0; - bed.dryingTime = 0; } else { @@ -919,16 +1029,14 @@ public void HandleMorning() Farmer player = Game1.player; if (bed.messiness > 0.0 || bed.wetness > 0.0) { - bed.dryingTime = 1000; + dryingTime = 1000; player.stamina -= 20f; } else if (bed.wetness > 0.0) { - bed.dryingTime = 600; + dryingTime = 600; player.stamina -= 10f; } - else - bed.dryingTime = 0; int timesUpAtNight = Math.Max(numPottyPeeAtNight, numPottyPooAtNight); player.stamina -= (timesUpAtNight * wakeUpPenalty); @@ -936,9 +1044,8 @@ public void HandleMorning() } Animations.AnimateMorning(this); - bed.Wash(); - pants = CreateNewPants(); - CleanPants(); + bed.Wash(dryingTime); + ResetPants(); } public void HandleNight() diff --git a/Regression/PrimevalTitmouse/Config.cs b/Regression/PrimevalTitmouse/Config.cs index f9a1764..b7ae096 100644 --- a/Regression/PrimevalTitmouse/Config.cs +++ b/Regression/PrimevalTitmouse/Config.cs @@ -24,5 +24,7 @@ public class Config public int MaxBowelCapacity; public int StartBladderContinence; public int StartBowelContinence; + public bool ReadSaveFiles; + public bool WriteSaveFiles; } } diff --git a/Regression/PrimevalTitmouse/Container.cs b/Regression/PrimevalTitmouse/Container.cs index f28625d..afe12fa 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 messiness == 0.0 && wetness == 0.0 && !drying && (InnerContainer == null || durability == InnerContainer.durability); + } + } public struct Date { public int time; @@ -28,19 +154,99 @@ public struct Date public int season; public int year; } + private Date _timeWhenDoneDrying; + 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; + } + } - public Date timeWhenDoneDrying; - private bool drying = false; + // 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 { get => _timeWhenDoneDrying; set => _timeWhenDoneDrying = value; } + 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; } + + + 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; + if (name == "") + { + Regression.monitor.Log(modDataBaseKey + " had no name, and there is no fallback possible for underwear"); + } + } + public Container(Body body,string subtype, string fallbackType) + { + modDataBaseKey = Body.modDataPrefix + "/" + subtype; + modDataDictionary = Game1.player.modData; + if(name == "") + { + Regression.monitor.Log(modDataBaseKey + " had no name, so fallback "+ fallbackType + " was used"); + ResetToDefault(fallbackType); + } + } + /*public Container(string type) { Container c; @@ -60,9 +266,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 +275,7 @@ public string GetPrefix() return "a"; } - public void Wash() + public void Wash(int dryingTimeOverwrite = -1) { if (washable) { @@ -78,27 +283,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 +313,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,57 +337,81 @@ public float AddPoop(float amount) } return 0.0f; } - - private void Initialize(Container c, float wetness, float messiness, int durability) + public float GetCapacity(IncidentType type) + { + switch (type) + { + case IncidentType.PEE: + return absorbency; + case IncidentType.POOP: + return containment; + default: + throw new Exception("Not implemented: type " + type.ToString()); + } + } + public float GetUsed(IncidentType type) + { + switch (type) + { + 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) { - 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; + this._innerContainer = null; + this.name = c.name; + this.timeWhenDoneDrying = c.timeWhenDoneDrying; + + 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; } - public void Initialize(string type, float wetness, float messiness, int durability) + public void ResetToDefault(string type, float wetness = -100, float messiness = -100, int durability = -100) + { + ResetToDefault(GetTypeDefault(type), wetness, messiness, durability); + } + public static Container GetTypeDefault(string 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); + return c; } - public void parseDryingDate(string date) + public static Date parseDryingDate(string date) { + var dateObj = new Date(); if (date == "") { - drying = false; - return; + dateObj.time = 0; + dateObj.day = 0; + dateObj.season = 0; + dateObj.year = 0; + return dateObj; } string[] splitted = date.Split("-"); - drying = true; + dateObj.time = int.Parse(splitted[0]); + dateObj.day = int.Parse(splitted[1]); + dateObj.season = int.Parse(splitted[2]); + dateObj.year = int.Parse(splitted[3]); - timeWhenDoneDrying.time = int.Parse(splitted[0]); - timeWhenDoneDrying.day = int.Parse(splitted[1]); - timeWhenDoneDrying.season = int.Parse(splitted[2]); - timeWhenDoneDrying.year = int.Parse(splitted[3]); + return dateObj; } - public string serializeDryingDate() + public static string serializeDryingDate(Date timeWhenDoneDrying) { - if (!drying) - { - return ""; - } return string.Format("{0}-{1}-{2}-{3}", timeWhenDoneDrying.time, timeWhenDoneDrying.day, timeWhenDoneDrying.season, timeWhenDoneDrying.year); } } diff --git a/Regression/PrimevalTitmouse/Data.cs b/Regression/PrimevalTitmouse/Data.cs index 23f1867..9d5de26 100644 --- a/Regression/PrimevalTitmouse/Data.cs +++ b/Regression/PrimevalTitmouse/Data.cs @@ -55,6 +55,7 @@ public class Data public string[] Poop_Voluntary; public string[] Spot_Washing_Bedding; public string[] Still_Soiled; + public string[] Should_Change; public string[] Toilet_Night; public string Underwear_Clean; public string Underwear_Drying; diff --git a/Regression/PrimevalTitmouse/Mail.cs b/Regression/PrimevalTitmouse/Mail.cs index 35e8815..093345b 100644 --- a/Regression/PrimevalTitmouse/Mail.cs +++ b/Regression/PrimevalTitmouse/Mail.cs @@ -27,7 +27,7 @@ public static void CheckMail() 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", 0.0f, 0.0f, 5)); // training pants are washable, they might be a good start equipment and are "not that great" + initialSupplies.Add(new Underwear("training pants", 5)); // training pants are washable, they might be a good start equipment and are "not that great" //If we're in Hard mode, also give pull-up. /*if (!Regression.config.Easymode) { diff --git a/Regression/PrimevalTitmouse/Regression.cs b/Regression/PrimevalTitmouse/Regression.cs index 5da1cca..a5de733 100644 --- a/Regression/PrimevalTitmouse/Regression.cs +++ b/Regression/PrimevalTitmouse/Regression.cs @@ -92,52 +92,73 @@ 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 static void restoreItems(StardewValley.Inventories.Inventory items, Dictionary> invReplacement = null) { - foreach (KeyValuePair> entry in invReplacement) + if (invReplacement != null) { + foreach (KeyValuePair> entry in invReplacement) + { + var underwear = new Underwear(); + underwear.rebuild(entry.Value, items[entry.Key]); + items[entry.Key] = underwear; + } + } + + + for (int i = 0; i < items.Count; i++) { - var underwear = new Underwear(); - underwear.rebuild(entry.Value, items[entry.Key]); - items[entry.Key] = underwear; + 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; + } } } private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) { - body = Helper.Data.ReadJsonFile(string.Format("{0}/RegressionSave.json", Constants.SaveFolderName)) ?? new Body(); + if (config.ReadSaveFiles) + { + 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); - } + Dictionary> invReplacement = null; + if(config.ReadSaveFiles) invReplacement = Helper.Data.ReadJsonFile>>(string.Format("{0}/RegressionSaveInv.json", Constants.SaveFolderName)); + restoreItems(Game1.player.Items, invReplacement); - var chestReplacement = Helper.Data.ReadJsonFile>>>(string.Format("{0}/RegressionSaveChest.json", Constants.SaveFolderName)); - if (chestReplacement != null) + Dictionary>> chestReplacement = null; + if (config.ReadSaveFiles) chestReplacement = Helper.Data.ReadJsonFile>>>(string.Format("{0}/RegressionSaveChest.json", Constants.SaveFolderName)); + + 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++; } + //restoreItems(Game1.player.Items, invReplacement); Animations.AnimateNight(body); HandleMorning(sender, e); @@ -171,8 +192,6 @@ 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>>(); @@ -197,9 +216,9 @@ private void BeforeSave(object Sender, SavingEventArgs e) 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); + Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSave.json", Constants.SaveFolderName), config.WriteSaveFiles ? body : null); + Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSaveInv.json", Constants.SaveFolderName), config.WriteSaveFiles ? invReplacements : null); + Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSaveChest.json", Constants.SaveFolderName), config.WriteSaveFiles ? chestReplacements : null); } private void ReceiveUpdateTick(object sender, OneSecondUpdateTickingEventArgs e) @@ -346,7 +365,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) @@ -390,7 +409,7 @@ private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) { foreach(string type in availableUnderwear) { - Underwear underwear = new Underwear(type, 0.0f, 0.0f, 1); + Underwear underwear = new Underwear(type, 1); currentShopMenu.forSale.Add(underwear); currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, StardewValley.Menus.ShopMenu.infiniteStock)); } @@ -449,7 +468,7 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) Game1.activeClickableMenu = null; if (!Regression.config.PantsChangeRequiresHome || body.InPlaceWithPants()) { - body.ChangePants(); + body.ResetPants(); Animations.Write(Regression.t.Change_At_Home, body); } else @@ -482,7 +501,7 @@ 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()) { @@ -490,18 +509,24 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) 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 underwear = new Underwear(body.underwear, 1); + + // We have to do all this before we change the underwear, because we lose the reference //If the underwear returned is not removable, destroy it - if (!container.removable && !container.washable) { } + if (!body.underwear.removable && !body.underwear.washable) { + Animations.Warn(Regression.t.Change_Destroyed, body); + } //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); - } + } + + body.ChangeUnderwear(activeObject); + body.ResetPants(); } //If it is wet, messy or drying, check if we can wash it else if (activeObject.container.washable) @@ -540,10 +565,15 @@ private void ReceiveTimeOfDayChanged(object sender, TimeChangedEventArgs e) if (Game1.timeOfDay == 610) Mail.CheckMail(); - //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) + if (Game1.timeOfDay < 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(this.body); + + if (rnd.NextDouble() < 0.0555555559694767 && (body.NeedsChangies(IncidentType.PEE) || body.NeedsChangies(IncidentType.POOP))) + Animations.AnimateShouldChange(this.body); } public Regression() diff --git a/Regression/PrimevalTitmouse/Strings.cs b/Regression/PrimevalTitmouse/Strings.cs index a8a16a4..595a225 100644 --- a/Regression/PrimevalTitmouse/Strings.cs +++ b/Regression/PrimevalTitmouse/Strings.cs @@ -18,7 +18,7 @@ public static string DescribeUnderwear(Container u, string baseDescription = nul 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); + newValue = !u.drying ? Strings.t.Underwear_Clean.Replace("$UNDERWEAR_DESC$", newValue) : Strings.t.Underwear_Drying.Replace("$UNDERWEAR_DESC$", newValue); } else { @@ -49,8 +49,17 @@ public static string DescribeUnderwear(Container u, string baseDescription = nul } } } + 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() + " " + newValue; + return u.GetPrefix() + " " + newOrOld + newValue; } @@ -60,9 +69,13 @@ public static string InsertVariables(string msg, Body b, Container c = null) 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, "#"); + 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_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)); + { + + 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); } diff --git a/Regression/PrimevalTitmouse/Underwear.cs b/Regression/PrimevalTitmouse/Underwear.cs index 9b31952..c447e13 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() @@ -59,24 +99,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 +133,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 +185,7 @@ public override string Name { get { - return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Status + id); + return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Status + container.name); } } @@ -151,10 +199,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/config.json b/Regression/config.json index 9a93dfe..78ee121 100644 --- a/Regression/config.json +++ b/Regression/config.json @@ -18,8 +18,10 @@ "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 "MaxBladderCapacity": 600, // 600 is around 3 potty runs a day - "MaxBowelCapacity": 1200, // 1200 is around 1.5 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, // Will read the legacy save files (to keep loading old stardew saves) + "WriteSaveFiles": false, // Will read and write the legacy save files (no longer needed, it's now written directly into the stardew saves) "Lang": "en" } \ No newline at end of file diff --git a/Regression/en.json b/Regression/en.json index 964dd17..47dd5e6 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -168,10 +168,15 @@ "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$ soon, but not right now. It's still warm", + "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$.", @@ -1556,7 +1561,7 @@ "removable": true, "durability": 8 }, - "lavender pullup": { + "lavender pullups": { "name": "lavender pullups", "description": "thick, soft and snug disposable flowery lavender pullups", "absorbency": 1550.0, @@ -1564,7 +1569,7 @@ "spriteIndex": 4, "price": 25, "washable": false, - "plural": true, + "plural": false, "dryingTime": 0, "removable": true, "durability": 0 @@ -1583,7 +1588,7 @@ "durability": 6 }, "joja diaper": { - "name": "Joja diaper", + "name": "joja diaper", "description": "thin white and cheap plastic diaper from JojaMart", "absorbency": 1100.0, "containment": 1400.0, @@ -1609,7 +1614,7 @@ "durability": 0 }, "cloth diaper": { - "name": "Cloth diaper", + "name": "cloth diaper", "description": "thick and soft white cloth diaper", "absorbency": 1400.0, "containment": 2600.0, From fd059979cda3756dc57cfa3bf7689a6f63895777 Mon Sep 17 00:00:00 2001 From: Proximitron Date: Mon, 9 Dec 2024 05:03:43 +0100 Subject: [PATCH 4/9] Working version with a lot of extensions, that don't have space in this --- README.md | 3 + Regression.sln | 2 +- Regression/PrimevalTitmouse/Animations.cs | 359 +++++++++---- Regression/PrimevalTitmouse/Body.cs | 83 +-- Regression/PrimevalTitmouse/Config.cs | 12 +- Regression/PrimevalTitmouse/Container.cs | 62 ++- Regression/PrimevalTitmouse/Data.cs | 4 +- .../IGenericModConfigMenuApi.cs | 181 +++++++ Regression/PrimevalTitmouse/Regression.cs | 504 ++++++++++++++++-- Regression/PrimevalTitmouse/Strings.cs | 8 + Regression/Regression Dialogue/Content.json | 22 +- .../Dialogue/NPCs/Abigail.json | 16 + .../Dialogue/NPCs/Gus.json | 6 +- .../Dialogue/NPCs/Jodi.json | 5 +- .../Dialogue/NPCs/Maru.json | 15 + .../Dialogue/NPCs/Penny.json | 5 +- .../Dialogue/NPCs/Sam.json | 5 +- Regression/Regression.csproj | 8 + Regression/config.json | 34 +- Regression/en.json | 238 +++++++-- 20 files changed, 1265 insertions(+), 307 deletions(-) create mode 100644 Regression/PrimevalTitmouse/IGenericModConfigMenuApi.cs create mode 100644 Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json create mode 100644 Regression/Regression Dialogue/Dialogue/NPCs/Maru.json diff --git a/README.md b/README.md index ea1b5f5..c25c156 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,8 @@ 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) +Highly recommended: (Allowes ingame configuration of the mod) +- [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098?tab=files] ### 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. 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/PrimevalTitmouse/Animations.cs b/Regression/PrimevalTitmouse/Animations.cs index 04d39b7..06ec0cc 100644 --- a/Regression/PrimevalTitmouse/Animations.cs +++ b/Regression/PrimevalTitmouse/Animations.cs @@ -3,12 +3,14 @@ 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.Runtime.CompilerServices; @@ -50,7 +52,7 @@ enum FaceDirection : int public static Texture2D sprites; private static Data t; - private static Farmer who; + public static Farmer player => Game1.player; //Static Accessor Methods. Ensure that variables are initialized. public static Data GetData() @@ -64,11 +66,7 @@ public static Texture2D GetSprites() return sprites; } - public static Farmer GetWho() - { - Animations.who ??= Game1.player; - return who; - } + public static float ZoomScale() { @@ -78,21 +76,24 @@ 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(StardewValley.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) @@ -135,27 +136,27 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) else Say(Animations.GetData().Mess_Accident, b); - Animations.GetWho().doEmote(12, false); - if (b.IsFishing() || !Animations.GetWho().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)); - Animations.GetWho().freezePause = poopAnimationTime; - Animations.GetWho().canMove = false; + player.doEmote(12, false); + if (b.IsFishing() || !player.canMove) return; // We skip the actual animations if nessesary + + 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)Animations.player).facingDirection.Value == 1 ? 0.0f : (float)-Game1.tileSize, (float)(Game1.tileSize * 2)), false, ((Character)Animations.player).facingDirection.Value == 1, (float)((Character)Animations.player).StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); + + player.freezePause = poopAnimationTime; + player.canMove = false; } public static void AnimateMessingEnd(Body b) { if (b.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, Animations.player.position.Value - new Vector2(Animations.player.facingDirection.Value == 1 ? 0.0f : -Game1.tileSize, Game1.tileSize * 2), false, Animations.player.facingDirection.Value == 1, Animations.player.StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); } public static void AnimateMessingMinor(Body b) { Animations.Say(Animations.GetData().Bowels_Leak, b); - ((Character)Animations.GetWho()).doEmote(12, false); + ((Character)Animations.player).doEmote(12, false); } public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) @@ -179,9 +180,9 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) else Animations.Say(Animations.GetData().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)Animations.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 (Animations.player.currentLocation.terrainFeatures.ContainsKey(((Character)Animations.player).Tile) && (terrainFeature = Animations.player.currentLocation.terrainFeatures[((Character)Animations.player).Tile] as HoeDirt) != null) terrainFeature.state.Value = 1; } else if (voluntary) @@ -190,18 +191,17 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) Animations.Say(Animations.GetData().Wet_Accident, b); // We skip the actual animations if nessesary - if (b.IsFishing() || !Animations.GetWho().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); + if (b.IsFishing() || !Animations.player.canMove) return; + + player.jitterStrength = 0.5f; + player.freezePause = peeAnimationTime; //milliseconds + player.canMove = false; + ((Character)Animations.player).doEmote(28, false); } public static void AnimateWettingMinor(Body b) { Animations.Say(Animations.GetData().Bladder_Leak, b); - ((Character)Animations.GetWho()).doEmote(28, false); + ((Character)Animations.player).doEmote(28, false); } @@ -210,9 +210,9 @@ public static void AnimateWettingEnd(Body b) if (b.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 (Animations.player.currentLocation.terrainFeatures.ContainsKey(((Character)Animations.player).Tile) && (terrainFeature = player.currentLocation.terrainFeatures[((Character)Animations.player).Tile] as HoeDirt) != null) terrainFeature.state.Value = 1; } } @@ -236,36 +236,94 @@ public static void AnimateMorning(Body b) } Animations.Write(msg, b); } - + 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) || !b.IsAllowedResource(IncidentType.PEE) && !b.IsAllowedResource(IncidentType.POOP)) return; - string toiletMsg = Strings.ReplaceAndOr(Strings.RandString(Animations.GetData().Toilet_Night), first, second, "&"); + + var list = Animations.GetData().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"); + 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 + "."; + 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 += " " + FirstCharToUpper(Strings.RandString(list["Belittle_Accidents"])) + "."; } - toiletMsg = Strings.InsertVariable(toiletMsg, "$HOW_MANY_TIMES", "."); + 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))); Write(toiletMsg, b); } @@ -397,32 +455,24 @@ public static void DrawUnderwearIcon(Container c, int x, int 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 || NPC_LIST.Contains(npc.Name)) 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!) @@ -430,35 +480,69 @@ 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; + var list = Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, radius, (GameLocation)Game1.currentLocation); - //Reduce the loss if the person likes you (more forgiving) - int heartLevelForNpc = Animations.GetWho().getFriendshipHeartLevelForNPC(npc.getName()); + var newList = new List(); + foreach(var npcEntry in list) + { + if (!NPC_LIST.Contains(npcEntry.Name)) + { + 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 = Animations.GetData().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 { @@ -476,65 +560,108 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over } npcType.Add(npc.getName().ToLower()); } - - //What did we do? Use to figure out the response. - string responseKey = ""; + return npcType; + } + public static string modifierForState(NPC npc) + { + return "dirty"; + } + 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) + { + 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")) + if (npcTypeList(npc).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) - { - 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; + + //Get NPC in radius + var nearby = NearbyVillager(b, mess, inUnderwear, overflow, attempt); - 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); + foreach (var npc in nearby) + { + someoneNoticed = true; + + //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); + } + //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 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); + //If we're in debug mode, notify how the relationship was effected + if (Regression.config.Debug && finalLossValue < 0) + Animations.Say(string.Format("{0} ({1}) changed friendship from {2} by {3}.", npc.Name, npc.Age, player.getFriendshipHeartLevelForNPC(npc.getName()), finalLossValue), (Body)null); - 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); + //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 (Animations.GetData().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); + } + + } + + //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); } - //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; } diff --git a/Regression/PrimevalTitmouse/Body.cs b/Regression/PrimevalTitmouse/Body.cs index da1249f..86808bf 100644 --- a/Regression/PrimevalTitmouse/Body.cs +++ b/Regression/PrimevalTitmouse/Body.cs @@ -28,14 +28,14 @@ public class Body 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 - private static readonly float maxBladderCapacity = Regression.config.MaxBladderCapacity; //about 600mL => changed to 800mL as player will start with lower bladder by default - private static readonly float minBladderContinence = 0.3f; // Also describes capacity as changes are linear + 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.3f; // 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.5f; // lowered from 0.67f to 0.5f to make the numbers smaller (too much poop) and bowel capacity / 1.5f (1000f in total) - private static readonly float maxBowelCapacity = (requiredCaloriesPerDay*foodToBowelConversion) / 1.5f / 1000f * Regression.config.MaxBowelCapacity; // The last 2 numbers usually end up as / 1200 * 1200 (cancle eachother out) to make configuration easier to understand - private static readonly float minBowelContinence = 0.3f; // Also describes capacity as changes are linear + private static float maxBowelCapacity => (requiredCaloriesPerDay*foodToBowelConversion) / 1.5f / 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.3f; // Also describes capacity as changes are linear //Setup Thresholds and messages private 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 @@ -414,6 +414,10 @@ public void AddResource(IncidentType type, float amount) } Accident(type, voluntary: false, inUnderwear: true); } + else if(!IsTryingToHoldIt(type) && oldFullnessPercent > 0.7f) + { + 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 @@ -442,8 +446,15 @@ public void AddFood(float amount, float conversionRatio = 1f) float newPercent = (requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; //Convert food lost into poo at half rate - if (amount < 0 && hunger < requiredCaloriesPerDay) - AddResource(IncidentType.POOP, amount * -1f * conversionRatio * foodToBowelConversion); + if (amount < 0) + { + if(hunger < requiredCaloriesPerDay) + 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) @@ -478,9 +489,15 @@ 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) - AddResource(IncidentType.PEE, 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) @@ -522,7 +539,7 @@ public void ChangeContinence(IncidentType type, float percent = 0.01f) //Change of bladder capacity is no longer nessesary. Handled by getter. if (Regression.config.Debug) - Animations.Say(string.Format("{0} continence changed by {1} to {2}, {0} capacity now {3}", type == IncidentType.POOP ? "Bowel": "Bladder", previousContinence, GetContinence(type), GetCapacity(type)), (Body)null); + Animations.Say(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)), (Body)null); //Warn that we may be losing control if(type == IncidentType.POOP) @@ -548,7 +565,7 @@ public void ChangeUnderwear(Underwear uw) 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) @@ -574,6 +591,10 @@ 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() { @@ -641,7 +662,7 @@ public bool NeedsChangies(IncidentType type) return underwear.GetUsed(type) > 0 && underwear.GetCapacity(type) - underwear.GetUsed(type) < GetCapacity(type); } - public bool IsTryingToHoldIt(IncidentType type, float vsAmount) + public bool IsTryingToHoldIt(IncidentType type, float vsAmount = 0) { float capacity = underwear.GetCapacity(type); float used = underwear.GetUsed(type); @@ -729,13 +750,6 @@ public void AddAccident(IncidentType type, float amount) throw new Exception("Not implemented: type " + type.ToString()); } - } - // Minor accidents (leaking) can happen before failure and is usually not causing someone else to notice - public void AccidentMinor(IncidentType type) - { - if (isSleeping) return; - - } public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear = true) { @@ -776,6 +790,7 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear } else { + 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) { numAccident++; @@ -784,7 +799,6 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear } else { - numPotty++; ChangeFullness(type, -amountToLose); } } @@ -825,7 +839,7 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear if (!attemptOnly) { 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, -this.bowelFullness); + ChangeFullness(type, -fullness); } FinalizeAccident(type, voluntary, true, attemptOnly); // Trying in your underwear is different, people might be acting differently } @@ -899,7 +913,7 @@ public float CalculateContinenceLossOrGain(IncidentType type, bool voluntary, bo float fullness = GetFullness(type); int rate; - if (voluntary) + if (voluntary && !inUnderwear) { rate = type == IncidentType.POOP ? Regression.config.BowelGainContinenceRate : Regression.config.BladderGainContinenceRate; } @@ -909,15 +923,14 @@ public float CalculateContinenceLossOrGain(IncidentType type, bool voluntary, bo } - //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) + //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)) + 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; } } @@ -995,20 +1008,14 @@ public float situationMultiplier(bool voluntary, bool inUnderwear) { multiplier = (voluntary ? (float)Regression.config.NighttimeGainMultiplier : (float)Regression.config.NighttimeLossMultiplier) / 100f; } - // 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)) - { - multiplier = (float)Regression.config.ToiletGainMultiplier / 100f; - } - // If we voluntary pee/poop our pants, this adds situational modifiers. Usually negates possible gains or at least reduces them. - else if(voluntary && inUnderwear) - { - multiplier = (float)Regression.config.GoingVoluntaryInUnderwearGainMultiplier / 100f; - } 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); diff --git a/Regression/PrimevalTitmouse/Config.cs b/Regression/PrimevalTitmouse/Config.cs index b7ae096..a5daf85 100644 --- a/Regression/PrimevalTitmouse/Config.cs +++ b/Regression/PrimevalTitmouse/Config.cs @@ -7,15 +7,13 @@ public class Config public bool Easymode; public string Lang; public bool PantsChangeRequiresHome; + public bool Wetting; 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; @@ -26,5 +24,13 @@ public class Config public int StartBowelContinence; public bool ReadSaveFiles; public bool WriteSaveFiles; + + public int KeyGoInPants; + public int KeyPee; + public int KeyPoop; + public int KeyGoInToilet; + public int KeyPeeInToilet; + public int KeyPoopInToilet; + } } diff --git a/Regression/PrimevalTitmouse/Container.cs b/Regression/PrimevalTitmouse/Container.cs index afe12fa..2aa772d 100644 --- a/Regression/PrimevalTitmouse/Container.cs +++ b/Regression/PrimevalTitmouse/Container.cs @@ -154,7 +154,40 @@ public struct Date public int season; public int year; } - private Date _timeWhenDoneDrying; + 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 { @@ -184,6 +217,7 @@ public bool drying { } } + // Here starts the block that contains all values we can take from type private string _description; private float _absorbency; @@ -195,7 +229,7 @@ public bool drying { private int _dryingTime; private bool _removable; - public Date timeWhenDoneDrying { get => _timeWhenDoneDrying; set => _timeWhenDoneDrying = value; } + 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; } @@ -390,29 +424,5 @@ public static Container GetTypeDefault(string type) return c; } - 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); - } } } diff --git a/Regression/PrimevalTitmouse/Data.cs b/Regression/PrimevalTitmouse/Data.cs index 9d5de26..9b70a89 100644 --- a/Regression/PrimevalTitmouse/Data.cs +++ b/Regression/PrimevalTitmouse/Data.cs @@ -38,6 +38,7 @@ public class Data public string[] Food_Low; public string[] Food_None; public string[] LookPants; + public string[] Diaper_Change_Dialog; public string[] Mess_Accident; public string[] Mess_Attempt; public string[] Mess_Voluntary; @@ -56,7 +57,7 @@ public class Data public string[] Spot_Washing_Bedding; public string[] Still_Soiled; public string[] Should_Change; - public string[] Toilet_Night; + public Dictionary Night; public string Underwear_Clean; public string Underwear_Drying; public string EasyMode_On; @@ -64,6 +65,7 @@ public class Data public string[] Underwear_Messy; public Dictionary Underwear_Options; public string[] Underwear_Wet; + public Dictionary> Villager_Friendship_Modifier; public Dictionary> Villager_Reactions; public string[] Wake_Up_Underwear_State; public string[] Washing_Bedding; 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/Regression.cs b/Regression/PrimevalTitmouse/Regression.cs index a5de733..9b24deb 100644 --- a/Regression/PrimevalTitmouse/Regression.cs +++ b/Regression/PrimevalTitmouse/Regression.cs @@ -1,12 +1,16 @@ -using Microsoft.Xna.Framework; +using GenericModConfigMenu; +using Microsoft.Xna.Framework; using Regression; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; +using StardewValley.Delegates; +using StardewValley.GameData.Characters; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Objects; using StardewValley.Tools; +using StardewValley.Triggers; using System; using System.Collections.Generic; using System.Linq; @@ -29,8 +33,10 @@ public class Regression : Mod public static Farmer who; private float tickCD1 = 0; private float tickCD2 = 0; + public static string dirtyEventToken = "dirtyEventToken"; 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 Harmony("com.primevaltitmouse.regression"); @@ -44,12 +50,280 @@ 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); + + TriggerActionManager.RegisterAction("Regression.StartChange", this.StartChange); } + 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.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.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: () => "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() { @@ -124,11 +398,15 @@ private static void restoreItems(StardewValley.Inventories.Inventory items, Dict } } + private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) { + var configFile = "RegressionSave.json"; if (config.ReadSaveFiles) { - body = Helper.Data.ReadJsonFile(string.Format("{0}/RegressionSave.json", Constants.SaveFolderName)) ?? new Body(); + body = Helper.Data.ReadJsonFile(string.Format("{0}/{1}", Constants.SaveFolderName, configFile)); + if (body == null) body = new Body(); + else jsonLoaded[configFile] = true; } else { @@ -138,12 +416,16 @@ private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) started = true; who = Game1.player; + configFile = "RegressionSaveInv.json"; Dictionary> invReplacement = null; - if(config.ReadSaveFiles) invReplacement = Helper.Data.ReadJsonFile>>(string.Format("{0}/RegressionSaveInv.json", Constants.SaveFolderName)); + 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}/RegressionSaveChest.json", Constants.SaveFolderName)); + if (config.ReadSaveFiles) chestReplacement = Helper.Data.ReadJsonFile>>>(string.Format("{0}/{1}", Constants.SaveFolderName, configFile)); + if (chestReplacement != null) jsonLoaded[configFile] = true; int locId = 0; foreach (var location in Game1.locations) @@ -216,41 +498,167 @@ private void BeforeSave(object Sender, SavingEventArgs e) var invReplacements = replaceItems(Game1.player.Items); - Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSave.json", Constants.SaveFolderName), config.WriteSaveFiles ? body : null); - Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSaveInv.json", Constants.SaveFolderName), config.WriteSaveFiles ? invReplacements : null); - Helper.Data.WriteJsonFile(string.Format("{0}/RegressionSaveChest.json", Constants.SaveFolderName), config.WriteSaveFiles ? chestReplacements : 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); + } + + 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 StartChange(string[] args, TriggerActionContext context, out string error) + { + try + { + var underwearName = "big kid undies"; + if (args[1] != null) + { + underwearName = args[1]; + } + + var diaper = new Underwear(underwearName, 1); + Underwear underwear = new Underwear(body.underwear, 1); + + // We have to do all this before we change the underwear, because we lose the reference + + //If the underwear returned is not removable, destroy it + if (!body.underwear.removable && !body.underwear.washable) + { + Animations.Warn(Regression.t.Change_Destroyed, body); + } + //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); + } + + body.ChangeUnderwear(diaper); + body.ResetPants(); + if (args[2] != null) + { + body.pants.displayName = args[1]; + body.pants.description = args[1]; + } + } + 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()) + //If time is moving, update our body state (Hunger, thirst, etc.) + if (ShouldTimePass()) + { + 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. { - 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. + tickCD2 += 1; //This should trigger multiple times during the eating animation. + } + if (tickCD2 >= 2) //Setting this to 2 should be able to balance preventing double triggers and ensuring no loss in intentional triggers. + { + tickCD1 = 0; + tickCD2 = 0; + } + + + // The following block makes npc (usually) not talk to you if you wear wet or messy pants... short of the special texts + + var newList = new List(); + var isFilthy = body.pants.wetness > 0 || body.pants.messiness > 0; + var list = Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, 10, (GameLocation)Game1.currentLocation); + foreach (var npc in list) + { + if (npc.CurrentDialogue.Count > 0 && npc.CurrentDialogue.Peek().TranslationKey == dirtyEventToken) { - tickCD2 += 1; //This should trigger multiple times during the eating animation. + RemoveDialogueFromNPC(npc, dirtyEventToken); } - if (tickCD2 >= 2) //Setting this to 2 should be able to balance preventing double triggers and ensuring no loss in intentional triggers. + if (isFilthy) { - tickCD1 = 0; - tickCD2 = 0; + var npcName = ""; + var mod = Animations.modifierForState(npc); + var responseKey = mod + Animations.responseKeyAdditionForState(npc); + var npcType = Animations.npcTypeList(npc); + 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 = 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); + } + + } + + var randNpcString = Strings.RandString(stringList3.ToArray()); + var npcStatement = Strings.ReplaceAndOr(randNpcString, body.pants.wetness > 0, body.pants.messiness > 0); + npcStatement = Strings.InsertVariables(npcStatement, body, (Container)null); + + + npcStatement = npcName + npcStatement; + npc.setNewDialogue(new Dialogue(npc, dirtyEventToken, npcStatement), true, true); } - } - //Handle eating and drinking. - if (Game1.player.isEating && Game1.activeClickableMenu == null && tickCD1 == 0) + + } + + //Handle eating and drinking. + if (Game1.player.isEating && Game1.activeClickableMenu == null && tickCD1 == 0) + { + body.Consume(who.itemToEat.Name); + tickCD1 += 1; + } + } + private void RemoveDialogueFromNPC(NPC npc, 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) { - body.Consume(who.itemToEat.Name); - tickCD1 += 1; + 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()); + } } //Determine if we need to handle time passing (not the same as Game time passing) @@ -263,8 +671,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) @@ -291,7 +729,6 @@ 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: @@ -320,12 +757,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; @@ -338,15 +769,6 @@ private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) case SButton.F8: Animations.CheckPottyFeeling(body); break; - case SButton.F9: - config.Debug = !config.Debug; - break; - case SButton.F10: - body.MinorAccident(IncidentType.PEE); - break; - case SButton.F11: - body.MinorAccident(IncidentType.POOP); - break; } } } diff --git a/Regression/PrimevalTitmouse/Strings.cs b/Regression/PrimevalTitmouse/Strings.cs index 595a225..02846e1 100644 --- a/Regression/PrimevalTitmouse/Strings.cs +++ b/Regression/PrimevalTitmouse/Strings.cs @@ -69,7 +69,15 @@ public static string InsertVariables(string msg, Body b, Container c = null) if (b != null) c = b.underwear; if (c != null) + { + var gettingChangedDialog = Strings.RandString(Animations.GetData().Diaper_Change_Dialog); + gettingChangedDialog = Strings.ReplaceAndOr(gettingChangedDialog, b.pants.wetness > 0, b.pants.messiness > 0); + str = str.Replace("$Diaper_Change_Dialog", gettingChangedDialog); + 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_DESC$", Strings.DescribeUnderwear(c, c.description)), !c.plural, "#"); + + } + if (b != null) { diff --git a/Regression/Regression Dialogue/Content.json b/Regression/Regression Dialogue/Content.json index ebc0c09..795f210 100644 --- a/Regression/Regression Dialogue/Content.json +++ b/Regression/Regression Dialogue/Content.json @@ -31,10 +31,20 @@ "Action": "Include", "FromFile": "Dialogue/NPCs/Vincent.json" }, - { - "LogName": "Jas", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Jas.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..7a62022 --- /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 Regression.StartChange \"joja diaper\"#$h", + "Diaper_Change_Refuse": "I was just asking.", + "Diaper_Change_Followup": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|You changed your mind? Sure...$h#$action Regression.StartChange \"joja diaper\"#$h" + } + } + ] +} \ 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/Jodi.json b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json index 56ccc89..2b1cb77 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json @@ -59,8 +59,9 @@ "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", - - + "Diaper_Change_Accept": "#Just a second... See it stretches! There! Right as rain!$l#$b#%Jodi changes you#$action Regression.StartChange \"baby print diaper\" \"sams pants\"#$h", + "Diaper_Change_Refuse": "Well, if you are like Vincent and want to stay in your filthy pants, suit yourself! Just don't leak on the couch, you hear?", + "Diaper_Change_Followup": "#$p dirty_change_yes#Again? Sorry i am bussy right now. I have to change Vincents bottom next!(This is an error, this should not be able to happen!)|I am glad you see reason! Hold this, yes this is baby powder, don't look at me like that!$3'#$b#%Jodi changes your#$action Regression.StartChange \"baby print diaper\" \"sams pants\"#$3" } } ] diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json b/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json new file mode 100644 index 0000000..beb30a6 --- /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 Regression.StartChange \"joja diaper\"#$h", + "Diaper_Change_Refuse": "I am here if you change your mind.", + "Diaper_Change_Followup": "#$p dirty_change_yes#?(This is an error, this should not be able to happen!)|Glad to help$l#$b#%Maru changes you with professional efficiency#$action Regression.StartChange \"joja diaper\"#$3" + + } + } + ] +} \ 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..823bcca 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json @@ -149,7 +149,10 @@ "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": "#Hop on the changing table!$l#$b#%Penny changes your diaper and smiles at you#$action Regression.StartChange \"heart diaper\"#$h", + "Diaper_Change_Refuse": "Do you want to play the big kid today? I can see it sagging from here!", + "Diaper_Change_Followup": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|Guess who gets their bottom changed?$h#$action Regression.StartChange \"heart diaper\"#$h" }, }, diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json index 6e4b2ce..2408af2 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json @@ -141,7 +141,10 @@ "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", - + + "Diaper_Change_Accept": "#Ah, hold still. Don't worry i got this!$l#$b#%Sam changes your diaper, making a lot of mistakes while doing so.#$action Regression.StartChange \"joja diaper\"#$h", + "Diaper_Change_Refuse": "Oh, ok.", + "Diaper_Change_Followup": "#$p dirty_change_yes#No?(This is an error, this should not be able to happen!)|Sure thing, lets see...$h#$b#%Sam changes your diaper, he just can't it get quite right.#$action Regression.StartChange \"joja diaper\"#$h" } }, diff --git a/Regression/Regression.csproj b/Regression/Regression.csproj index 64d4aea..9c5a364 100644 --- a/Regression/Regression.csproj +++ b/Regression/Regression.csproj @@ -33,6 +33,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -63,4 +69,6 @@ + + diff --git a/Regression/config.json b/Regression/config.json index 78ee121..4955ac5 100644 --- a/Regression/config.json +++ b/Regression/config.json @@ -1,27 +1,31 @@ //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 "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": true, // 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). + "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, // Will read the legacy save files (to keep loading old stardew saves) - "WriteSaveFiles": false, // Will read and write the legacy save files (no longer needed, it's now written directly into the stardew saves) + "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 47dd5e6..48cac2f 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -216,10 +216,36 @@ "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" + "Diaper_Change_Dialog": [ + "#$q dirty_change_yes/dirty_change_no Diaper_Change_Followup#Do you want to get changed like a toddler?#$r dirty_change_yes 1 Diaper_Change_Accept#Nod.#$r dirty_change_no 0 Diaper_Change_Refuse#Shake your head." ], + "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 slept through the whole night", + "You didn't wake up once this night", + "You wake up in the morning", + "You didn't feel the need to go tonight", + "You slept like a baby" + ], + "Accident_At_Night": [ + "you yourself $ACCIDENT_TIMES_TOTAL like a toddler", + "you yourself $ACCIDENT_ONCE_TWICE_TOTAL like the little bed you are" + ], + "Belittle_Accidents": [ + "Looks like someone really does need to be in their diapers at night", + "Someone should wear protection at night" + ], + "Underwear_Stuck": [ + "but you couldn't get your $UNDERWEAR_NAME$ off in time" + ] + }, + + "Wake_Up_Underwear_State": [ "You wake up in $INSPECT_UNDERWEAR_NAME$." ], @@ -284,19 +310,76 @@ "Your pants are poopy!", "You messed your pants!" ], + "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 + } + }, "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" + "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?", - "Does someone need a diaper change?" + "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." + "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", @@ -319,6 +402,9 @@ "...$5", "...Did you just...$2" ], + "dirty": [ + "Your pants are all... ...." + ], "ground": [ "Eww. Is that normal in the city?$5", "What... Ugh!$5", @@ -328,6 +414,31 @@ "What... Put your pants back on!$5" ] }, + "kid": { + "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" + ] + }, "animal": { "soiled_nice": [ "...", @@ -342,10 +453,10 @@ }, "abigail": { "soiled_verynice": [ - "Want a change? #$b#I could change you, if you want!$h", + "Want a change? #$b#I could change you, if you want!$h$Diaper_Change_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?", - "Let me help with that! Lay down for me.$h", + "Let me help with that! Lay down for me.$h$Diaper_Change_Dialog", "Ewww, I think.... I think I pooped myself.$s #$b#...$s #$b#Could you... maybe change me?" ], "soiled_nice": [ @@ -368,7 +479,7 @@ "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?", + "$hLooks like $UNDERWEAR_NAME$ a little now!", "$sI think my diaper's starting to sag. Can you give me a hand?" ], "soiled_nice": [ @@ -381,13 +492,27 @@ "$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": { + "soiled_verynice": [ + "Again? Sure, you know the drill...$l$Diaper_Change_Dialog" + ], + "soilded_nice": [ + "Lets be professional about this. Lie down on the bed for me please?$0$Diaper_Change_Dialog" + ], + "soiled_mean": [ + "Incontinence i guess?$4" + ], + "dirty": [ + "You will catch a cold, or worse. Let's get the cloth off!$1$Diaper_Change_Dialog" + ] + }, "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.", + "You don't need to rush potty training if you're not ready yet.#$b#You need help?$Diaper_Change_Dialog", + "It can be hard for little to remember to go potty sometimes. It's okay.#$b#Need a change?$Diaper_Change_Dialog", "Oh goodness!$1", - "Awww, you're so cute when you're embarrassed!$1" + "Awww, you're so cute when you're embarrassed!$1#$b#Comeon, lets get you in some new Diapers!$Diaper_Change_Dialog" ], "soiled_nice": [ "$FARMERNAME$, I think you might need to go change.", @@ -395,17 +520,20 @@ ], "soiled_mean": [ "You might need to tap into those supplies I left you$4" + ], + "dirty": [ + "$p dirty_change_no# No leaks! $3| Aww, come here @! This things happen! We can make one of Vincents diapers fit! $1$Diaper_Change_Dialog" ] }, "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'", + "Are you okay buddy?#$b#Do you want some help with that?$Diaper_Change_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.", + "Man, you're such a little baby sometimes.#$b#%Sam giggles a bit as he pats your squishy bottom.#$b#Need help with that?$Diaper_Change_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.", @@ -423,7 +551,10 @@ "...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": [ + "Can't let you get a cold, can i. Need help?$1$Diaper_Change_Dialog" + ], }, "penny": { "soiled_verynice": [ @@ -474,61 +605,62 @@ }, "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" + "#$p 102#%*Giggles*|Mommy told me big kids are supposed to use the potty. #$b#I don't wanna be a big kid either!$1", + "#$p 102#%*Giggles*|%Vincent watches you yourself and giggles.#$b#Good one!$1", + "#$p 102#%*Giggles*|%You notice Vincent watching as you yourself.#$b#All better?", + "#$p 102#%*Giggles*|%Vincent watches the whole scene curiously and giggles when you look over. #$b# You !$1", + "#$p 102#%*Giggles*|If you want I could ask my Mommy to change you.#$b#No?#$b#That's okay, I like being too!$1", + "#$p 102#%*Giggles*|$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!" + "#$p 102#%*Giggles*|Don't cry, Mommy says it's okay to have accidents sometimes.", + "#$p 102#%*Giggles*|Don't worry $FARMERNAME$, I still do that too!", + "#$p 102#%*Giggles*|Feel all better?", + "#$p 102#%*Giggles*|It smells like you need a diaper change!", + "#$p 102#%*Giggles*|I kney it! It does happen to bigs too!" ], "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" + "#$p 102#%Ewww$3|%Vincent saw what happened and snickers at you.", + "#$p 102#%Ewww$3|Was that an accident?", + "#$p 102#%Ewww$3|Ha! Gross!$1", + "#$p 102#%Ewww$3|$FARMERNAME$ just !$1", + "#$p 102#%Ewww$3|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" + "#$p 102#%Ewww!$3|Ewww!$3", + "#$p 102#%Ewww!$3|Ewww! Don't there!$3", + "#$p 102#%Ewww!$3|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" + "#$p 102#%...$2|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." + "#$p 102#%*Giggles*|Don't cry, it's okay for little s to have accidents sometimes.", + "#$p 102#%*Giggles*|Oh no, did you have an accident? That's okay, you can try again next time.", + "#$p 102#%*Giggles*|It's okay, I won't tell anyone you had an accident $FARMERNAME$", + "#$p 102#%*Giggles*|It's okay $FARMERNAME$, I still have accidents too.$1", + "#$p 102#%*Giggles*|I can see you waddling!$4", + "#$p 102#%*Giggles*|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" + "#$p 102#%...$2|*Giggles* Uh oh!$1", + "#$p 102#%...$2|You're supposed to do that on the potty you know.$4", + "#$p 102#%...$2|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" + "#$p 102#%Ewww!$3|Oh... gross...$3", + "#$p 102#%Ewww!$3|Ewww$3", + "#$p 102#%Ewww!$3|...$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" + "Ewww!$3", + "#$p 102#%Ewww!$3|Ewww! Don't there!$3", + "#$p 102#%Ewww!$3|...$2" ], "ground_attempt": [ - "#$p 102#%Jas doesn't seem to notice what happened.|Eww! Why are you trying to on on the ground?$3" + "#$p 102#%...$2|Eww! Why are you trying to on on the ground?$3" ] } }, From 375ce36ad7abc6ae81ccedd176a891058b91b39a Mon Sep 17 00:00:00 2001 From: Proximitron Date: Fri, 13 Dec 2024 23:04:30 +0100 Subject: [PATCH 5/9] Testversion for change and get changed implementation --- README.md | 8 +- Regression/Assets/peePoop.xcf | Bin 0 -> 106045 bytes Regression/Assets/peePoop_s.xcf | Bin 0 -> 24113 bytes Regression/Assets/pee_poop.png | Bin 0 -> 33663 bytes Regression/PrimevalTitmouse/Animations.cs | 272 ++- Regression/PrimevalTitmouse/Body.cs | 26 +- Regression/PrimevalTitmouse/Container.cs | 16 +- Regression/PrimevalTitmouse/Data.cs | 4 + .../PrimevalTitmouse/InventoryPatches.cs | 38 + Regression/PrimevalTitmouse/Regression.cs | 1769 +++++++++++------ Regression/PrimevalTitmouse/Strings.cs | 68 +- Regression/PrimevalTitmouse/Underwear.cs | 1 + Regression/Regression Dialogue/Content.json | 97 +- .../Dialogue/NPCs/Abigail.json | 4 +- .../Dialogue/NPCs/Jas.json | 147 +- .../Dialogue/NPCs/Jodi.json | 112 +- .../Dialogue/NPCs/Maru.json | 4 +- .../Dialogue/NPCs/Penny.json | 4 +- .../Dialogue/NPCs/Sam.json | 18 +- .../Dialogue/NPCs/Sebastian.json | 5 +- .../Dialogue/NPCs/Vincent.json | 119 +- Regression/Regression.csproj | 6 +- Regression/config.json | 2 +- Regression/en.json | 204 +- 24 files changed, 1929 insertions(+), 995 deletions(-) create mode 100644 Regression/Assets/peePoop.xcf create mode 100644 Regression/Assets/peePoop_s.xcf create mode 100644 Regression/Assets/pee_poop.png create mode 100644 Regression/PrimevalTitmouse/InventoryPatches.cs diff --git a/README.md b/README.md index c25c156..dbbddfa 100644 --- a/README.md +++ b/README.md @@ -51,17 +51,13 @@ Highly recommended: (Allowes ingame configuration of the mod) - 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/Assets/peePoop.xcf b/Regression/Assets/peePoop.xcf new file mode 100644 index 0000000000000000000000000000000000000000..88ff949e1c9b329165b4826c976b2a9f469b9260 GIT binary patch literal 106045 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�L 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%0ALs4*cqV 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 z z6}QAmiM9N#BVMS}XBodB2_E8a1M#KA%bQxRCTnp*@f@omkUlAvE@D!*>xq(Dr_g?4 zFD&+O;*>Dmr*!sR8YC2Su=GQe%J;sg-ovwiJg#`oc4}w(amm+g?Jt??-9>+<0((q7 zaK(C6|3*f+Yf&hcfAd;KnLA@q`Hw?0xS!T`VE=yWKF%GezGP0xLe)&H?T6bQ+iHCj zI?bL_x~gslw}U*9EqeTUSgKl`dE0(#mn$5Oe0lbC`+TCfeR%_#XreqC=zB^bER|AJo4ZaOJWHhK&_nC+Z(&ASix;cc zjuH7}oBHD27Rwy;b_p$i&gYaTAJX}p`oaCvoYpeIAftJz`GcLTJMG{4Lh*D*DH9`I zMJ-|#$YR)wcy2X8Kl;k4I3hL=CLdYkn( zAwJ{yq>};2F3Wr1Z|2H~ZRmlRxViWLIj=GLU9KUv=FM3Go&_SGPdQfNyvq>ha+``E z1bCm!&@SHQU6$JT!`%;yl96{*04*Z81}~8Lweu{06SW2=p%CbMYmFNz@uJ8#u1Cx= ztNFr@A<>PFLj7Vi0KF!1+{m~M;51+S6ac>dNH>HIVJ<6(Lc0R@0}a_XoFYodu~?rK z(g>Mizmkp@O;u!U`=oKF}Ax zeR~iXxQO$FmB;Uju+Cz_GM*Y4ih;nK4mP_l(tGv&NMgP*HW;~nmC{knbz{*!Et2f% zj`WR`8yNNW+~jI*sO>x)p~$UN${6ea@Z%2{gIU^j(1sLAd!i7vf)MQTJHlL; zd>4eeb#OF3bOX}W^nPJLeovLK4qD6-j*Km>P392GUM?}ecBPjt)81{9+GiF_%Um0^ zNo%5vVM1aziN<~af#(MwMF;z#mrXt(({!5gOSd+i$%Z@W>mNjVKN7jgE|v~S6Nz-) z(yuJ)$FA4hK&f7g_p^=BzMHbbWR;;IWfz`=s$_K>gLg1H9*Fc_zuYyDCP9P@zB8N} z8Xk(p%rY{2Vq+lrF_mXRFd7~j#zs0GW4&)9J(m4%;bRJ3CmOlg)oYJf`X>7a?84JV zwSJ?|5lQuQMFt#ZP6HZp^me5C@}(=+dwR9Va9@AFI1{1U18|L_y*)RsUcG{DEQhxR zW`RRM_>X8xv^m3fhG2Q{TR@4pHgsFoDL!~-l>buLQw!&UcAtVd#$+On*Mpw!E_%d< z?u#dKNtfH@u8u|k{XyT*8AD!?( z&^5X}`W0f$$k=7S$0dS7J=mg$Pj@d@{pZ_{`h7tVg<{3&JyPFzt{YqOsbi^tQ)f7K z<&?MXuo#yL{g3Y>ugBAR0nN_j1#`k>c?y`AJF(OL1~+z(fdJB9zaFxNljro_PP!{6 z6bOo1C_(*HXE+>!gv--M{6248gExFW^6@aVSsz}6^-i>Fw`^Fg4iA2Grp;S_#M9jD zpRNxvlqQU*-A(@Rg^yCj#_i+>7s7ZGb-O)HKI(D?ENwMq4o9u`QWhAce=pAwX+ z1o4sw&F|0??q<{nW{{`ez9UmpFrHX*MowLW}p-Wxf8eyU{O}v_@b){bT^5E*Wg`x{ny6 z=fWrpd?tTl1h8L44uoVXldfDcGcC@*SoO!4}?!${b&TIEGX*8UTf55j-V`KYh1Z{NByzk@htkCIh|}F`jh5z%v091c6AabLU(-aAf~^p#O_zPKhw7pWeF47 zW&08xyPrmpF=x0S@@q|U=BbDGJ^ZMgd6034NJWw?BGQzIkL6)v!3?1TA=iXc8Q(k~ z>RnPW$%Dpw_(2#C;>iKG2%^`qw`%i}*|<$3d>e3GPT9#i_2ugPEGzz>EW?hR!c}Ug zvaWaJIaaBtMawRz#8b`7zQ4G4K%)LlBc#Hf&pfhqaVt;S=1IF?99B-s-QeU%9BfC>J>{3l05gfKbA@vK4FHIg6?{ zeC^r&Cw`TsqA$Ar@2GEYUwhB&EOZHc<4i(X5SPrFWe^CTBWw2J2X{Pw-(LNDJMz@% zg8RO)eR)B)9r_gD6T<|;#a~pYb_v|sf*KG?_|1$ktyME+9|DMjwy!V-%Pd>ThnN`f8_4EIJ$lrcew^xeE_q*r^8&uNz+vXF$T&u?3+)(q)UpJov zoISqdd{f@s)!I5WoK;x5@(bTBf7f^XjU`Le$M%=bA8*-v-wRLJvh!vySh?xT>a~My zXLj79ZtXmOqV9F|r7f%AwAeb9T#y;+{*@{+XSxJsGi4XdUcCO9@2VFLdi=*uUkdD4 zI#UfS+xd6jZ#bZP4t-yJ@5>vOloVtmh5wKO_~0(8xVw7YV_#C%*WYb!>p1hCf5);M zb!*vM_`~nNU$eGCspUWT zo3H%YrqzopigS56*f!!Xkx~~ecplF$E}wtblI5%Jdtlv$jhi-Y-m+!$rcE0+tb1V1 zsukSeTvn7nO#r=YDIq&d5CAq^A}~#32`~;dF+B3U7HomIHF_W5!&F$(FAYdI10o>( zBB%?2B|s!bZon3mC}+3UI~nOS3IB)zW<_LnMg-IfMBHTefT%b5nD|fF4cooGVd7AQuGWBT>B($%Skl(ILxhq{fljL)ypg z(AO)tWKy*>hkW_Y`)C((kp4%zZ^E3_%qKE25k*RlPa}crBn1xz9!6{7+ZxU^fdPrfE(g!XcDpA=8N|raCIDOSbTnKu$m!rBkFM@gXZs!8b;_ z``I6vBIu7|xu(LU=PH)Knd~5f#3hzf5?Gqs;tWN4CQBfY`7FUFMS5(RXkpz@d$0^3 zudszqXU4WMX6Y5|j@->vq;klSq*xcMdafD6g2RhQm#+4VJ2SJF>=4xk7e@7V-MH-}m)LJl-iTzG-C3a~hx(k@L#G*w&+$^OrBMth z__7PzBQlO`q>l0}7s(@%Q0)OhAb66kCjnLo1l=#h8Rx68H9_GB*%@!)oZ<7S3K!Nf!=@) zaD;{gDV07sh7-{RXK^nChFokkg0Bkx40kM~LlaPyrfyKr`+ ztd`exvL}tT%Dmg3q%|J#gg+QbW3$pTV_+o)pB=Ay)?Q2UifzitW^=FHO;-_2Z z>ec!R++NqeJ#$rwU}Bv6Qu_}agqTdUz5IDRFO(|hqshk}|H9wf(9|@m>e)G!RGGBe zr)@t(Ox;&!PqTAeIi{CYR4}i|YI`(dMW%=zTEcfU9ui7H#`mQxo%FUo6cB9c8nWiTUJRs*VnU zgjsLH+6fMCmUPNmvZ`=5x}VXV9qKQZ;fk6D`M;THb1ZpA>3dMcym44%r`Q6v^@GZt<5-l3(-(B~Zd{K`@jHI_~rw>uX-^2)oN^Z`iF zV|cCjwA^@B-ot;7LnBI^R?n>v%#uqIl0?%S`p`E_J8H_sy@ZD#&pN=t(pwlKCz*bm9%QdbY4Z=4?%k z5liPl{crzj&D=b4eWn0bJMSNVd-3{GZcQS=_@sdacyj-V+Bg>?)8^)3Gl|wm`Y<)p*_7N7 zZhYWd8!Bc@vk`5USSzef9o%Tz(|ZpDdQ;+$cM%X2X&>1^81pN4Wx=Z?9w ztX%tGVTtzsjLb|1p9RAgb-#uy0vF5T&uCl$*IT^?dchrqOO0zHuIOPmhwm{Aqq+&- zp=KnVR=ByWta#Hl+%q(h$VFR<3$_&(X&)%vX3;KQa@!p=B%-viFs*#c=91El#c7)g z%8IF{3Rm!wMT@k<0k|EdBw1QkU@lHGZz(OJVl>sylecbrXk)Q<>*kH6MJYkaCFa7- z8#iy!CM#cQTg>YUv>D33%oGH#`!~UvTIC-NesF7fL1F18voXfNdGp>G=nuxmQ zY0HYY6%-Y08;QfV%$fgS*+%XC#ap(PZr(IEDKkAINn59(zR6mMBkP*%RNST}Em7XRiZy)m8C`hSHib%DMfQB*oLRl&CC36QeIw+8o!Uq-i`Xu&CB|4 z6bH=31ng30U)&GMScUU%W+nm0Lw!9T+LD1#DE&r;r^7L(`B_-+q_EG0d zx>{qjfn4)Z{ph=i8}xlodfNAW^Q>!xMw|=axE>d6U_s@ZH<#y^+_!NfZWupYwBHh3 ziPSy+QT#>U#zp;UjKEH z-*IPr-wd;gVTstvIJVDXMDjB?Gz<59tEc0ueCu?^L!^#B6|O9B!rA$H@!EAof0weD zfvt0;hV^+RB}Mm1q;E1K$cNr6DB?@q(=5Wx@1je)diDTv>i^Z(63>K|>vCZ{^NVYS~ zU=kx%OB)OPEraHgb;XY#Yi_yp^Urn@3Z`zGtn{v`E#+QG}vOS)WKcRQ#!uM|>};GGwX|xguB@CO*$IH!0XXe&n<@@d*Z>87>lcT%cH+L)cT|J zW#<^i)BWMP+yZDX*20!}3$ydz>wmo_is^SgnO~wP6+sp=XCY9PgmP+1Ig7`<-cnq& z_W5&Bj3_<1uEgIWn=L9cDOOonGbs(VcuUs3C?Vr;sI#W1Fu>w1T7BEnmBmQIU1YWt zuUfivRS{>_Sfs+D8WjnH1~(O&{Vks2q-JFp1f!lGj4RA z#v-P&LKxLNtt#4wV!k=aPb(Cr`e) z01q)#YA#qjdGcb~>>yWCYURHnL5%lwa7=68BgMgZ2;apQKjs{G7(t#((N%{xt~HmM zknFm$1!$p#h_PyYDYFmrO!sJlILQKSy}xgQ60Pd6I=KmTWTN7>|k}CF@W?e~V}?+qhx$ zdQ!@*7t5g00E<|(%|q0TG*n&`WDyG={pRb)Pu-uN`uvkU&lD-)#oOFO#fWv4>xv;z zw5b#EJ!Jj*)`w8M0AwQXLmt9!yzdv9Ay86!LP>$qeR60+Nh$O%ply5v5%D1Nr@~-V zWYLyR<}rbcV#FJq<%L0(0rUFe4>4vJjV^j)9n$caOV+;lbD5I_GwyjZGnwgmwg}z> z=F*~%YZ%6R(EHEgk`Rm6T(skYK%i0;5!-eYz-zFixE4CNb@Z*RWkobAw6IMFn+Y^L zW*%`JFE2KSTEybA4yqNxIM+kv&zN~5TMXEu_O(OHa zNF4W-IHS-!B}H0-w3k>&m*gP&;tsqU=Vp~nnMyu`$KtRGL( zBPmD^B$@QatPO8{@zUF`9Y>J#=Vd0&ASWS+O=69#fi-#)4XLwAc3n0wQtdQjxXEqQ zBV%3qvo<{=y*$}4%H*a6f$wxWfvie1QlTW1DG6yCmg*RJQA&hKf(Mr*n)GRZOJt;} zMtzJ)FeX_Tbpj*JGZ|t{k}(exi!|F{j5Udd8{O)7Mr>MS(8roQ#svhEHz9G1U^;Yn zvMvU~sdsA#=8?#k)?{R)7>&^;mvLfNM*gRwOvo6<_4=YjgCW^u)FU;oKGAUVKM09p zgbkDRMk8n9p}Hhfl0QmiG-{HDjJU%SB8>&`?#zT}tx%H@ttk*?4bPKKrlMP0HlSdb(Vi_(>&zT0GSbZpmkuVf> zrZRcZ2#m>jUOFSx%rp3;)f~2Jema$D&}hKxg_%FTowg@ZwLN?GurtXiPRPQo`qi;Q36(dA~=4 z#l+x^XI$j|8G2(d8l357Dk9BM%5M}+#`HgOP!^#RQ_B4rdYZRUFiahw^P`k)LL_3~ zAb4v%#N4u%xo<@ZluE^<rqZg%cVz!Zg zw+P*Vj!pRE4-JcG{zi?7&}T{F=-_kHUw=>MB^B{B-nnHOI=MlG-~^M3_GA5m=Wf|J z94!Ct@FQ7CI^;D#Q`4EQ|L&&0ny3;b#OH{6+HYq~&?V}0h&*64=o5`IR+YW-oSVVS zGDHqPA}6KaIxo{`NHDpQCrr9&d7W1zoGwiV1~l z7_u~qk#Fac84?-E$oA+IMpk!^LO~XUF@zn*$Xn!ahPZLzM$(g$VT`;hIuy6Tj7UeW z5Js9Vzk&@0#|B;T;hgAUvP&C^)$=$;4E?Ef3>|=E#%}^6YBw@azHrYF`B{_B&|yft zrSqg7&UL|zB)%RuiIKy{1~Rhrc@`somg3LIr>=vtr=-#)I2NQNY$`)`sL#8gI} za2$(A!o>PPJ1i87B6(EPvYRTFeiMq%h*Zl>)Fk8?k!6{w~VkC{rF z-#74-b&wS&Jm%4bGhR+<9mK$h9WP!=gGc0>4C7>+5!ft-(GiOwkIfy0>|*ecA+#{w zNQR7yWn|VAOuO;t255A0AWD=m7HzFf!!)Bz?`s0081gt4tJrM^$1v^{TZ8?~Ga1f5 zn(_2e6I3J$1*Q*3^F}X*b#&}g@ zm>AF1&Lpwt0w*%^vlwd#`VUHc4`G(WrzbEFsmL@`dUlWx#J*ncQ36meR4D{?p>%`Q z49Cu4RG7&Ki!!mAG2^%yjFt>g}p}&z{@Ws6tk$ zMl6=tp!@6m>P6d!)BUi&LLrhFiJM*FUq9GT|K<9OsNf)fjS7v|8}gjhZf`&eY{Njk z{pnt{r5yL;XH$>M9wg;e0tdYV$wa3;=?}V{h zMh^QZu3r8$T#MX7Ubn>{w|CL@(LK;QJai8k@Ea@QO7`Ccps}$W7XvM-N2f1%62cza zqjS?E)l}Ba#^t>Em9^e(i>>EtzxqpV92d<9+@#m)>|8x-7wa498~l}GX&P8OtaqQ? zZvA718jYDvdCwkLFE`Y4P=nN9ucs1ZpSs>_|6l?ZD=c=^Z20pwe|Xre`x@%3YNW_F z)LZxMvvPK*+5UVu8v*4k+8t2O+Z#?CKYl_35qJH*6W@M&qQP#bY1KFES;Vo}Sq1E{ z+WqT2)}!AZKmP4eo2q^Y3jXHA@na{xu{WrZ03Kq8Khg_*%N9^iY^vkZu@iPpy~_@n zW5-XRy8P?KchHs4@xs3dL{i6&A3t{d7?N@|)Z5`YcKoO{uwMKkoXSXHAJ_vRwC}s) z$G_WWrB&^*?f?G7iSPE=AoLN0LZE1o33?9q(AD8XcAKVt2%50NNh{m0Ua&tO#B#xC z(vrW~np7`X%^D6vnHQ_IkUKuK!N>m5onh36`Jm7lH+s+TIKavDa`thd5lk;p}{JPN}lR^ZmQL8C$@OwbE<-0i)I zi=xReswI1IYkwga10TzTeGm-EXF{Tsrw@G&S%~(A_rsLHQGXAq7prepqko3sk~FvO z4npw0e?%z3;hzQ9dm8FL$xK`rw4G6`nsz_rnf#6|yk3nK zK%hxggQvd1{%$fxng9$w8Gk_}1NsWrAk^F6n5v4IF?hG-597h=49N=JDM@FkFd8fk1&t^;(}3A ziz^Wq{Vc$>5El|*0?Uhw|G%{kV`BJUTZd8i*M7zhU30epZmNJ`>+rZZU)UrVR( zz(r;788_4SJ!z}&8$OH+tAc9GS)xRyDmVKWBK_#3H&|_b=n^`chOp`P)DU-PPp5}& z`p-2s&8LQs)XQi$lhtuI~8^R*-%p}H9b4Kj!b~xeH z?GXFP8CNdfs8e)w z_DKeYu1p0t%HJ366g&D|l8!DCgx20LC)>w51xIH;PZE*4B(?WMA)U@4=@XJbJ&$!=B`LJaosPa3q|npu8pO(y?{~x@O`)for^`@jh;JQ7 z?@l%>njYfQLyUr=K zyDQ0bR1cXk1_t3)XJ4XI?1M_8P^bY%h*R$C_d{Yll!gBqB+~65WHeSz?an^6 zl1*>x<>qdOztck8zN`dMsmUPEB&0Fp9-Q>f%B`7AloAe&&APoo-B6;Iz4sqn6$&5bZDIJx_C9m zgg@n=HQ41Pk|HEshET0`M95Q@pi;5nPdWmeV%yM&OiQ5C`_oz_3zX+ zGTGD7r$STbKaAmJsY?wN4e*E}kWcyMUW9bG`_U@gQk#QAD{J$7g}{LqP~ly)bI~3# z20g2z2RD7_LxV@lu=GZ_+}7KN7_{99kxZXF*oijgbV7bmbk>A1-jjszO6Ed`Q|^jK zVOoTtPMT%cfTSi73@giyZWO4qhgxcQB0JFyIVa!Ui(v!(CxUUxHFA45TAS0+)8Rw| z$L!Ech^xCtjpoyaTB4hW2!_8yC5x@_#B=xbiYnsjY(rxb2D>|Ysb~8Td6k+ABC#eX zJm22!P&plrp6>3hj=mw@Gtkr8)zu3>ucNmeop4yzbBT!93U;B5p85KNc+tu+79Ff5BFFG@&5gVrKD9kiFQw3m0e247Ucs!N4jlL&tt4~a2KrG&G6 z1RZ~n)>}_!ua^uu-Pp81b_^r)$1yI6?Ohn+I3&d)&)(kduI?c+NV=Tp+jLhz=yA{x z+#Vuy_jYyn_&M0#q3)h87siIcKM;&K?c_iKb}q8Fs}s??dV6|%I$cnt$YB)oB2Yje zN4&Dg^MU{uR8OElEWwHQRz`CrB#_+6#4}ziVdUN}344yOiKD&ZCjle+Xu@>L=d9Hi zaKjSMZtoAZwKeDISWo)g$7`+DnhO}zSt2m5u6?zf)w|~cHF9rH$DT9f4n|1fu zR@|jSO6syg#%;6K9_(A8A@FmOPJ5lrh7E<)y7#sf?SK2kPr=R-a#;wMj~0#4q|AYJ#m^ zo84No|L6W>7}AdJwc5h0Qq6&;B!+jN#+@zPD(?NJr^>bTIEXvWAW&c zP+v0^Db(6p#Wk=Q(h_{pReKY_~Wf&?ZrKh zVEFFx)FeU|hx^ekr1sN$bXIZCIcn;a`8pl4uG`;>8>wwiofbKZ);;GXjO@;RwE@T% zx}{1XHjScEJXziTE;_b*tF5*Gt5E%QWu48>>akg?cU9I}>ohb8R4g6WoA(4*y>;)e zntIc7d;Q>gZ}pVL&+VZSymikh!8gKrU5DzBhn<7B_lw)YIRDA7_*vawEDh%ZvR<*G z8eJ%a&9=XzU8ZJU($DXy^G8GYQyi9JLF zAl8GW5R_ksWkL>Kk8;~~UvTQ^2rG5(#q)V=e@E7SG;8md%R)H+tXBiA;_kCDMl8`n zPSpmY{O_)ua>KKD5_jEuE2rG}EUMcddObpIC`jjUZC#*MsH^_Eq6XlC7exzMGEuq`_)4;pruNlP{$MRvKF0A^QgX?`xB21327v z6A}`)leWF|e$S6Q;|upztB{tpt~RztuB}tUz5Bu$?6Sy^rw&^^s=c31MV}r#b#5Q@ z2vygeMX*3zAD%)>LB4x0%F(B#Q~VyptvPm%k6?rj4;mSI(4HR$Xxlj1yq80p6nCHR zMTyZpmA=c_bBvZt;YtzDA8!zV8B0t5fJbP*bO}^0l^R z9M>t6z={0>$OMCgt*-892ay8s$lk%@R*WntI$v{kWE$`;6XcGXIz;cOtKIj_SvTQH z$MHeI-Fb9>EyfBIfA5c-)SyDsbxQ){ZLF=Oi8!HF`+*||kDfWP|L{Q@6=rSjx|;6> z7gK{B759*5HIML3wY9WelR9;+x2{$xmdfg?+k0|gKsUqfOPD2tnnwufY^b57wyCTt z8?gsihiV(nxupT!H^cd(2a8mN?r*Ji^x>c*?2j>~^jqs{j&u<>%yZuiXAarzFcI-` z+kx7;x?pP$%3IU$gLjY&LE`k4$>8#K4EEyb{q;39K9$v>kTrGtz8maZ;hPXR(k@<> zJ5L-qXs@e-kZu2gBWJz+-M^vBT8^~6hd@Gv&WmSHpSjTLB4juagB&dOsL$SO!n|1N zS_x(bm?E*_hd>l&2DrqZEHN_>K{_x#U?!?d{xWekdc((QYS@gXFk%w3>^huKs7?T| z*glDodjG&;&-jugW?;ORYW@@+zzFIJlCdnEk)uO`7->AQrYfs!c_*w2#6{Qb@*i~} zFz($*SM_8WRz_@IDl+*17BN^Q8FF|QR7PNmAsnnu+X-154Z}v1j+Q5ug`3TyZW1?^ znsw)3>%N=_Fxax$0!+CN!S#YXgZ|wT0E?2}p;#m?sdbDrc{@f}ne4#0&(*fT*)`Ds zd+R2+Zdc(9kgKbKQJ8-OW;zy&d};tCEV{G?#z2@i^Qg5JW?GoqLa-kHk&YXralB%N z!XeW*x-U@n{;Hzy2UTog3H z{>?)}$HU2eqKr5soO-|Eb0@%#%SNNjVIcvG?DLer^n?AJtERq2gx@-cnw|{^52o|T z)BrP;guR-(4`yhYoC-;s-SRzhoOgncdrZ7f>3xeg|a#d}j+pT(fwl$-I(2yReC+s88=4a43!p4t8e zPC(}c#lnsiw7lO0{lx?o;Ktk%rQEzXd^3lUM^~@Fre0$G{Llnhfs45{gT;w5Dn*m> z{AUvsyXoxDTK_Q~8&MdW>N_0&95;pO!)h&};6#tpSu+8mu!i=rs_4z9=mPkMJ7|?= zF#W2r51;F$>*LlZ0;otoH~x{IvHGQ(PwO-m>ljv0UH7}oSP4okPlcr6UgX9-dI`Ia z-s5*`U>jy*9=eDG{OHbZ*CZ8CCT{e-Klfsf>kqGvH{#h87*WFVPdS3=4yy6#DAq)6 zO#!zb>kXwFhjR~vVR53KRg1lB2t0(|A2)=+mMXBE>7DLSx>@6p+ljS7Xpv(cX~nLy z_t4!KI};!hxcaBw(N0gFv)g{NAH&8of@<1cM_(k;;hm1Isu}cXnH~3HM-+U#SSxpa zoXm~GQ}6-V7jTOWYRju}EISrb6DxY+oSZ{Ezcq-(x`dU&wzOl<>EL@0-=bpB&qP)= z>j3A#x;PqgytC_XiC}n8iiqEIIj~oC{QN+mA~tPbuNFn#HwQLWF{Hf1k?54#o)3oT zgzDa2W!LIBFpq_8RlTCA7rQO2oRxh$w2s{i!Io5PeL4V!9)9#w-MtR1vptU9uC~_J zj$Ujg9n{rM*ZHhNbULa{IB7|*;~Z)PbzZ#u^QH4`km|hHc;V8yHtbWd+jlz7WOJ}} zdRXqZMhA94kUige^2GNor|8b}eCv-VzHd8ClY}mvT|50)#i|>2KT79mJ_GaV59cB1 zX*vTN>yJOv-RD>1sf@&qdppo6H=W^*OT!|kA#(BpM5F^VIke~rHE0U%z6)(X9{;ZO zG)?7v`^n?qx1E8vNXv!&B|G~BGIDhOeCfi^=UTBp?YemJ0-i(J3pYJL?ZWa6=Yz1P zqDnwS>S*h51Y*noEHaUoVrMCJ|4~KLx&xa|$?+GsMfUcNeiL@FjyIHCZfV3WwreLx zZ|0wLBss?4LDGx$Si9Df#pzjZ-=}6ZUJDe{mP=1^v#? z^s!@I@ntZQpp}1wFph_FG~XV4j)y%&C;=pV)ms$#Nc9JY+PQ@0i~<^{O0v^VcgP{b9Gn`9avU*Ut5D=!%{HOy_)Ju)=CzYDEL- z?mqM0%7jrt8XTOc{6k~s|Ndw@yj@*;=W8&kAWdpZRwe(53ZuhaZ1{tDL7F~!`dv?a zeTMq+jxOsGe;BT*B*quD>4l%sDh7Ky8qfc9=BM+Q+PbjW^*Y+VS_s=W6^q2hqU~zN zm4A=IYaDL6iN}M}2HW3r@h|CqO2#yEY$e%#F6^c+F2U?Z72k)gIE!B8?(1#czadV| zu!)R|^-Cz+eYq1uA4eOcqr3I!6B)sriE(j(+BNTgf2qB*N9AyJcQpO9`+-SeYK&Pd z+s$wRqbKJ4{^Po1-yPrgk3Vjl6&nIAOkf7MfUwBu*tpo3sPI7bBg~(f`NRKUNz@Ks z)Tp=s*CJdfEfcH|yTxVY+aAK*|98kPaLNC*QI_Jz*L*UbyXIyA+*Ad_M%j!nePK6) z3%&AL02h_PC*!#9`{sDx_ch2aU5|-icBjn&^wLu^Ozif*weBv3*zJ0wI48I8YY@AG zAa=i5pPiGJeZNG&U&)6)%+Jl~e=FyeA9MhC2l}4M%gcv!9(Y|jlNtQ!`TRUZK8NzU zz56~a%A*kqOIAJT<8>!8Jx`ppWYcKC-tr1w?xnmgjuFA@y0=T4Rw0440DcE^@^Xux zIq7uDJwMx%7*F-VlI)_qLa@J1^Qs5)b8>T6uUeU1`mqA-y0;JP$gyMt>r+{rG|l|n z>@{mvuPj~ncn@GJp7d{CwJO)o;@ojH(fpj84M+8i=aeNk+Xn+X%%#_)o0qfYBseV_ zG7Yly?YNp^-byo!D&n7WSApvr1Sd>W$}MlAfUiK_%g=>3Fgt+3c{%w7)mfNp$>)W6 z@E!26!Fell-^cnGhFx)AK|W=B^Vk0EmSN=Ai$$yO)5bi2z&V!hv#|3Rcpc}GWa#A1 zoloS(SUfoo|L%<++keElv!{E1!J6E>g8Uc@o6qL*_vF>~f7uzuxSUVrB5Ndqv|UIg ze|28o^XF<{ev+PCn>&)yfG?%obuanw-k$1)!dxZAb=xf#PNNP|2l-oiU^7F%w^$1D zb90eHPGJK!Lfz!vHA*HR7dNX}l}gR2HL7y)-ZDQN9630@@>279CEHaB>I>6e^M>5D zxxjnHa^7FVVQ^P-yeN8a>i5GPPO<&m{HQLV-)nI=fsthRV}aS)s7=n>Hfns1$_7Cdc3Z@I#o`^pYnmhUVyZGJxDpXXdm5`6KufD_aJqDi&U_6^XM|~#`PP^Hf{x(??vKk?xP?w zKeRPFI}h}^xcV{5B6}4U`PnrAP*isA{cb8!w>A%?H&R)%sWZyL6N{yFM|Pk^$jvJ} zjuFK3o4OD3^DzcMB6q`gqs!bI8C}_tG9`{sm|yTW2nh$he_E3b*m!mJechh|M-Kax zWxO{yx2{>EV9&WZA5y8&%p2KxkXn3OaoFI(ZC^IRWOcKJ6&_O%e? zb2sD`KXwtvu{gPTJU_22k0Q_m7~hWj(B-zxIYAb8LH2#Qx#g#tDal4$XSU^KZ(UOm z2)W!%ozT>+HM~_;i+y7pYt6Ft{VsYo@z2gm;S?p68K|%#;EezUVhEIGCS|TfToA? zvsaqm{fFH28l|6I&gYqIZ&mFZk8X-D8{Am_+*`Z6chx#DKMR-vEW z;B0kzQ;q=p`5^G;m1#PyPCxS>nP89l4=>^LUWnePz|Z{@e%9%!Jm61{yQ6H<@YwcuE42&{Kdq5#-;r%^z2N z@R@=@d#uagr89!H?bA-y=_sw3pif<>Akcj6OkI-JpfNdVdIr5t7q3lB(oKHJh8g$e zsXDO06w-BOUQIJmn`oGU&{b&$Fv-JYwT{)Z2Dg%|PHS3$`FL?^68O-*jH_wtv>6I3 zt=Ek*4FZ^?3F(qc86eXl1%JbV-crh1r!^SXQg(W-K55hlXsy%gZ-fD&=@y+f27tD4 zf%_VSIw>Ir{BFuBG7+{3Ou~_WSvze?8U#JMNmFN(d?w16gkN8Q>M+pgE)biETKy`8 zp>}V`!c*(-rfIm4Mxxe`IOjtc(}&)lW6=2$0**c4OG%$R*9T1Z9lJ5v=u0sTAgIDu z`I~z5Sfq2&fUkWy7?bZXMlk&^WNMX6Ky6M4#T0p&9i5SumOd?cv_DiV_!rU*X*CCtDp#dvOc*0RvFC0t_7&& z47I5>?J*RBZd26H?cDjvwD(40JT(otwQ(|d*&HvWsB32Ev|v%?w6`&9urKf2`Si+E zpd#|k08>2_<4!cp7h#n4OxNon*PHe^wrsS#>KAwJd}!3{06M|5%!etoAQbJtX~%ET z?{FNlY?V=m7_PLJe7hwqJ9Z8{a{F)D2+Z=Vnms$!4;7ZY#zAC-qo!;%jnJC*d%RGm z_Jim9D9-w4SSDDd!5ezbh#=^u1H7i`^XKk1CMGIHdUK>mf7!Y7#qIA67wM}^q_5Mb zYetMz_;x(@PCl@6q z>XHIXQo;lv;5>W`)8tq`EYZ+!AF8G)a!yw zJcbWr#%nkcPkCUnUYiOoUm?yhXezjPb`pf#iP}sIYs)DJ&Js6s-^vL(T{XLLB*S~c5eE-GPhR3FHdci;o1M$R!OaS3f&3D;PPsMY!K<_AsL95qegi1{U6|POx z>1lZ=XRgb7ejTce^5cywOo;)eW(ua$@@T&@XyfA(;u8}Sw7&9~FfyX~FWpFSa@2B} z{JWcUC?ad@|8;R#Lx_n@6c+zAlg_dH(^I$1)EPoe&R-WJ)WqsMi=NARo-QFMOTOap zBeRSN+7Ocy!|9d$DL4*Q8MLOQ-ywgW@Bj{obibWF8RgUdic$|U4d@f&jW=eOy|UQH zn)fM-jx94~L;AAiGgCp652R+z%)Oh^OQFtI5TZnO`GZ2&ZDht=L!ndh85DXlj$GO67tEfqKEp$G1(OWowi#BTjDDKIst(0Whs~b4Y+g`hdwyvpcuNAV(6(p z4BdqL$*Nyd=)pLr0-H`L^ifo?7~ylb`AGCY)X?L2T`dIGTs9SfNWndMm`#5NlSg6!mW$k#7DGvuPJk^LamG3 z=xt%xG|XD^OJ+SVd!ipBUbi{x8fM)zBY+uF-*T5JGB8l1AnQ`dlGH$Ik}Q4tiO1Kk zT^O&x>JqD;g3~)#IC%Bk9jSo|tiEtAHUDa6+!l%xz`zHlgO=kmrf6_77<|2ko_9}T*%p#N8gRY zn26Uq=y^ie9AxSVy#0%#-+aC-2qJ#BeR1UQ=ePPJ6_ySSKEOP1StefO30$<}p+y0B zpn&VQKfDkls}Or*;0Rk@n1OeO0gbEhQjCyt*A>P*XwiL|B%C#u&kMoe1^Z9Tx^xvz z-ndET(GZ76^wunN3X#j&GEA5UESb!vA!PC*9Q~nTaZ{(WlThiCX8|#nf|p#E$%wIw zLSTW%pu;9j55h_0{HO)od~w12d809mO`ELn<#)`3dvg2;U#`uIFa5rNPO?&6n>0Or~8xMe2}^W~GElNs_=zC3d}M!iYHbos;(#v8FV z^A~V=))F-&CQ`OMFe3yf(yHu)K%a`1E!{XJ?tq;-AW;bgN$a0a5To6N#s~C>c zz>ugRI4%;eTNrr-E!S_k4)qhWH3>^Cv{^2xY&y zyzQyIbwkeBM8-3E-G)V4bo^kvFoWL0aKRBN#yRt^Ti~5PcbqmN7(0Wj6uAu)`PB<{ zb}g<%T=cU5*Fs!K20t2&ZFs%d=|h#W$;<@jPE<|I^Xv%aB}%7 zPA;G5yMmL8?H9bmIC)#sWdfXB1Ww+{HOV{{WeQGC`kI@YoXx^8PA+#gH8(r^F7j7! za=DHAIGl}xS8#Gk@uGg0!Aqtx-3m@FwKTOf(^E7YRl-U&%#@2QjZH0nPVsUR4=>EI zZH>(>lt^xFkr35A>mY#-;^BC|`Er+Z1uPeb;2rD~E;oW~^^xT$2oC*`ZPOLDoNsAr z25!!`w=@s>=yG0cZfbJ&g*o|_=H?+ET`tOP%}qY!+>21pFk>$EH8yvQc5+SPkb;;~ z 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 BV?O`@ literal 0 HcmV?d00001 diff --git a/Regression/Assets/pee_poop.png b/Regression/Assets/pee_poop.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c1d7fc88cd397911e4eace7ec46a8ee31362a2 GIT binary patch literal 33663 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 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; @@ -50,23 +52,24 @@ enum FaceDirection : int Up = 0 }; - public static Texture2D sprites; - private static Data t; - public static Farmer player => Game1.player; - - //Static Accessor Methods. Ensure that variables are initialized. - public static Data GetData() - { - t ??= Regression.t; - return t; + private static Texture2D _sprites; + public static Texture2D sprites { + get { + _sprites ??= Regression.help.ModContent.Load(SPRITES); + return _sprites; + } } - public static Texture2D GetSprites() + private static Texture2D _peepoopSprites; + public static Texture2D peepoopSprites { - sprites ??= Regression.help.ModContent.Load(SPRITES); - return sprites; + 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() { @@ -100,13 +103,13 @@ public static void AnimateDrinking(bool waterSource = false) return; //Otherwise say something about it - Say(Animations.GetData().Drink_Water_Source, null); + Say(Animations.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(Animations.Data.Bedding_Still_Wet, b); } @@ -120,25 +123,25 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) if (!(b.underwear.removable || inUnderwear)) { - Animations.Say(Animations.GetData().Cant_Remove, b); + Animations.Say(Animations.Data.Cant_Remove, b); return; } if (!inUnderwear) { if (b.InToilet(inUnderwear)) - Say(Animations.GetData().Poop_Toilet, b); + Say(Animations.Data.Poop_Toilet, b); else - Say(Animations.GetData().Poop_Voluntary, b); + Say(Animations.Data.Poop_Voluntary, b); } else if (voluntary) - Say(Animations.GetData().Mess_Voluntary, b); + Say(Animations.Data.Mess_Voluntary, b); else - Say(Animations.GetData().Mess_Accident, b); + Say(Animations.Data.Mess_Accident, b); player.doEmote(12, false); - if (b.IsFishing() || !player.canMove) return; // We skip the actual animations if nessesary + if (Body.IsFishing() || !player.canMove) return; // We skip the actual animations if nessesary 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)Animations.player).facingDirection.Value == 1 ? 0.0f : (float)-Game1.tileSize, (float)(Game1.tileSize * 2)), false, ((Character)Animations.player).facingDirection.Value == 1, (float)((Character)Animations.player).StandingPixel.Y / 10000f, 0.01f, Microsoft.Xna.Framework.Color.White, 1f, 0.0f, 0.0f, 0.0f, false)); @@ -146,16 +149,16 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) 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.player.position.Value - new Vector2(Animations.player.facingDirection.Value == 1 ? 0.0f : -Game1.tileSize, Game1.tileSize * 2), false, Animations.player.facingDirection.Value == 1, Animations.player.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) { - Animations.Say(Animations.GetData().Bowels_Leak, b); + Animations.Say(Animations.Data.Bowels_Leak, b); ((Character)Animations.player).doEmote(12, false); } @@ -169,16 +172,16 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) if (!(b.underwear.removable || inUnderwear)) { - Animations.Say(Animations.GetData().Cant_Remove, b); + Animations.Say(Animations.Data.Cant_Remove, b); return; } if (!inUnderwear) { if (b.InToilet(inUnderwear)) - Animations.Say(Animations.GetData().Pee_Toilet, b); + Animations.Say(Animations.Data.Pee_Toilet, b); else - Animations.Say(Animations.GetData().Pee_Voluntary, b); + Animations.Say(Animations.Data.Pee_Voluntary, b); ((GameLocation)Animations.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; @@ -186,12 +189,12 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) terrainFeature.state.Value = 1; } else if (voluntary) - Animations.Say(Animations.GetData().Wet_Voluntary, b); + Animations.Say(Animations.Data.Wet_Voluntary, b); else - Animations.Say(Animations.GetData().Wet_Accident, b); + Animations.Say(Animations.Data.Wet_Accident, b); // We skip the actual animations if nessesary - if (b.IsFishing() || !Animations.player.canMove) return; + if (Body.IsFishing() || !Animations.player.canMove) return; player.jitterStrength = 0.5f; player.freezePause = peeAnimationTime; //milliseconds @@ -200,14 +203,14 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) } public static void AnimateWettingMinor(Body b) { - Animations.Say(Animations.GetData().Bladder_Leak, b); + Animations.Say(Animations.Data.Bladder_Leak, b); ((Character)Animations.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)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)); @@ -221,18 +224,18 @@ 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); + string msg = "" + Strings.RandString(Animations.Data.Wake_Up_Underwear_State); if (second) { - msg = msg + " " + Strings.ReplaceOptional(Strings.RandString(Animations.GetData().Messed_Bed), flag); + msg = msg + " " + Strings.ReplaceOptional(Strings.RandString(Animations.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(Animations.Data.Washing_Bedding), flag, second, "&"); } else if (flag) { - msg = msg + " " + Strings.RandString(Animations.GetData().Wet_Bed); + msg = msg + " " + Strings.RandString(Animations.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(Animations.Data.Spot_Washing_Bedding), flag, second, "&"); } Animations.Write(msg, b); } @@ -281,7 +284,7 @@ public static void AnimateNight(Body b) if (!(first | second) || !b.IsAllowedResource(IncidentType.PEE) && !b.IsAllowedResource(IncidentType.POOP)) return; - var list = Animations.GetData().Night; + var list = Animations.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 = ""; @@ -330,37 +333,37 @@ public static void AnimateNight(Body 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(Animations.Data.Wet_Attempt, b); else if (b.InToilet(inUnderwear)) - Say(Animations.GetData().Pee_Toilet_Attempt, b); + Say(Animations.Data.Pee_Toilet_Attempt, b); else - Say(Animations.GetData().Pee_Attempt, b); + Say(Animations.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); + Animations.Say(Animations.Data.Mess_Attempt, b); else if (b.InToilet(inUnderwear)) - Animations.Say(Animations.GetData().Poop_Toilet_Attempt, b); + Animations.Say(Animations.Data.Poop_Toilet_Attempt, b); else - Animations.Say(Animations.GetData().Poop_Attempt, b); + Animations.Say(Animations.Data.Poop_Attempt, b); } public static void AnimateStillSoiled(Body b) { - string baseString = Strings.RandString(Animations.GetData().Still_Soiled); + string baseString = Strings.RandString(Animations.Data.Still_Soiled); baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); Animations.Say(baseString, b); } public static void AnimateShouldChange(Body b) { - string baseString = Strings.RandString(Animations.GetData().Should_Change); + string baseString = Strings.RandString(Animations.Data.Should_Change); baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); Animations.Say(baseString, b); @@ -369,35 +372,47 @@ public static void AnimateWashingUnderwear(Container c) { if (c.MarkedForDestroy()) { - Animations.Write(Strings.InsertVariables(Animations.GetData().Overwashed_Underwear[0], (Body)null, c), (Body)null); + Animations.Write(Strings.InsertVariables(Animations.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); + Animations.Write(Strings.InsertVariables(Strings.RandString(Animations.Data.Washing_Underwear), (Body)null, c), (Body)null); } } public static void CheckPants(Body b) { - StardewValley.Objects.Clothing pants = b.GetPantsStardew(); - b.pants.displayName = pants.displayName; - b.pants.description = pants.displayName; - b.pants.plural = true; - Animations.Say(Animations.GetData().LookPants[0] + " " + Strings.DescribeUnderwear(b.pants, null) + ".", b); + Animations.Say(Animations.Data.LookPants[0] + " " + Strings.DescribeUnderwear(b.pants, null) + ".", b); } public static bool WarnCurrentThreshold(float[] thresholds, string[][] messages, float currentValue, bool greaterAs = false) + { + var curr = GetCurrentThreshold(thresholds,messages,currentValue,greaterAs); + if(curr != null) + { + Animations.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; - Animations.Warn(messages[index]); - return true; + return index; } - return false; + return -1; } + public static void CheckContinence(Body b) { if (b.IsAllowedResource(IncidentType.PEE)) @@ -412,33 +427,30 @@ public static void CheckContinence(Body b) } public static void CheckPottyFeeling(Body b) { - float newFullness = b.bladderFullness / b.bladderCapacity; - - bool pottyMessage = false; - if (newFullness > (1 - b.bladderContinence)) - { - pottyMessage = WarnCurrentThreshold(Body.WETTING_THRESHOLDS, Body.WETTING_MESSAGES, newFullness, false); // index offset is 1, because we want the current, not next message - } - if (!pottyMessage) Warn(Body.WETTING_MESSAGE_GREEN); + Warn(Strings.RandString(GetPottyFeeling(b, IncidentType.PEE)) + "^" + Strings.RandString(GetPottyFeeling(b, IncidentType.POOP))); + } - newFullness = b.bowelFullness / b.bowelCapacity; - pottyMessage = false; - if (newFullness > (1 - b.bowelContinence)) + 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))) { - pottyMessage = WarnCurrentThreshold(Body.MESSING_THRESHOLDS, Body.MESSING_MESSAGES, newFullness, false); // index offset is 1, because we want the current, not next message + pottyMessages = GetCurrentThreshold(type == IncidentType.PEE ? Body.WETTING_THRESHOLDS : Body.MESSING_THRESHOLDS, type == IncidentType.PEE ? Body.WETTING_MESSAGES : Body.MESSING_MESSAGES, newFullness, false); } - if (!pottyMessage) Warn(Body.MESSING_MESSAGE_GREEN); + 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(Animations.Data.PeekWaistband[0] + " " + Strings.DescribeUnderwear(b.underwear, (string)null) + ".", 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(); + Texture2D underwearSprites = Animations.sprites; Microsoft.Xna.Framework.Rectangle srcBoxCurrent = Animations.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); @@ -449,7 +461,34 @@ public static void DrawUnderwearIcon(Container c, int x, int y) 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); + 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 = Animations.peepoopSprites; + if (peeOrPoopIcon == null) return; + Microsoft.Xna.Framework.Rectangle emptyIcon = Animations.StatusRectangle(b, type,false, LARGE_SPRITE_DIM); + Microsoft.Xna.Framework.Rectangle filledIcon = Animations.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 = Animations.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); } } @@ -461,7 +500,7 @@ private static void EndDrinking(Farmer who) public static void HandlePasserby() { - if (Utility.isThereAFarmerOrCharacterWithinDistance(player.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!")); } @@ -486,18 +525,21 @@ private static List NearbyVillager(Body b, bool mess, bool inUnderwear, boo if (overflow) radius *= 2; + return NearbyVillager(radius); + } + + public static List NearbyVillager(int radius) + { var list = Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, radius, (GameLocation)Game1.currentLocation); var newList = new List(); - foreach(var npcEntry in list) + foreach (var npcEntry in list) { - if (!NPC_LIST.Contains(npcEntry.Name)) - { - newList.Add(npcEntry); - } + newList.Add(npcEntry); } return newList; } + public static Dictionary FriendshipLossOnAccident(Body b, bool mess, bool inUnderwear, bool overflow, bool attempt = false) { var list = new Dictionary(); @@ -520,7 +562,7 @@ public static int FriendshipLossOnAccident(NPC npc, bool mess, bool inUnderwear, //Does this leave the possibility of friendship gain if we have enough hearts already? Maybe because they find the vulnerability endearing? float friendshipLoss = -1 + (heartLevelForNpc - 2) / 2; - var modifiers = Animations.GetData().Villager_Friendship_Modifier; + var modifiers = Animations.Data.Villager_Friendship_Modifier; var modifierKey = modifierForIncident(npc, mess, inUnderwear, overflow, attempt); float finalModifier = 1.0f; @@ -562,10 +604,7 @@ public static List npcTypeList(NPC npc) } return npcType; } - public static string modifierForState(NPC npc) - { - return "dirty"; - } + public static string modifierForIncident(NPC npc, bool mess, bool inUnderwear, bool overflow, bool attempt = false) { if (!inUnderwear) @@ -582,7 +621,12 @@ public static string modifierForIncident(NPC npc, bool mess, bool inUnderwear, b } public static string responseKeyAdditionForState(NPC npc) { + if (!Regression.canGetGiveChangeNpc(npc)) + { + return "_fallback"; + } return ""; + } public static string responseKeyAdditionForIncident(NPC npc, bool inUnderwear, int friendshipLoss) { @@ -615,7 +659,6 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over //Get NPC in radius var nearby = NearbyVillager(b, mess, inUnderwear, overflow, attempt); - foreach (var npc in nearby) { someoneNoticed = true; @@ -648,7 +691,7 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over { Dictionary dictionary; string[] strArray; - if (Animations.GetData().Villager_Reactions.TryGetValue(key2, out dictionary) && dictionary.TryGetValue(responseKey, out 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); @@ -656,10 +699,20 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over } + 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); - npc.setNewDialogue(new Dialogue(npc, null, npcStatement), true, true); - Game1.drawDialogue(npc); + + Regression.QueueAction(() => + { + if (b.underwear.used) + { + npcStatement = Strings.InsertVariables(npcStatement, npc); + npc.setNewDialogue(new Dialogue(npc, null, npcStatement), true, true); + Game1.drawDialogue(npc); + } + }); } return someoneNoticed; @@ -672,7 +725,10 @@ 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) @@ -748,25 +804,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); + Animations.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, 0); + },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); + Animations.Write(Strings.RandString(msgs), b, c, delay); } } } diff --git a/Regression/PrimevalTitmouse/Body.cs b/Regression/PrimevalTitmouse/Body.cs index 86808bf..0f65718 100644 --- a/Regression/PrimevalTitmouse/Body.cs +++ b/Regression/PrimevalTitmouse/Body.cs @@ -38,7 +38,7 @@ public class Body public static readonly float minBowelContinence = 0.3f; // Also describes capacity as changes are linear //Setup Thresholds and messages - private 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 + 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}; @@ -166,6 +166,7 @@ public int numAccidentPeeAtNight get => LoadInt("numAccidentPeeAtNight", 0); set => save("numAccidentPeeAtNight", value); } + private float lastStamina = 0; public float bladderCapacity @@ -595,6 +596,7 @@ public void CleanPants() 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() { @@ -650,7 +652,9 @@ 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() { @@ -668,7 +672,7 @@ public bool IsTryingToHoldIt(IncidentType type, float vsAmount = 0) 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 > 300) return false; // If the underwear is already heavily used, we stop trying + 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 @@ -900,7 +904,7 @@ public void StartAccident(IncidentType type, bool voluntary = false, bool inUnde Animations.AnimateWettingEnd(this); break; case IncidentType.POOP: - Animations.AnimateMessingEnd(this); + Animations.AnimateMessingEnd(Game1.player); break; default: throw new Exception("Not implemented: type " + type.ToString()); @@ -965,7 +969,7 @@ private void HandleOverflow(IncidentType type) private void _HandlePeeOverflow() { - Animations.Write(Regression.t.Pee_Overflow, this, Animations.peeAnimationTime); + 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); @@ -985,7 +989,7 @@ private void _HandlePeeOverflow() private void _HandlePoopOverflow() { - Animations.Write(Regression.t.Poop_Overflow, this, Animations.poopAnimationTime); + 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() { @@ -1034,7 +1038,7 @@ public void HandleMorning() { Farmer player = Game1.player; - if (bed.messiness > 0.0 || bed.wetness > 0.0) + if (bed.messiness > 0.0) { dryingTime = 1000; player.stamina -= 20f; @@ -1093,7 +1097,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); @@ -1152,7 +1156,7 @@ public void Warn(float oldPercent, float newPercent, float[] thresholds, string[ public void Consume(string itemName) { Consumable item; - if(Animations.GetData().Consumables.TryGetValue(itemName, out item)) + if(Animations.Data.Consumables.TryGetValue(itemName, out item)) { this.AddFood(item.calorieContent); this.AddWater(item.waterContent); @@ -1165,7 +1169,7 @@ public void Consume(string itemName) } public enum IncidentType { - PEE, - POOP + PEE = 0, + POOP = 1 } } diff --git a/Regression/PrimevalTitmouse/Container.cs b/Regression/PrimevalTitmouse/Container.cs index 2aa772d..eb0679d 100644 --- a/Regression/PrimevalTitmouse/Container.cs +++ b/Regression/PrimevalTitmouse/Container.cs @@ -144,7 +144,7 @@ public bool stackable { get { - return messiness == 0.0 && wetness == 0.0 && !drying && (InnerContainer == null || durability == InnerContainer.durability); + return !used && !drying && (InnerContainer == null || durability == InnerContainer.durability); } } public struct Date @@ -239,6 +239,8 @@ public bool drying { 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; } + private Container _innerContainer = null; public Container InnerContainer @@ -276,7 +278,17 @@ public Container(Body body,string subtype, string fallbackType) modDataDictionary = Game1.player.modData; if(name == "") { - Regression.monitor.Log(modDataBaseKey + " had no name, so fallback "+ fallbackType + " was used"); + 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); } } diff --git a/Regression/PrimevalTitmouse/Data.cs b/Regression/PrimevalTitmouse/Data.cs index 9b70a89..fe1e33a 100644 --- a/Regression/PrimevalTitmouse/Data.cs +++ b/Regression/PrimevalTitmouse/Data.cs @@ -29,6 +29,8 @@ public class Data 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; @@ -39,6 +41,7 @@ public class Data 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; @@ -67,6 +70,7 @@ public class Data public string[] Underwear_Wet; public Dictionary> Villager_Friendship_Modifier; public Dictionary> Villager_Reactions; + public Dictionary>> Villager_Underwear_Options; public string[] Wake_Up_Underwear_State; public string[] Washing_Bedding; public string[] Washing_Underwear; 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/Regression.cs b/Regression/PrimevalTitmouse/Regression.cs index 9b24deb..e7d1258 100644 --- a/Regression/PrimevalTitmouse/Regression.cs +++ b/Regression/PrimevalTitmouse/Regression.cs @@ -1,20 +1,30 @@ 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.Runtime.CompilerServices; +using System.Xml.Serialization; using xTile.Dimensions; +using static StardewValley.Minigames.TargetGame; namespace PrimevalTitmouse { @@ -34,13 +44,15 @@ public class Regression : Mod 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 Harmony("com.primevaltitmouse.regression"); - //harmony.PatchAll(); + var harmony = new HarmonyLib.Harmony("com.primevaltitmouse.regression"); + harmony.PatchAll(); help = h; monitor = Monitor; @@ -56,310 +68,112 @@ public override void Entry(IModHelper h) h.Events.Display.MenuChanged += new EventHandler(ReceiveMenuChanged); h.Events.Display.RenderingHud += new EventHandler(ReceivePreRenderHudEvent); - TriggerActionManager.RegisterAction("Regression.StartChange", this.StartChange); - } - 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; + h.Events.GameLoop.UpdateTicked += new EventHandler(OnUpdateTicked); - // register mod - configMenu.Register( - mod: this.ModManifest, - reset: () => config = new Config(), - save: () => this.Helper.WriteConfig(config) - ); + h.Events.Player.Warped += new EventHandler(OnWarped); - // 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 - ); + // 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); - 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.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 - ); + GameStateQueryDelegate queryDelegate = (GameStateQueryDelegate)Delegate.CreateDelegate(typeof(GameStateQueryDelegate), this, "DIAPER_USED"); + GameStateQuery.Register("DIAPER_USED", queryDelegate); - 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.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 - ); + WorldIsFurry = Helper.ModRegistry.IsLoaded("sion9000.AnthroCharactersContinued"); + SelfIsFurry = Helper.ModRegistry.IsLoaded("krystedez.FurryFarmer"); + } - // 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: () => "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 - ); + private void OnWarped(object sender, WarpedEventArgs e) + { + // Some character have random changes after warped + foreach(var npc in e.NewLocation.characters) + { + var name = npc.Name.ToLower(); + if(name == "vincent") + { + if (Regression.rnd.Next(2) > 0) npcChange(npc); + var undies = npcUnderwear(npc); + var result = Regression.rnd.Next(7); + // Vincent is oft messy or wet. Sometimes both + if (result <= 2) undies.AddPoop((float)Math.Max(400, 900)); + if (result > 0 && result <= 5) undies.AddPee((float)Math.Max(300, 700)); + } + else if(name == "jas") + { + if (Regression.rnd.Next(2) > 0) npcChange(npc); + var undies = npcUnderwear(npc); + var result = Regression.rnd.Next(7); + // Jas is less often messy, nearly as often wet + if (result <= 2) undies.AddPoop((float)Math.Max(200, 700)); + if (result > 0 && result <= 5) undies.AddPee((float)Math.Max(300, 700)); + } + else if (name == "jas") + { + if (Regression.rnd.Next(2) > 0) npcChange(npc); + var undies = npcUnderwear(npc); + var result = Regression.rnd.Next(7); + // Jas is less often messy, nearly as often wet + if (result <= 2) undies.AddPoop((float)Math.Max(200, 700)); + if (result > 0 && result <= 5) undies.AddPee((float)Math.Max(300, 700)); + } + } + } + public bool DIAPER_USED(string[] query, GameStateQueryContext context) + { + var underwear = body.underwear; - // 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 || PrimevalTitmouse.Regression.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) + var targetNpcName = query.Length > 1 ? query[1] : null; + if (targetNpcName != null) { - if (config.Messing) - { - float percentage = body.GetBowelPercent(); - StatusBars.DrawStatusBar(x1, y1, percentage, new Color(146, 111, 91)); - x1 -= 10 + StatusBars.barWidth; - } - if (config.Wetting) + switch (targetNpcName) { - float percentage = body.GetBladderPercent(); - StatusBars.DrawStatusBar(x1, y1, percentage, new Color(byte.MaxValue, 225, 56)); + case "pee": + return underwear.wetness > 0; + case "poop": + return underwear.messiness > 0; + default: + break; } + var npc = NpcByName(targetNpcName); + if (npc == null) return false; + + underwear = npcUnderwear(npc); + // 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; } - 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() @@ -372,33 +186,6 @@ private void GiveUnderwear() Game1.activeClickableMenu = new ItemGrabMenu(objList); } - private static void restoreItems(StardewValley.Inventories.Inventory items, Dictionary> invReplacement = null) - { - if (invReplacement != null) { - foreach (KeyValuePair> entry in invReplacement) - { - var underwear = new Underwear(); - underwear.rebuild(entry.Value, items[entry.Key]); - 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; - } - } - } - - private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) { var configFile = "RegressionSave.json"; @@ -440,7 +227,6 @@ private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) } locId++; } - //restoreItems(Game1.player.Items, invReplacement); Animations.AnimateNight(body); HandleMorning(sender, e); @@ -451,7 +237,7 @@ private void HandleMorning(object Sender, DayStartedEventArgs e) body.HandleMorning(); } - private static Dictionary> replaceItems(StardewValley.Inventories.Inventory items) + public static Dictionary> replaceItems(IList items) { var replacements = new Dictionary>(); @@ -467,6 +253,33 @@ 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]); + 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) @@ -474,30 +287,33 @@ private void BeforeSave(object Sender, SavingEventArgs e) body.bedtime = lastTimeOfDay; if (Game1.dayOfMonth != 1 || Game1.currentSeason != "spring" || Game1.year != 1) body.HandleNight(); - + 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); + foreach (var furn in location.furniture.OfType()) + { + Monitor.Log(string.Format("Found storage furniture {0}", furn.DisplayName), LogLevel.Info); + } + locId++; } - locId++; } + var invReplacements = config.WriteSaveFiles ? replaceItems(Game1.player.Items) : null; - var invReplacements = replaceItems(Game1.player.Items); - + var configFile = "RegressionSave.json"; if (config.WriteSaveFiles || jsonLoaded.ContainsKey(configFile)) { @@ -519,26 +335,240 @@ private void BeforeSave(object Sender, SavingEventArgs e) if (jsonLoaded.ContainsKey(configFile)) jsonLoaded.Remove(configFile); } } + public NPC NpcByName(string name, int range = 20) + { + name = name.ToLower(); + foreach (var npc in Animations.NearbyVillager(range)) + { + if (npc.Name.ToLower() == name) + { + return npc; + } + } + return null; + } + public bool StartAccident(string[] args, TriggerActionContext context, out string error) + { + + error = null; + + 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(); + + if (args.Length < 3) + { + error = "Parameter 2, type, should be given!"; + return false; + } + var typeStr = args[2]; + + IncidentType type = IncidentType.PEE; + switch (typeStr) + { + case "pee": + type = IncidentType.PEE; + break; + case "poop": + type = IncidentType.POOP; + break; + default: + error = $"Parameter 2, type '{type}' is unknown!"; + return false; + } + + + if (target == "player" || target == "farmer" || target == "self") + { + body.Accident(type); + } + else + { + var targetNpc = NpcByName(target); + if (targetNpc == null) + { + error = $"Parameter 1, '{target}' not found in local npc list in 20 range"; + return false; + } + npcAccident(targetNpc, 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 = NpcByName(target); + 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 = npcUnderwear(targetNpc); + // 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); + + + if (who.ActiveItem == newUnderwear) + { + who.reduceActiveItemByOne(); + } + else { + newUnderwear.Stack -= 1; + if (newUnderwear.Stack < 1) + { + who.removeItemFromInventory(newUnderwear); + } + } + + npcChange(targetNpc, 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,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[1] != null) + if (args.Length > 1) { underwearName = args[1]; } var diaper = new Underwear(underwearName, 1); + Underwear underwear = new Underwear(body.underwear, 1); - // We have to do all this before we change the underwear, because we lose the reference + body.ChangeUnderwear(diaper); + body.ResetPants(); //If the underwear returned is not removable, destroy it - if (!body.underwear.removable && !body.underwear.washable) + if (!underwear.container.washable) { - Animations.Warn(Regression.t.Change_Destroyed, body); + 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)) @@ -547,13 +577,13 @@ public bool StartChange(string[] args, TriggerActionContext context, out string objList.Add(underwear); Game1.activeClickableMenu = new ItemGrabMenu(objList); } + var dirtyPants = body.HasWetOrMessyDebuff(); - body.ChangeUnderwear(diaper); - body.ResetPants(); - if (args[2] != null) + + if (args.Length > 2 && dirtyPants) { - body.pants.displayName = args[1]; - body.pants.description = args[1]; + body.pants.displayName = args[2]; + body.pants.description = args[2]; } } catch (Exception e) @@ -565,67 +595,113 @@ public bool StartChange(string[] args, TriggerActionContext context, out string error = null; return true; } - private void ReceiveUpdateTick(object sender, OneSecondUpdateTickingEventArgs e) + public bool AddNpcMessage(string[] args, TriggerActionContext context, out string error) { - - //Ignore everything until we've started the day - if (!started) - return; - - - //If time is moving, update our body state (Hunger, thirst, etc.) - if (ShouldTimePass()) + try { - 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 (args.Length < 2) { - tickCD2 += 1; //This should trigger multiple times during the eating animation. + error = "Parameter 1, target, has to be the name of an npc"; + return false; } - if (tickCD2 >= 2) //Setting this to 2 should be able to balance preventing double triggers and ensuring no loss in intentional triggers. + var target = args[1]; + target = target.ToLower(); + var targetNpc = NpcByName(target); + if (targetNpc == null) { - tickCD1 = 0; - tickCD2 = 0; + error = $"Parameter 1, '{target}' not found in local npc list in 20 range"; + return false; } - - - // The following block makes npc (usually) not talk to you if you wear wet or messy pants... short of the special texts + 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) RemoveDialogueFromNPC(targetNpc, eventToken); + } + var msg = args[2].Replace("___", "#").Replace("$_", "$"); + targetNpc.setNewDialogue(new Dialogue(targetNpc, 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; + + + //If time is moving, update our body state (Hunger, thirst, etc.) + if (ShouldTimePass()) + { + 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. + { + tickCD2 += 1; //This should trigger multiple times during the eating animation. + } + if (tickCD2 >= 2) //Setting this to 2 should be able to balance preventing double triggers and ensuring no loss in intentional triggers. + { + tickCD1 = 0; + tickCD2 = 0; + } + + + // The following block makes npc (usually) not talk to you if you wear wet or messy pants... short of the special texts var newList = new List(); - var isFilthy = body.pants.wetness > 0 || body.pants.messiness > 0; + var isFilthy = body.pants.used; var list = Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, 10, (GameLocation)Game1.currentLocation); foreach (var npc in list) { - if (npc.CurrentDialogue.Count > 0 && npc.CurrentDialogue.Peek().TranslationKey == dirtyEventToken) - { - RemoveDialogueFromNPC(npc, dirtyEventToken); - } + if (npc.CurrentDialogue.Count > 0) RemoveDialogueFromNPC(npc, dirtyEventToken); + if(npc.CurrentDialogue.Count > 0) RemoveDialogueFromNPC(npc, generalEventToken); + + if (isFilthy) { - var npcName = ""; - var mod = Animations.modifierForState(npc); + var mod = "dirty"; var responseKey = mod + Animations.responseKeyAdditionForState(npc); - var npcType = Animations.npcTypeList(npc); - List stringList3 = new List(); - foreach (string key2 in npcType) + + var randNpcString = Strings.RandString(GetVillagerReactions(npc,responseKey).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")) { - Dictionary dictionary; - string[] strArray; - if (Animations.GetData().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); - } - + npcStatement = Strings.ReplaceOptional(npcStatement, body.HasWetOrMessyDebuff()); } - - var randNpcString = Strings.RandString(stringList3.ToArray()); + npcStatement = Strings.InsertVariables(npcStatement, npc); + npc.setNewDialogue(new Dialogue(npc, dirtyEventToken, npcStatement), true, true); + } + else if (npc.CurrentDialogue.Count <= 0) + { + var mod = "general"; + var responseKey = mod + Animations.responseKeyAdditionForState(npc); + + var randNpcString = Strings.RandString(GetVillagerReactions(npc, responseKey).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); - npcStatement = npcName + npcStatement; npc.setNewDialogue(new Dialogue(npc, dirtyEventToken, npcStatement), true, true); } + } @@ -638,6 +714,128 @@ private void ReceiveUpdateTick(object sender, OneSecondUpdateTickingEventArgs e) tickCD1 += 1; } } + private List GetVillagerReactions(NPC npc, string responseKey) + { + 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); + } + + } + return stringList3; + } + public static string npcDefaultUnderwear(NPC npc) { + switch (npc.Name.ToLower()) + { + case "vincent": + return "baby print diaper"; + case "jas": + return "lavender pullups"; + default: + return npc.Gender == Gender.Male ? "big kid undies" : "polka dot panties"; + } + } + public static Container npcUnderwear(NPC npc) + { + return new Container(npc, "underwear", npcDefaultUnderwear(npc)); + } + public static string npcDefaultPantsName(NPC npc) + { + switch (npc.Name.ToLower()) + { + case "vincent": + return "toddler pants"; + case "jas": + return "purple toddler skirts"; + default: + return npc.Gender == Gender.Male ? "pants" : "skirt"; + } + } + public static Container npcPants(NPC npc) + { + var staticType = "blue jeans"; + var defaultName = npcDefaultPantsName(npc); + var pants = new Container(npc, "pants", staticType); + if(pants.displayName == staticType && defaultName != "" && defaultName != pants.displayName) + { + pants.displayName = defaultName; + pants.description = defaultName; + } + return pants; + } + + // a very simplified accident mechanic that assumes that the npc has an accident in a way that the diaper can be anywhere from full to empty + public static void npcAccident(NPC npc, IncidentType type) + { + + var underwear = npcUnderwear(npc); + var accidentSize = (float)Regression.rnd.Next((int)(underwear.GetCapacity(type) * 0.1f), (int)underwear.GetCapacity(type)); + if (type == IncidentType.PEE) + { + npc.movementPause = 3000; + npc.doEmote(28, false); + underwear.AddPee(accidentSize); + Game1.playSound("wateringCan"); + } + else + { + npc.movementPause = 3000; + npc.doEmote(12, false); + underwear.AddPoop(accidentSize); + Animations.AnimateMessingEnd(npc); + } + + + + } + public static void npcChange(NPC npc, string underwearName = null, string pantsName = null) + { + var underwear = npcUnderwear(npc); + if (underwearName != null) + { + underwear.ResetToDefault(underwearName); + } + else + { + underwear.ResetToDefault(npcDefaultUnderwear(npc)); + } + + var pants = npcPants(npc); + pants.ResetToDefault(pants,0,0); + } + // This refers to the "general" interaction that can contain dialog to getting changed or doing changes, depending on the character interacted with. It could also be both. + public static bool canGetGiveChangeNpc(NPC npc) + { + int heartLevelForNpc = Game1.player.getFriendshipHeartLevelForNPC(npc.Name); + switch (npc.Name.ToLower()) { + case "vincent": // can get changed + return heartLevelForNpc >= 6 && Game1.player.getFriendshipHeartLevelForNPC("Jodi") >= 4; + case "jas": // can get changed + return 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; + case "penny": + return heartLevelForNpc > 6; + default: + return false; + } + } + private void RemoveDialogueFromNPC(NPC npc, string keyRemove) { // Temporary stack to hold dialogues we want to keep @@ -769,233 +967,664 @@ private void ReceiveKeyPress(object sender, ButtonPressedEventArgs e) 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;*/ + + } + } + } + + //A menu has been opened, figure out if we need to modify it + private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) + { + //Don't do anything if our day hasn't started + if (!started) + return; + + DialogueBox attemptToSleepMenu; + ShopMenu currentShopMenu; + + //If we try to sleep, check if the bed is done drying (only matters in Hard Mode) + 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.drying) + { + Response[] sleepAttemptResponses = attemptToSleepMenu.responses; + if (sleepAttemptResponses.Length == 2) + { + Response response = sleepAttemptResponses[1]; + Game1.currentLocation.answerDialogue(response); + Game1.currentLocation.lastQuestionKey = null; + attemptToSleepMenu.closeDialogue(); + Animations.AnimateDryingBedding(body); + } + } + } + //If we're in the mailbox, handle the initial letter from Jodi that contains protection + else if (e.NewMenu is LetterViewerMenu && Game1.currentLocation is Farm) + { + LetterViewerMenu letterMenu = (LetterViewerMenu)e.NewMenu; + Mail.ShowLetter(letterMenu); + } + //If we're trying to shop, handle the underwear inventory + else if((currentShopMenu = e.NewMenu as ShopMenu) != null) + { + //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) + { + foreach(string type in availableUnderwear) + { + Underwear underwear = new Underwear(type, 1); + currentShopMenu.forSale.Add(underwear); + currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, StardewValley.Menus.ShopMenu.infiniteStock)); + } } } } - //A menu has been opened, figure out if we need to modify it - private void ReceiveMenuChanged(object sender, MenuChangedEventArgs e) + //Check if we are at a natural water source + private static bool AtWaterSource() + { + GameLocation currentLocation = Game1.currentLocation; + Vector2 toolLocation = who.GetToolLocation(false); + int x = (int)toolLocation.X; + int y = (int)toolLocation.Y; + return currentLocation.doesTileHaveProperty(x / Game1.tileSize, y / Game1.tileSize, "Water", "Back") != null || currentLocation.doesTileHaveProperty(x / Game1.tileSize, y / Game1.tileSize, "WaterSource", "Back") != null; + } + + //Check if we are at the Well (and its constructed) + private static bool AtWell() + { + GameLocation currentLocation = Game1.currentLocation; + Vector2 toolLocation = who.GetToolLocation(false); + int x = (int)toolLocation.X; + int y = (int)toolLocation.Y; + Vector2 vector2 = new Vector2((float)(x / Game1.tileSize), y / Game1.tileSize); + return currentLocation.IsBuildableLocation() && currentLocation.getBuildingAt(vector2) != null && (currentLocation.getBuildingAt(vector2).buildingType.Value.Equals("Well") && currentLocation.getBuildingAt(vector2).daysOfConstructionLeft.Value <= 0); + + } + + //Handle Mouse Clicks/Movement + private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) + { + //Ignore if we aren't started or otherwise paused + if (!(Game1.game1.IsActive && !Game1.paused && started)) + { + return; + } + + //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(); + return; + } + + //Otherwise Check if we're holding underwear + Underwear activeObject = who.ActiveObject as Underwear; + 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.drying) + { + if(Regression.config.PantsChangeRequiresHome && body.HasWetOrMessyDebuff() && !body.InPlaceWithPants()) + { + Animations.Write(Regression.t.Change_Requires_Pants, body); + return; + } + + Underwear OldUnderwear = new Underwear(body.underwear, 1); + + body.ChangeUnderwear(activeObject); + who.reduceActiveItemByOne(); + body.ResetPants(); + + //If the underwear returned is not removable, destroy it + 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(OldUnderwear, false)) + { + List objList = new List(); + 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) + { + //Are we at a water source? If so, wash the underwear. + if (AtWaterSource()) + { + activeObject.container.Wash(); + Animations.AnimateWashingUnderwear(activeObject.container); + } + } + return; //Done with underwear + } + + + //If we're at a water source, and not holding underwear, drink from it. + if ((AtWaterSource()|| AtWell()) && e.IsDown(SButton.LeftShift)) + this.body.DrinkWaterSource(); + } + + } + + //If approppriate, draw bars for Hunger, thirst, bladder and bowels + public void ReceivePreRenderHudEvent(object sender, RenderingHudEventArgs args) + { + if (!started || Game1.currentMinigame != null || Game1.eventUp || Game1.globalFade) + 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.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.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: () => "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() { - //Don't do anything if our day hasn't started - if (!started) - return; - DialogueBox attemptToSleepMenu; - ShopMenu currentShopMenu; + 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 we try to sleep, check if the bed is done drying (only matters in Hard Mode) - 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.drying) - { - Response[] sleepAttemptResponses = attemptToSleepMenu.responses; - if (sleepAttemptResponses.Length == 2) - { - Response response = sleepAttemptResponses[1]; - Game1.currentLocation.answerDialogue(response); - Game1.currentLocation.lastQuestionKey = null; - attemptToSleepMenu.closeDialogue(); - Animations.AnimateDryingBedding(body); - } - } - } - //If we're in the mailbox, handle the initial letter from Jodi that contains protection - else if (e.NewMenu is LetterViewerMenu && Game1.currentLocation is Farm) + 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) { - LetterViewerMenu letterMenu = (LetterViewerMenu)e.NewMenu; - Mail.ShowLetter(letterMenu); + 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 we're trying to shop, handle the underwear inventory - else if((currentShopMenu = e.NewMenu as ShopMenu) != null) + if (config.Debug) { - //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) + if (config.Messing) { - //Joja shop ONLY sels the Joja diaper and a cloth diaper - availableUnderwear.Clear(); - availableUnderwear.Add("joja diaper"); - availableUnderwear.Add("cloth diaper"); - underwearAvailableAtShop = true; + float percentage = body.GetBowelPercent(); + StatusBars.DrawStatusBar(x1, y1, percentage, new Color(146, 111, 91)); + x1 -= 10 + StatusBars.barWidth; } - - if(underwearAvailableAtShop) + if (config.Wetting) { - foreach(string type in availableUnderwear) - { - Underwear underwear = new Underwear(type, 1); - currentShopMenu.forSale.Add(underwear); - currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, StardewValley.Menus.ShopMenu.infiniteStock)); - } + 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); - //Check if we are at a natural water source - private static bool AtWaterSource() - { - GameLocation currentLocation = Game1.currentLocation; - Vector2 toolLocation = who.GetToolLocation(false); - int x = (int)toolLocation.X; - int y = (int)toolLocation.Y; - return currentLocation.doesTileHaveProperty(x / Game1.tileSize, y / Game1.tileSize, "Water", "Back") != null || currentLocation.doesTileHaveProperty(x / Game1.tileSize, y / Game1.tileSize, "WaterSource", "Back") != null; + Animations.DrawStateIcon(body, IncidentType.PEE, x3, y3 + 74); + Animations.DrawStateIcon(body, IncidentType.POOP, x3, y3 + 74 + 74); } - - //Check if we are at the Well (and its constructed) - private static bool AtWell() + private void ReceiveTimeOfDayChanged(object sender, TimeChangedEventArgs e) { - GameLocation currentLocation = Game1.currentLocation; - Vector2 toolLocation = who.GetToolLocation(false); - int x = (int)toolLocation.X; - int y = (int)toolLocation.Y; - Vector2 vector2 = new Vector2((float)(x / Game1.tileSize), y / Game1.tileSize); - return currentLocation.IsBuildableLocation() && currentLocation.getBuildingAt(vector2) != null && (currentLocation.getBuildingAt(vector2).buildingType.Value.Equals("Well") && currentLocation.getBuildingAt(vector2).daysOfConstructionLeft.Value <= 0); + lastTimeOfDay = Game1.timeOfDay; + + //If its 6:10AM, handle delivering mail + if (Game1.timeOfDay == 610) + Mail.CheckMail(); + + if (Game1.timeOfDay < 630) + return; + //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(this.body); + + if (rnd.NextDouble() < 0.0555555559694767 && (body.NeedsChangies(IncidentType.PEE) || body.NeedsChangies(IncidentType.POOP))) + Animations.AnimateShouldChange(this.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"); } - //Handle Mouse Clicks/Movement - private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) + private delegate bool ActionHandler(string[] args, TriggerActionContext context, out string error); + public bool ActionManager(string[] args, TriggerActionContext context, out string error) { - //Ignore if we aren't started or otherwise paused - if (!(Game1.game1.IsActive && !Game1.paused && started)) - { - return; - } + error = null; - //Handle a Left Click - 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; + // Remove the first arg "ACTION_MANAGER" + args = args.Skip(1).ToArray(); - ////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)) + // 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)) { - this.body.DrinkWateringCan(); - return; + /*error = $"Unknown action: {actionName}"; + return false;*/ + // we will just assume that its not an action but a parameter from another function } - //Otherwise Check if we're holding underwear - Underwear activeObject = who.ActiveObject as Underwear; - if (activeObject != null) + // 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 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.drying) + if (actionHandlers.ContainsKey(args[i])) { - if(Regression.config.PantsChangeRequiresHome && body.HasWetOrMessyDebuff() && !body.InPlaceWithPants()) - { - Animations.Write(Regression.t.Change_Requires_Pants, body); - return; - } - who.reduceActiveItemByOne(); //Take it out of inventory - Underwear underwear = new Underwear(body.underwear, 1); - - // We have to do all this before we change the underwear, because we lose the reference + nextActionIndex = i; + break; + } + } - //If the underwear returned is not removable, destroy it - if (!body.underwear.removable && !body.underwear.washable) { - Animations.Warn(Regression.t.Change_Destroyed, body); - } - //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); - } + // Extract arguments for this action (including the action name itself) + string[] actionArgs = args.Skip(index).Take(nextActionIndex - index).ToArray(); - body.ChangeUnderwear(activeObject); - body.ResetPants(); - } - //If it is wet, messy or drying, check if we can wash it - else if (activeObject.container.washable) - { - //Are we at a water source? If so, wash the underwear. - if (AtWaterSource()) - { - activeObject.container.Wash(); - Animations.AnimateWashingUnderwear(activeObject.container); - } - } - return; //Done with underwear + // Execute the action + if (!actionHandlers[actionName](actionArgs, context, out error)) + { + return false; } - - - //If we're at a water source, and not holding underwear, drink from it. - if ((AtWaterSource()|| AtWell()) && e.IsDown(SButton.LeftShift)) - this.body.DrinkWaterSource(); + + // Move to the next action + index = nextActionIndex; } - + + return true; } - //If approppriate, draw bars for Hunger, thirst, bladder and bowels - public void ReceivePreRenderHudEvent(object sender, RenderingHudEventArgs args) + 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) { - if (!started || Game1.currentMinigame != null || Game1.eventUp || Game1.globalFade) - return; - DrawStatusBars(); + actionQueue.Enqueue((action, delay)); } - private void ReceiveTimeOfDayChanged(object sender, TimeChangedEventArgs e) + private static void ExecuteNextAction() { - lastTimeOfDay = Game1.timeOfDay; + if (actionQueue.Count == 0) return; - //If its 6:10AM, handle delivering mail - if (Game1.timeOfDay == 610) - Mail.CheckMail(); + isExecutingAction = true; + (Action action, int delay) nextAction = actionQueue.Dequeue(); - if (Game1.timeOfDay < 630) - return; + // Execute the custom action + nextAction.action(); - //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(this.body); + // Wait before allowing the next action to execute + DelayedAction.functionAfterDelay(() => + { + isExecutingAction = false; + }, nextAction.delay); + } - if (rnd.NextDouble() < 0.0555555559694767 && (body.NeedsChangies(IncidentType.PEE) || body.NeedsChangies(IncidentType.POOP))) - Animations.AnimateShouldChange(this.body); + 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 02846e1..11d6511 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; @@ -66,15 +67,15 @@ public static string DescribeUnderwear(Container u, string baseDescription = nul public static string InsertVariables(string msg, Body b, Container c = null) { string str = msg; - if (b != null) + if (b != null && c == null) c = b.underwear; if (c != null) { - var gettingChangedDialog = Strings.RandString(Animations.GetData().Diaper_Change_Dialog); + var gettingChangedDialog = Strings.RandString(Animations.Data.Diaper_Change_Dialog); gettingChangedDialog = Strings.ReplaceAndOr(gettingChangedDialog, b.pants.wetness > 0, b.pants.messiness > 0); - str = str.Replace("$Diaper_Change_Dialog", gettingChangedDialog); + str = str.Replace("$GETTING_CHANGED_DIALOG$", "#$b#" + gettingChangedDialog); - 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_DESC$", Strings.DescribeUnderwear(c, c.description)), !c.plural, "#"); + 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, "#"); } @@ -86,6 +87,62 @@ public static string InsertVariables(string msg, Body b, Container c = null) return Strings.ReplaceOr(str, Strings.who.IsMale, "/").Replace("$FARMERNAME$", Strings.who.Name); } + 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 = Regression.npcUnderwear(b); + 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.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, "#"); + + } + + if (b != null) + { + var pants = Regression.npcPants(b); + 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) { @@ -96,6 +153,7 @@ public static string InsertVariable(string inputString, string variableName, str public static string RandString(string[] msgs = null) { + if (msgs == null || msgs.Length == 0) return ""; return msgs[Regression.rnd.Next(msgs.Length)]; } diff --git a/Regression/PrimevalTitmouse/Underwear.cs b/Regression/PrimevalTitmouse/Underwear.cs index c447e13..34aadcd 100644 --- a/Regression/PrimevalTitmouse/Underwear.cs +++ b/Regression/PrimevalTitmouse/Underwear.cs @@ -78,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 diff --git a/Regression/Regression Dialogue/Content.json b/Regression/Regression Dialogue/Content.json index 795f210..d9257a2 100644 --- a/Regression/Regression Dialogue/Content.json +++ b/Regression/Regression Dialogue/Content.json @@ -1,50 +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" - }, - { - "LogName": "Maru", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Maru.json" - }, - { - "LogName": "Abigail", - "Action": "Include", - "FromFile": "Dialogue/NPCs/Abigail.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 index 7a62022..0e140b3 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json @@ -7,9 +7,9 @@ "Entries": { - "Diaper_Change_Accept": "#Just lie down for me!$l#$b#%Abigail changes your diaper, using way to much baby powder#$action Regression.StartChange \"joja diaper\"#$h", + "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\"#$h", "Diaper_Change_Refuse": "I was just asking.", - "Diaper_Change_Followup": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|You changed your mind? Sure...$h#$action Regression.StartChange \"joja diaper\"#$h" + "Diaper_Change_Followup": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|You changed your mind? Sure...$h#$action DIAPER_CHANGE \"joja diaper\"#$h" } } ] diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json b/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json index 33ad327..ce05142 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.#$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.", -"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.#$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", -"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.#$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!", -"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.#$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", + "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 little bit 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 slowly walks off.", + "Change_Diaper_Refuse": "It's ok, i get Aunty Marnie to change me!$4", + "Change_Diaper_Followup": "#$p dirty_change_no#Aunty Marnie said she is gona change me in a minute!|But no diapers! Only big girl underpants!$s#$b#%You change jas into training pants and set her down gently. She smiles at you.#$action CHANGE_DIAPER_OTHERS \"jas\" \"training pants\"#$h" + }, + }, + ] } \ 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 2b1cb77..2147f29 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json @@ -1,68 +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.#$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.", - "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.", + "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!", - "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.#$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.", - "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", - "Diaper_Change_Accept": "#Just a second... See it stretches! There! Right as rain!$l#$b#%Jodi changes you#$action Regression.StartChange \"baby print diaper\" \"sams pants\"#$h", - "Diaper_Change_Refuse": "Well, if you are like Vincent and want to stay in your filthy pants, suit yourself! Just don't leak on the couch, you hear?", - "Diaper_Change_Followup": "#$p dirty_change_yes#Again? Sorry i am bussy right now. I have to change Vincents bottom next!(This is an error, this should not be able to happen!)|I am glad you see reason! Hold this, yes this is baby powder, don't look at me like that!$3'#$b#%Jodi changes your#$action Regression.StartChange \"baby print diaper\" \"sams pants\"#$3" - } - } - ] + "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", + "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 into one of Vincents baby print diapers< and some old pants from sam>#$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 index beb30a6..49ab0ab 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Maru.json @@ -5,9 +5,9 @@ "Action":"EditData", "Target":"Characters/Dialogue/Maru", "Entries": { - "Diaper_Change_Accept": "%Maru changes you quick and professional#$action Regression.StartChange \"joja diaper\"#$h", + "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": "#$p dirty_change_yes#?(This is an error, this should not be able to happen!)|Glad to help$l#$b#%Maru changes you with professional efficiency#$action Regression.StartChange \"joja diaper\"#$3" + "Diaper_Change_Followup": "..." } } diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json b/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json index 823bcca..e9f14ab 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json @@ -150,9 +150,9 @@ "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": "#Hop on the changing table!$l#$b#%Penny changes your diaper and smiles at you#$action Regression.StartChange \"heart diaper\"#$h", + "Diaper_Change_Accept": "#Hop on the changing table!$l#$b#%Penny changes your diaper and smiles at you#$action DIAPER_CHANGE \"heart diaper\"#$h", "Diaper_Change_Refuse": "Do you want to play the big kid today? I can see it sagging from here!", - "Diaper_Change_Followup": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|Guess who gets their bottom changed?$h#$action Regression.StartChange \"heart diaper\"#$h" + "Diaper_Change_Followup": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|Guess who gets their bottom changed?$h#$action DIAPER_CHANGE \"heart diaper\"#$h" }, }, diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json index 2408af2..73f9fc8 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.", @@ -142,9 +142,9 @@ "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", - "Diaper_Change_Accept": "#Ah, hold still. Don't worry i got this!$l#$b#%Sam changes your diaper, making a lot of mistakes while doing so.#$action Regression.StartChange \"joja diaper\"#$h", + "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": "#$p dirty_change_yes#No?(This is an error, this should not be able to happen!)|Sure thing, lets see...$h#$b#%Sam changes your diaper, he just can't it get quite right.#$action Regression.StartChange \"joja diaper\"#$h" + "Diaper_Change_Followup": "#$p dirty_change_yes#No?(This is an error, this should not be able to happen!)|Sure thing, lets see...$h#$b#%Sam changes your diaper, he just can't it get quite right.#$action DIAPER_CHANGE \"baby print diaper\" \"sams old pants\"#$h" } }, @@ -167,7 +167,7 @@ "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_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", 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..a23471c 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.#$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", - "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#$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.", - "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?#$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", - "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.#$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", + "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#%Looking vincent waddle away, you feel much less certain about that than he is.", + "Change_Diaper_Followup": "(Something went wrong, try again)" + } + } ] } \ No newline at end of file diff --git a/Regression/Regression.csproj b/Regression/Regression.csproj index 9c5a364..605b1c6 100644 --- a/Regression/Regression.csproj +++ b/Regression/Regression.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -10,11 +10,15 @@ + + + PreserveNewest + PreserveNewest diff --git a/Regression/config.json b/Regression/config.json index 4955ac5..4b0453d 100644 --- a/Regression/config.json +++ b/Regression/config.json @@ -8,7 +8,7 @@ "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, // Defines if you will notice accidents on low control values. - "Debug": true, // Allowes to spawn items, change potty training and displays debug related messages. + "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). "BladderLossContinenceRate": 2, //2 is a 2% continence loss for MaxBladderCapacity accidents. diff --git a/Regression/en.json b/Regression/en.json index 48cac2f..329b8fd 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -219,6 +219,10 @@ "Diaper_Change_Dialog": [ "#$q dirty_change_yes/dirty_change_no Diaper_Change_Followup#Do you want to get changed like a toddler?#$r dirty_change_yes 1 Diaper_Change_Accept#Nod.#$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 $NPC_HIS_HER$ $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", @@ -310,6 +314,58 @@ "Your pants are poopy!", "You messed your pants!" ], + "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": "-20", + "dialog_key": "Change_Diaper_Accept_Upset" + }, + "lavender pullups": { + "friendship": "20", + "dialog_key": "Change_Diaper_Accept" + }, + "training pants": { + "friendship": "30", + "dialog_key": "Change_Diaper_Accept" + }, + "big kid undies": { + "friendship": "0", + "dialog_key": "Change_Diaper_Accept_Unprotected" + }, + "dinosaur undies": { + "friendship": "2", + "dialog_key": "Change_Diaper_Accept_Unprotected" + } + + } + }, "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 @@ -362,6 +418,12 @@ "ground_attempt": 0.5, "soiled": 0, "dirty": 0.05 + }, + "jas": { + "ground": 1.0, + "ground_attempt": 0.5, + "soiled": 0, + "dirty": 0, } }, "Villager_Reactions": { @@ -415,6 +477,11 @@ ] }, "kid": { + "general_fallback": [ + "Not now! 'M playing!", + "Playing?", + "... Yes?" + ], "soiled_verynice": [ "*Giggles* Uh oh!$1" ], @@ -452,11 +519,17 @@ ] }, "abigail": { + "general": [ + "You need a change?#$b#$query !DIAPER_USED#Aww...|$GETTING_CHANGED_DIALOG$" + ], + "general_fallback": [ + "%Maybe you should get to know Abigail better first!" + ], "soiled_verynice": [ - "Want a change? #$b#I could change you, if you want!$h$Diaper_Change_Dialog", + "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?", - "Let me help with that! Lay down for me.$h$Diaper_Change_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?" ], "soiled_nice": [ @@ -493,47 +566,41 @@ ] }, "maru": { + "general": [ + "Everything dry?#$b#$query !DIAPER_USED#Hmm... but come back if that changes.|$GETTING_CHANGED_DIALOG$" + ], + "general_fallback": [ + "%Maybe you should get to know Maru better first!" + ], "soiled_verynice": [ - "Again? Sure, you know the drill...$l$Diaper_Change_Dialog" + "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$Diaper_Change_Dialog" + "Lets be professional about this. Lie down on the bed for me please?$0$GETTING_CHANGED_DIALOG$" ], "soiled_mean": [ "Incontinence i guess?$4" ], "dirty": [ - "You will catch a cold, or worse. Let's get the cloth off!$1$Diaper_Change_Dialog" + "You will catch a cold, or worse. Let's get the cloth off!$1$GETTING_CHANGED_DIALOG$g" ] }, - "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.#$b#You need help?$Diaper_Change_Dialog", - "It can be hard for little to remember to go potty sometimes. It's okay.#$b#Need a change?$Diaper_Change_Dialog", - "Oh goodness!$1", - "Awww, you're so cute when you're embarrassed!$1#$b#Comeon, lets get you in some new Diapers!$Diaper_Change_Dialog" - ], - "soiled_nice": [ - "$FARMERNAME$, I think you might need to go change.", - "You poor thing! Did you just yourself?" + "sam": { + "general": [ + "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_mean": [ - "You might need to tap into those supplies I left you$4" + "general_fallback": [ + "%Maybe you should get to know Sam better first!" ], - "dirty": [ - "$p dirty_change_no# No leaks! $3| Aww, come here @! This things happen! We can make one of Vincents diapers fit! $1$Diaper_Change_Dialog" - ] - }, - "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#Do you want some help with that?$Diaper_Change_Dialog", + "#$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?$Diaper_Change_Dialog", + "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.", @@ -553,19 +620,25 @@ "#$p 102#You might want to take care of that...|Great, more potty issues to be witness to. Thanks.$5" ], "dirty": [ - "Can't let you get a cold, can i. Need help?$1$Diaper_Change_Dialog" - ], + "Oh man. Can't let you catch a cold, can i$9?#$b#Where are vincents diapers again?$1$GETTING_CHANGED_DIALOG$" + ] }, "penny": { + "general": [ + "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", + "%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" + "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.", @@ -603,7 +676,38 @@ "I have enough to clean up.$3" ] }, + "jodi": { + "general": [ + "You need a change?#$b#%Jodi checks your diaper#$b#$query !DIAPER_USED#Good for now.|$GETTING_CHANGED_DIALOG$" + ], + "general_fallback": [ + "%Maybe you should get to know Jodi better first!" + ], + "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": [ + "$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": [ + "%You wonder if Vincent might need a change. You quickly check his diaper.#$b#$query !DIAPER_USED \"vincent\"#He is wearing $NPC_PANTS_NAME$ and $NPC_INSPECT_UNDERWEAR_NAME$.|$CHANGE_OTHER_DIALOG$" + ], + "general_fallback": [ + "%Maybe you should get to know Vincent or Jodi better first!" + ], "soiled_verynice": [ "#$p 102#%*Giggles*|Mommy told me big kids are supposed to use the potty. #$b#I don't wanna be a big kid either!$1", "#$p 102#%*Giggles*|%Vincent watches you yourself and giggles.#$b#Good one!$1", @@ -636,6 +740,12 @@ ] }, "jas": { + "general": [ + "%You wonder if Jas might need a change. You quickly check her diaper.#$b#Wha? No, 'm a big girl now!$3#$b#$query !DIAPER_USED \"jas\"#She is wearing $NPC_PANTS_NAME$ and $NPC_INSPECT_UNDERWEAR_NAME$.|$CHANGE_OTHER_DIALOG$" + ], + "general_fallback": [ + "%Maybe you should get to know Jas or Marnie better first!" + ], "soiled_verynice": [ "#$p 102#%*Giggles*|Don't cry, it's okay for little s to have accidents sometimes.", "#$p 102#%*Giggles*|Oh no, did you have an accident? That's okay, you can try again next time.", @@ -666,11 +776,19 @@ }, "Change": [ - "You change into $PANTS_PREFIX$ clean $PANTS_NAME$ and $INSPECT_UNDERWEAR_NAME$." + "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." + "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." @@ -1647,7 +1765,7 @@ "absorbency": 75.0, "containment": 75.0, "spriteIndex": 0, - "price": 100, + "price": 120, "washable": false, "plural": false, "dryingTime": 300, @@ -1686,7 +1804,7 @@ "absorbency": 400.0, "containment": 600.0, "spriteIndex": 3, - "price": 35, + "price": 45, "washable": true, "plural": true, "dryingTime": 500, @@ -1712,7 +1830,7 @@ "absorbency": 850.0, "containment": 1400.0, "spriteIndex": 5, - "price": 80, + "price": 60, "washable": true, "plural": true, "dryingTime": 600, @@ -1725,7 +1843,7 @@ "absorbency": 1100.0, "containment": 1400.0, "spriteIndex": 6, - "price": 30, + "price": 15, "washable": false, "plural": false, "dryingTime": 0, @@ -1734,11 +1852,11 @@ }, "baby print diaper": { "name": "baby print diaper", - "description": "little soft and crinkly fresh-scented disposable baby print diaper. Its a bit small, but you can fit", + "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": 75, + "price": 20, "washable": false, "plural": false, "dryingTime": 0, @@ -1751,12 +1869,12 @@ "absorbency": 1400.0, "containment": 2600.0, "spriteIndex": 8, - "price": 260, + "price": 120, "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 + "durability": 8 }, "space diaper": { "name": "space diaper", @@ -1764,7 +1882,7 @@ "absorbency": 2700.0, "containment": 2800.0, "spriteIndex": 9, - "price": 100, + "price": 80, "washable": false, "plural": false, "dryingTime": 0, @@ -1777,7 +1895,7 @@ "absorbency": 2700.0, "containment": 2700.0, "spriteIndex": 10, - "price": 100, + "price": 80, "washable": false, "plural": false, "dryingTime": 0, @@ -1790,7 +1908,7 @@ "absorbency": 3400.0, "containment": 3500.0, "spriteIndex": 11, - "price": 140, + "price": 120, "washable": false, "plural": false, "dryingTime": 0, From 1f0a98a2bcc0f5183e34d38fe9be6584433a7418 Mon Sep 17 00:00:00 2001 From: Proximitron Date: Sat, 14 Dec 2024 05:41:14 +0100 Subject: [PATCH 6/9] fixes for sam texts --- .../Dialogue/NPCs/Sam.json | 112 +++++++++--------- Regression/en.json | 2 +- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json index 73f9fc8..c0ef549 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json @@ -152,62 +152,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#%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", - } + "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/en.json b/Regression/en.json index 329b8fd..c02bfc2 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -604,7 +604,7 @@ "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.'" + "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", From 7edd6e519546d127ddb9c8d9d955072c558ea46e Mon Sep 17 00:00:00 2001 From: Proximitron Date: Tue, 14 Jan 2025 20:39:53 +0100 Subject: [PATCH 7/9] Finalized testing, new release version (Release 3) --- Regression/PrimevalTitmouse/Animations.cs | 165 +- Regression/PrimevalTitmouse/Body.cs | 112 +- Regression/PrimevalTitmouse/Config.cs | 58 +- Regression/PrimevalTitmouse/Container.cs | 10 +- Regression/PrimevalTitmouse/Data.cs | 1 + .../PrimevalTitmouse/DialogueParserPatches.cs | 21 + Regression/PrimevalTitmouse/FarmerPatches.cs | 24 + Regression/PrimevalTitmouse/Mail.cs | 1 + Regression/PrimevalTitmouse/NpcBody.cs | 463 ++ Regression/PrimevalTitmouse/Regression.cs | 597 +-- Regression/PrimevalTitmouse/Strings.cs | 43 +- .../Dialogue/NPCs/Abigail.json | 4 +- .../Dialogue/NPCs/Jas.json | 46 +- .../Dialogue/NPCs/Jodi.json | 28 +- .../Dialogue/NPCs/Penny.json | 60 +- .../Dialogue/NPCs/Sam.json | 10 +- .../Dialogue/NPCs/Vincent.json | 42 +- Regression/config.json | 2 + Regression/en.json | 4069 +++++++++-------- 19 files changed, 3318 insertions(+), 2438 deletions(-) create mode 100644 Regression/PrimevalTitmouse/DialogueParserPatches.cs create mode 100644 Regression/PrimevalTitmouse/FarmerPatches.cs create mode 100644 Regression/PrimevalTitmouse/NpcBody.cs diff --git a/Regression/PrimevalTitmouse/Animations.cs b/Regression/PrimevalTitmouse/Animations.cs index 606f60c..b1b6d3a 100644 --- a/Regression/PrimevalTitmouse/Animations.cs +++ b/Regression/PrimevalTitmouse/Animations.cs @@ -94,7 +94,7 @@ public static void AnimateDrinking(bool waterSource = false) // ISSUE: method pointer //Start Drinking animation. While drinking pause time and don't allow movement. - player.FarmerSprite.animateOnce(StardewValley.FarmerSprite.drink, DRINK_ANIMATION_INTERVAL, DRINK_ANIMATION_FRAMES, new AnimatedSprite.endOfAnimationBehavior(EndDrinking)); + player.FarmerSprite.animateOnce(FarmerSprite.drink, DRINK_ANIMATION_INTERVAL, DRINK_ANIMATION_FRAMES, new AnimatedSprite.endOfAnimationBehavior(EndDrinking)); player.freezePause = PAUSE_TIME; player.canMove = false; @@ -103,13 +103,13 @@ public static void AnimateDrinking(bool waterSource = false) return; //Otherwise say something about it - Say(Animations.Data.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.Data.Bedding_Still_Wet, b); + Write(Data.Bedding_Still_Wet, b); } @@ -123,28 +123,28 @@ public static void AnimateMessingStart(Body b, bool voluntary, bool inUnderwear) if (!(b.underwear.removable || inUnderwear)) { - Animations.Say(Animations.Data.Cant_Remove, b); + Say(Data.Cant_Remove, b); return; } if (!inUnderwear) { if (b.InToilet(inUnderwear)) - Say(Animations.Data.Poop_Toilet, b); + Say(Data.Poop_Toilet, b); else - Say(Animations.Data.Poop_Voluntary, b); + Say(Data.Poop_Voluntary, b); } else if (voluntary) - Say(Animations.Data.Mess_Voluntary, b); + Say(Data.Mess_Voluntary, b); else - Say(Animations.Data.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 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)Animations.player).facingDirection.Value == 1 ? 0.0f : (float)-Game1.tileSize, (float)(Game1.tileSize * 2)), false, ((Character)Animations.player).facingDirection.Value == 1, (float)((Character)Animations.player).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, 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)); player.freezePause = poopAnimationTime; player.canMove = false; @@ -158,8 +158,8 @@ public static void AnimateMessingEnd(Character target) } public static void AnimateMessingMinor(Body b) { - Animations.Say(Animations.Data.Bowels_Leak, b); - ((Character)Animations.player).doEmote(12, false); + Say(Data.Bowels_Leak, b); + ((Character)player).doEmote(12, false); } public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) @@ -172,39 +172,39 @@ public static void AnimateWettingStart(Body b, bool voluntary, bool inUnderwear) if (!(b.underwear.removable || inUnderwear)) { - Animations.Say(Animations.Data.Cant_Remove, b); + Say(Data.Cant_Remove, b); return; } if (!inUnderwear) { if (b.InToilet(inUnderwear)) - Animations.Say(Animations.Data.Pee_Toilet, b); + Say(Data.Pee_Toilet, b); else - Animations.Say(Animations.Data.Pee_Voluntary, b); + Say(Data.Pee_Voluntary, b); - ((GameLocation)Animations.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)); + ((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.player.currentLocation.terrainFeatures.ContainsKey(((Character)Animations.player).Tile) && (terrainFeature = Animations.player.currentLocation.terrainFeatures[((Character)Animations.player).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.Data.Wet_Voluntary, b); + Say(Data.Wet_Voluntary, b); else - Animations.Say(Animations.Data.Wet_Accident, b); + Say(Data.Wet_Accident, b); // We skip the actual animations if nessesary - if (Body.IsFishing() || !Animations.player.canMove) return; + if (Body.IsFishing() || !player.canMove) return; player.jitterStrength = 0.5f; player.freezePause = peeAnimationTime; //milliseconds player.canMove = false; - ((Character)Animations.player).doEmote(28, false); + ((Character)player).doEmote(28, false); } public static void AnimateWettingMinor(Body b) { - Animations.Say(Animations.Data.Bladder_Leak, b); - ((Character)Animations.player).doEmote(28, false); + Say(Data.Bladder_Leak, b); + ((Character)player).doEmote(28, false); } @@ -215,29 +215,39 @@ public static void AnimateWettingEnd(Body b) { ((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.player.currentLocation.terrainFeatures.ContainsKey(((Character)Animations.player).Tile) && (terrainFeature = player.currentLocation.terrainFeatures[((Character)Animations.player).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.Data.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.Data.Messed_Bed), flag); + msg = msg + " " + Strings.ReplaceOptional(Strings.RandString(Data.Messed_Bed), flag); if (!Regression.config.Easymode) - msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Animations.Data.Washing_Bedding), flag, second, "&"); + msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Data.Washing_Bedding), flag, second, "&"); } else if (flag) { - msg = msg + " " + Strings.RandString(Animations.Data.Wet_Bed); + msg = msg + " " + Strings.RandString(Data.Wet_Bed); if (!Regression.config.Easymode) - msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Animations.Data.Spot_Washing_Bedding), flag, second, "&"); + msg = msg + " " + Strings.ReplaceAndOr(Strings.RandString(Data.Spot_Washing_Bedding), flag, second, "&"); + } + Write(msg, b); + } + private static string GetNumericTranslationMultiple(int amount) + { + switch (amount) + { + case 1: + return ""; + default: + return "multiple times "; } - Animations.Write(msg, b); } private static string GetNumericTranslationOnceTwice(int amount) { @@ -281,10 +291,10 @@ public static void AnimateNight(Body b) { bool first = b.numPottyPeeAtNight > 0; bool second = b.numPottyPooAtNight > 0; - if (!(first | second) || !b.IsAllowedResource(IncidentType.PEE) && !b.IsAllowedResource(IncidentType.POOP)) + if (!b.IsAllowedResource(IncidentType.PEE) && !b.IsAllowedResource(IncidentType.POOP)) return; - var list = Animations.Data.Night; + 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 = ""; @@ -319,14 +329,12 @@ public static void AnimateNight(Body b) accidentReport = FirstCharToUpper(accidentReport); toiletMsg += " " + accidentReport + "."; - - if (b.numAccidentPooAtNight > 0 || b.numAccidentPeeAtNight > 0) - toiletMsg += " " + FirstCharToUpper(Strings.RandString(list["Belittle_Accidents"])) + "."; } 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); } @@ -335,11 +343,11 @@ public static void AnimatePeeAttempt(Body b, bool inUnderwear) if (Body.IsFishing()) return; if (inUnderwear) - Say(Animations.Data.Wet_Attempt, b); + Say(Data.Wet_Attempt, b); else if (b.InToilet(inUnderwear)) - Say(Animations.Data.Pee_Toilet_Attempt, b); + Say(Data.Pee_Toilet_Attempt, b); else - Say(Animations.Data.Pee_Attempt, b); + Say(Data.Pee_Attempt, b); } public static void AnimatePoopAttempt(Body b, bool inUnderwear) @@ -347,50 +355,50 @@ public static void AnimatePoopAttempt(Body b, bool inUnderwear) if (Body.IsFishing()) return; if (inUnderwear) - Animations.Say(Animations.Data.Mess_Attempt, b); + Say(Data.Mess_Attempt, b); else if (b.InToilet(inUnderwear)) - Animations.Say(Animations.Data.Poop_Toilet_Attempt, b); + Say(Data.Poop_Toilet_Attempt, b); else - Animations.Say(Animations.Data.Poop_Attempt, b); + Say(Data.Poop_Attempt, b); } public static void AnimateStillSoiled(Body b) { - string baseString = Strings.RandString(Animations.Data.Still_Soiled); + string baseString = Strings.RandString(Data.Still_Soiled); baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); - Animations.Say(baseString, b); + Say(baseString, b); } public static void AnimateShouldChange(Body b) { - string baseString = Strings.RandString(Animations.Data.Should_Change); + string baseString = Strings.RandString(Data.Should_Change); baseString = baseString.Replace("$UNDERWEAR_LONGDESC$", Strings.DescribeUnderwear(b.underwear, b.underwear.displayName, true)); - Animations.Say(baseString, b); + Say(baseString, b); } public static void AnimateWashingUnderwear(Container c) { if (c.MarkedForDestroy()) { - Animations.Write(Strings.InsertVariables(Animations.Data.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.Data.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) { - Animations.Say(Animations.Data.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) { - Animations.Warn(curr); + Warn(curr); return true; } return false; @@ -427,7 +435,7 @@ public static void CheckContinence(Body b) } public static void CheckPottyFeeling(Body b) { - Warn(Strings.RandString(GetPottyFeeling(b, IncidentType.PEE)) + "^" + Strings.RandString(GetPottyFeeling(b, IncidentType.POOP))); + 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) @@ -443,15 +451,15 @@ public static string[] GetPottyFeeling(Body b, IncidentType type) } public static void CheckUnderwear(Body b) { - Say(Animations.Data.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.sprites; - 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); @@ -473,10 +481,10 @@ public static void DrawStateIcon(Body b, IncidentType type, int x, int y) int topOffset = LARGE_SPRITE_DIM - (int)Math.Ceiling(newFullness * LARGE_SPRITE_DIM); Microsoft.Xna.Framework.Color defaultColor = Microsoft.Xna.Framework.Color.White; - Texture2D peeOrPoopIcon = Animations.peepoopSprites; + Texture2D peeOrPoopIcon = peepoopSprites; if (peeOrPoopIcon == null) return; - Microsoft.Xna.Framework.Rectangle emptyIcon = Animations.StatusRectangle(b, type,false, LARGE_SPRITE_DIM); - Microsoft.Xna.Framework.Rectangle filledIcon = Animations.StatusRectangle(b, type, true, LARGE_SPRITE_DIM, topOffset); + 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); @@ -485,7 +493,7 @@ public static void DrawStateIcon(Body b, IncidentType type, int x, int y) ((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 = Animations.GetPottyFeeling(b, type)[0]; + 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); @@ -530,7 +538,7 @@ private static List NearbyVillager(Body b, bool mess, bool inUnderwear, boo public static List NearbyVillager(int radius) { - var list = Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, radius, (GameLocation)Game1.currentLocation); + var list = Utility.GetNpcsWithinDistance(((Character)player).Tile, radius, (GameLocation)Game1.currentLocation); var newList = new List(); foreach (var npcEntry in list) @@ -562,7 +570,7 @@ public static int FriendshipLossOnAccident(NPC npc, bool mess, bool inUnderwear, //Does this leave the possibility of friendship gain if we have enough hearts already? Maybe because they find the vulnerability endearing? float friendshipLoss = -1 + (heartLevelForNpc - 2) / 2; - var modifiers = Animations.Data.Villager_Friendship_Modifier; + var modifiers = Data.Villager_Friendship_Modifier; var modifierKey = modifierForIncident(npc, mess, inUnderwear, overflow, attempt); float finalModifier = 1.0f; @@ -619,11 +627,17 @@ public static string modifierForIncident(NPC npc, bool mess, bool inUnderwear, b return "soiled"; } } - public static string responseKeyAdditionForState(NPC npc) + public static string responseKeyAdditionForState(NPC npc, bool isDirty = false) { - if (!Regression.canGetGiveChangeNpc(npc)) + var body = new NpcBody(npc); + + if (!isDirty && body.canGetGiveChangeNpc) + { + return "_offer_change"; + } + else if (isDirty && body.canGiveDirtyChangeNpc) { - return "_fallback"; + return "_offer_change"; } return ""; @@ -636,7 +650,7 @@ public static string responseKeyAdditionForIncident(NPC npc, bool inUnderwear, i //Animals only have a "nice" response if (npcTypeList(npc).Contains("animal")) { - return "nice"; + return "_nice"; } else { @@ -644,11 +658,11 @@ public static string responseKeyAdditionForIncident(NPC npc, bool inUnderwear, i //If we have a really high relationship with the NPC, they're very nice about our accident if (heartLevelForNpc >= 8) { - return "verynice"; + return "_verynice"; } //Otherwise they'll be mean or nice depending on how much friendship we're losing - if (friendshipLoss < 0) return "nice"; - return "mean"; + if (friendshipLoss < 0) return "_nice"; + return "_mean"; } } return ""; @@ -661,6 +675,7 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over var nearby = NearbyVillager(b, mess, inUnderwear, overflow, attempt); foreach (var npc in nearby) { + if (npc.Age == 2 && !Regression.ChildrenAndDiapers) continue; someoneNoticed = true; //Make a list based on who saw us. @@ -678,20 +693,20 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over //If we're in debug mode, notify how the relationship was effected if (Regression.config.Debug && finalLossValue < 0) - Animations.Say(string.Format("{0} ({1}) changed friendship from {2} by {3}.", npc.Name, npc.Age, player.getFriendshipHeartLevelForNPC(npc.getName()), finalLossValue), (Body)null); + 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); + string responseKey = modifierKey + responseKeyAdditionForIncident(npc,inUnderwear, finalLossValue); 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)) + 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); @@ -706,7 +721,7 @@ public static bool HandleVillager(Body b, bool mess, bool inUnderwear, bool over Regression.QueueAction(() => { - if (b.underwear.used) + if (b.underwear.used || attempt || !inUnderwear) { npcStatement = Strings.InsertVariables(npcStatement, npc); npc.setNewDialogue(new Dialogue(npc, null, npcStatement), true, true); @@ -733,7 +748,7 @@ public static void Say(string msg, Body b = 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) @@ -821,7 +836,7 @@ public static void Warn(string msg, Body b = null, Container c = null) public static void Warn(string[] msgs, Body b = null, Container c = null) { - Animations.Warn(Strings.RandString(msgs), b, c); + Warn(Strings.RandString(msgs), b, c); } public static void Write(string msg, Body b = null, Container c = null,int delay = 0) @@ -829,14 +844,14 @@ public static void Write(string msg, Body b = null, Container c = null,int delay msg = Strings.InsertVariables(msg, b, c); Regression.QueueAction(() => { - DelayedAction.showDialogueAfterDelay(msg, 0); + DelayedAction.showDialogueAfterDelay(msg, 10); },delay); } public static void Write(string[] msgs, Body b = null, Container c = null, int delay = 0) { - Animations.Write(Strings.RandString(msgs), b, c, delay); + Write(Strings.RandString(msgs), b, c, delay); } } } diff --git a/Regression/PrimevalTitmouse/Body.cs b/Regression/PrimevalTitmouse/Body.cs index 0f65718..cb6c84e 100644 --- a/Regression/PrimevalTitmouse/Body.cs +++ b/Regression/PrimevalTitmouse/Body.cs @@ -24,18 +24,23 @@ public class Body //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 - 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 = 3000f; // I adjusted it from 3500 to 3000, because the farmer still eats half the farm every day + private static readonly float requiredCaloriesPerDay = 3500f; + 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 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.3f; // Also describes capacity as changes are linear + 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.5f; // lowered from 0.67f to 0.5f to make the numbers smaller (too much poop) and bowel capacity / 1.5f (1000f in total) - private static float maxBowelCapacity => (requiredCaloriesPerDay*foodToBowelConversion) / 1.5f / 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.3f; // Also describes capacity as changes are linear + 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 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 @@ -46,9 +51,9 @@ public class Body 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.5f, 0.65f, 0.8f, 1.0f }; + 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 = { minBowelContinence, 0.5f, 0.65f, 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 }; @@ -56,7 +61,7 @@ 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) @@ -343,6 +348,18 @@ public float GetCapacity(IncidentType type) 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) @@ -372,7 +389,7 @@ public void SetContinence(IncidentType type, float value) } public float GetHungerPercent() { - return (requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; + return (hungerMeterMax - hunger) / hungerMeterMax; } public float GetThirstPercent() @@ -415,7 +432,7 @@ public void AddResource(IncidentType type, float amount) } Accident(type, voluntary: false, inUnderwear: true); } - else if(!IsTryingToHoldIt(type) && oldFullnessPercent > 0.7f) + else if(!underwear.removable && oldFullnessPercent > 0.7f && !IsTryingToHoldIt(type)) { Accident(type, voluntary: true, inUnderwear: true); } @@ -442,14 +459,14 @@ public void AddResource(IncidentType type, 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) { - if(hunger < requiredCaloriesPerDay) + 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. @@ -462,7 +479,7 @@ public void AddFood(float amount, float conversionRatio = 1f) { AddResource(IncidentType.POOP, hunger * -0.5f * conversionRatio * foodToBowelConversion); hunger = 0f; - newPercent =(requiredCaloriesPerDay - hunger) / requiredCaloriesPerDay; + newPercent = GetHungerPercent(); } if (Regression.config.NoHungerAndThirst) @@ -472,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; } @@ -538,9 +556,7 @@ public void ChangeContinence(IncidentType type, float percent = 0.01f) SetContinence(type, previousContinence + percent); //Change of bladder capacity is no longer nessesary. Handled by getter. - - if (Regression.config.Debug) - Animations.Say(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)), (Body)null); + 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 if(type == IncidentType.POOP) @@ -582,7 +598,7 @@ public void ResetPants() if (myPants != null) { pants.displayName = myPants.displayName.ToLower(); - pants.description = myPants.description.ToLower(); + pants.description = myPants.displayName.ToLower(); } CleanPants(); } @@ -733,7 +749,7 @@ public void AddAccident(IncidentType type, float amount) case IncidentType.PEE: if (isSleeping) { - _ = this.bed.AddPee(this.pants.AddPee(this.underwear.AddPee(amount))); + _ = this.bed.AddPee(this.underwear.AddPee(amount)); } else { @@ -743,7 +759,7 @@ public void AddAccident(IncidentType type, float amount) case IncidentType.POOP: if (isSleeping) { - _ = this.bed.AddPoop(this.pants.AddPoop(this.underwear.AddPoop(amount))); + _ = this.bed.AddPoop(this.underwear.AddPoop(amount)); } else { @@ -760,7 +776,7 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear float attemptThreshold = GetAttemptThreshold(type); float capacity = GetCapacity(type); float fullness = GetFullness(type); - float continence = GetContinence(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 @@ -780,8 +796,10 @@ public void Accident(IncidentType type, bool voluntary = false, bool inUnderwear 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)continence; + //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) @@ -1012,6 +1030,10 @@ public float situationMultiplier(bool voluntary, bool inUnderwear) { multiplier = (voluntary ? (float)Regression.config.NighttimeGainMultiplier : (float)Regression.config.NighttimeLossMultiplier) / 100f; } + else if (voluntary && inUnderwear) + { + multiplier *= (Regression.config.InUnderwearOnPurposeMultiplier / 100f); + } return multiplier; } @@ -1040,13 +1062,13 @@ public void HandleMorning() Farmer player = Game1.player; if (bed.messiness > 0.0) { - dryingTime = 1000; - player.stamina -= 20f; + dryingTime = 800; + player.stamina -= 60f; } else if (bed.wetness > 0.0) { dryingTime = 600; - player.stamina -= 10f; + player.stamina -= 40f; } int timesUpAtNight = Math.Max(numPottyPeeAtNight, numPottyPooAtNight); @@ -1070,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); } @@ -1152,19 +1181,30 @@ 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.Data.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 diff --git a/Regression/PrimevalTitmouse/Config.cs b/Regression/PrimevalTitmouse/Config.cs index a5daf85..cde756c 100644 --- a/Regression/PrimevalTitmouse/Config.cs +++ b/Regression/PrimevalTitmouse/Config.cs @@ -2,35 +2,37 @@ { public class Config { - public bool AlwaysNoticeAccidents; - public bool Debug; - public bool Easymode; - public string Lang; - public bool PantsChangeRequiresHome; - public bool Wetting; - public bool Messing; - public int FriendshipPenaltyBladderMultiplier; - public int FriendshipPenaltyBowelMultiplier; - public bool NoHungerAndThirst; - public int NighttimeLossMultiplier; - public int NighttimeGainMultiplier; - public int BladderLossContinenceRate; - public int BowelLossContinenceRate; - public int BladderGainContinenceRate; - public int BowelGainContinenceRate; - public int MaxBladderCapacity; - public int MaxBowelCapacity; - public int StartBladderContinence; - public int StartBowelContinence; - public bool ReadSaveFiles; - public bool WriteSaveFiles; + 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; - public int KeyPee; - public int KeyPoop; - public int KeyGoInToilet; - public int KeyPeeInToilet; - public int KeyPoopInToilet; + 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 eb0679d..4ea4e7f 100644 --- a/Regression/PrimevalTitmouse/Container.cs +++ b/Regression/PrimevalTitmouse/Container.cs @@ -240,7 +240,7 @@ public bool drying { 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 @@ -267,10 +267,6 @@ public Container(Underwear underwear, string fallbackType) { modDataBaseKey = Underwear.modDataKey; modDataDictionary = underwear.modData; - if (name == "") - { - Regression.monitor.Log(modDataBaseKey + " had no name, and there is no fallback possible for underwear"); - } } public Container(Body body,string subtype, string fallbackType) { @@ -278,7 +274,7 @@ public Container(Body body,string subtype, string fallbackType) modDataDictionary = Game1.player.modData; if(name == "") { - Regression.monitor.Log($"{modDataBaseKey} for body had no name, so fallback {fallbackType} was used"); + // Regression.monitor.Log($"{modDataBaseKey} for body had no name, so fallback {fallbackType} was used"); ResetToDefault(fallbackType); } } @@ -288,7 +284,7 @@ public Container(NPC npc, string subtype, string fallbackType) modDataDictionary = npc.modData; if (name == "") { - Regression.monitor.Log($"{modDataBaseKey} for {npc.Name} had no name, so fallback {fallbackType} was used"); + //Regression.monitor.Log($"{modDataBaseKey} for {npc.Name} had no name, so fallback {fallbackType} was used"); ResetToDefault(fallbackType); } } diff --git a/Regression/PrimevalTitmouse/Data.cs b/Regression/PrimevalTitmouse/Data.cs index fe1e33a..d5f6463 100644 --- a/Regression/PrimevalTitmouse/Data.cs +++ b/Regression/PrimevalTitmouse/Data.cs @@ -71,6 +71,7 @@ public class Data 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/Mail.cs b/Regression/PrimevalTitmouse/Mail.cs index 093345b..5406195 100644 --- a/Regression/PrimevalTitmouse/Mail.cs +++ b/Regression/PrimevalTitmouse/Mail.cs @@ -28,6 +28,7 @@ public static void CheckMail() // 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) { 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 e7d1258..46788ec 100644 --- a/Regression/PrimevalTitmouse/Regression.cs +++ b/Regression/PrimevalTitmouse/Regression.cs @@ -21,6 +21,7 @@ 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; @@ -31,18 +32,15 @@ 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; @@ -72,6 +70,8 @@ public override void Entry(IModHelper h) 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); @@ -102,46 +102,97 @@ public override void Entry(IModHelper h) 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; + } + 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; + } - private void OnWarped(object sender, WarpedEventArgs e) + 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) { - // Some character have random changes after warped - foreach(var npc in e.NewLocation.characters) + if (args.Length < 2) { - var name = npc.Name.ToLower(); - if(name == "vincent") - { - if (Regression.rnd.Next(2) > 0) npcChange(npc); - var undies = npcUnderwear(npc); - var result = Regression.rnd.Next(7); - // Vincent is oft messy or wet. Sometimes both - if (result <= 2) undies.AddPoop((float)Math.Max(400, 900)); - if (result > 0 && result <= 5) undies.AddPee((float)Math.Max(300, 700)); - } - else if(name == "jas") - { - if (Regression.rnd.Next(2) > 0) npcChange(npc); - var undies = npcUnderwear(npc); - var result = Regression.rnd.Next(7); - // Jas is less often messy, nearly as often wet - if (result <= 2) undies.AddPoop((float)Math.Max(200, 700)); - if (result > 0 && result <= 5) undies.AddPee((float)Math.Max(300, 700)); - } - else if (name == "jas") - { - if (Regression.rnd.Next(2) > 0) npcChange(npc); - var undies = npcUnderwear(npc); - var result = Regression.rnd.Next(7); - // Jas is less often messy, nearly as often wet - if (result <= 2) undies.AddPoop((float)Math.Max(200, 700)); - if (result > 0 && result <= 5) undies.AddPee((float)Math.Max(300, 700)); - } + Monitor.Log("Usage: dialog ", LogLevel.Error); + return; } + + string npcName = args[0]; + string message = string.Join(" ", args, 1, args.Length - 1); + + TriggerDebugDialog(npcName, message); + } + /// + /// Handler for the "dialog" console command. + /// Usage: trigger_dialog + /// + + /// + /// 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) + { + // 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); + } + else + { + Monitor.Log($"NPC '{npcName}' not found!", LogLevel.Warn); + } + } + + private void OnWarped(object sender, WarpedEventArgs e) + { + return; } public bool DIAPER_USED(string[] query, GameStateQueryContext context) { @@ -159,10 +210,10 @@ public bool DIAPER_USED(string[] query, GameStateQueryContext context) default: break; } - var npc = NpcByName(targetNpcName); + var npc = NpcBody.ByName(targetNpcName,20); if (npc == null) return false; - underwear = npcUnderwear(npc); + 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) @@ -175,6 +226,38 @@ public bool DIAPER_USED(string[] query, GameStateQueryContext context) 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) + { + 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) + } + } private void GiveUnderwear() { @@ -235,6 +318,7 @@ private void ReceiveAfterDayStarted(object sender, DayStartedEventArgs e) private void HandleMorning(object Sender, DayStartedEventArgs e) { body.HandleMorning(); + Mail.CheckMail(); } public static Dictionary> replaceItems(IList items) @@ -261,6 +345,10 @@ public static void restoreItems(IList items, Dictionary 3 ? args[3] : null); + 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,oldUnderwear.container); + 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 @@ -606,10 +682,10 @@ public bool AddNpcMessage(string[] args, TriggerActionContext context, out strin } var target = args[1]; target = target.ToLower(); - var targetNpc = NpcByName(target); + var targetNpc = NpcBody.ByName(target, -1); if (targetNpc == null) { - error = $"Parameter 1, '{target}' not found in local npc list in 20 range"; + error = $"Parameter 1, '{target}' not found in global npc list"; return false; } if (args.Length < 3) @@ -621,10 +697,10 @@ public bool AddNpcMessage(string[] args, TriggerActionContext context, out strin if(args.Length > 3) { eventToken = args[3]; - if (targetNpc.CurrentDialogue.Count > 0) RemoveDialogueFromNPC(targetNpc, eventToken); + if (targetNpc.CurrentDialogue.Count > 0) targetNpc.RemoveDialogue(eventToken); } var msg = args[2].Replace("___", "#").Replace("$_", "$"); - targetNpc.setNewDialogue(new Dialogue(targetNpc, eventToken, msg), true, false); + targetNpc.npc.setNewDialogue(new Dialogue(targetNpc.npc, eventToken, msg), true, false); } catch (Exception e) { @@ -646,35 +722,24 @@ private void ReceiveUpdateTick(object sender, OneSecondUpdateTickingEventArgs e) //If time is moving, update our body state (Hunger, thirst, etc.) if (ShouldTimePass()) { - 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. - { - tickCD2 += 1; //This should trigger multiple times during the eating animation. - } - if (tickCD2 >= 2) //Setting this to 2 should be able to balance preventing double triggers and ensuring no loss in intentional triggers. - { - tickCD1 = 0; - tickCD2 = 0; - } + //body.HandleTime(timeInTick); to handle this cleaner, we move this to the time-changing tick // The following block makes npc (usually) not talk to you if you wear wet or messy pants... short of the special texts - - var newList = new List(); var isFilthy = body.pants.used; - var list = Utility.GetNpcsWithinDistance(((Character)Animations.player).Tile, 10, (GameLocation)Game1.currentLocation); - foreach (var npc in list) + foreach (var npc in NpcBody.ByRange(10)) { - if (npc.CurrentDialogue.Count > 0) RemoveDialogueFromNPC(npc, dirtyEventToken); - if(npc.CurrentDialogue.Count > 0) RemoveDialogueFromNPC(npc, generalEventToken); - + if (npc.CurrentDialogue.Count > 0) npc.RemoveDialogue(dirtyEventToken); + if(npc.CurrentDialogue.Count > 0) npc.RemoveDialogue(generalEventToken); + + if (npc.Age == 2 && !ChildrenAndDiapers) continue; if (isFilthy) { var mod = "dirty"; - var responseKey = mod + Animations.responseKeyAdditionForState(npc); + var responseKey = mod + Animations.responseKeyAdditionForState(npc.npc, true); - var randNpcString = Strings.RandString(GetVillagerReactions(npc,responseKey).ToArray()); + 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); @@ -682,182 +747,31 @@ private void ReceiveUpdateTick(object sender, OneSecondUpdateTickingEventArgs e) { npcStatement = Strings.ReplaceOptional(npcStatement, body.HasWetOrMessyDebuff()); } - npcStatement = Strings.InsertVariables(npcStatement, npc); - npc.setNewDialogue(new Dialogue(npc, dirtyEventToken, npcStatement), true, true); + npcStatement = Strings.InsertVariables(npcStatement, npc.npc); + npc.npc.setNewDialogue(new Dialogue(npc.npc, dirtyEventToken, npcStatement), true, true); } else if (npc.CurrentDialogue.Count <= 0) { var mod = "general"; - var responseKey = mod + Animations.responseKeyAdditionForState(npc); + var responseKey = mod + Animations.responseKeyAdditionForState(npc.npc, false); - var randNpcString = Strings.RandString(GetVillagerReactions(npc, responseKey).ToArray()); + 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); + npcStatement = Strings.InsertVariables(npcStatement, npc.npc); - npc.setNewDialogue(new Dialogue(npc, dirtyEventToken, npcStatement), true, true); + 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; } } - private List GetVillagerReactions(NPC npc, string responseKey) - { - 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); - } - } - return stringList3; - } - public static string npcDefaultUnderwear(NPC npc) { - switch (npc.Name.ToLower()) - { - case "vincent": - return "baby print diaper"; - case "jas": - return "lavender pullups"; - default: - return npc.Gender == Gender.Male ? "big kid undies" : "polka dot panties"; - } - } - public static Container npcUnderwear(NPC npc) - { - return new Container(npc, "underwear", npcDefaultUnderwear(npc)); - } - public static string npcDefaultPantsName(NPC npc) - { - switch (npc.Name.ToLower()) - { - case "vincent": - return "toddler pants"; - case "jas": - return "purple toddler skirts"; - default: - return npc.Gender == Gender.Male ? "pants" : "skirt"; - } - } - public static Container npcPants(NPC npc) - { - var staticType = "blue jeans"; - var defaultName = npcDefaultPantsName(npc); - var pants = new Container(npc, "pants", staticType); - if(pants.displayName == staticType && defaultName != "" && defaultName != pants.displayName) - { - pants.displayName = defaultName; - pants.description = defaultName; - } - return pants; - } - // a very simplified accident mechanic that assumes that the npc has an accident in a way that the diaper can be anywhere from full to empty - public static void npcAccident(NPC npc, IncidentType type) - { - - var underwear = npcUnderwear(npc); - var accidentSize = (float)Regression.rnd.Next((int)(underwear.GetCapacity(type) * 0.1f), (int)underwear.GetCapacity(type)); - if (type == IncidentType.PEE) - { - npc.movementPause = 3000; - npc.doEmote(28, false); - underwear.AddPee(accidentSize); - Game1.playSound("wateringCan"); - } - else - { - npc.movementPause = 3000; - npc.doEmote(12, false); - underwear.AddPoop(accidentSize); - Animations.AnimateMessingEnd(npc); - } - - - - } - public static void npcChange(NPC npc, string underwearName = null, string pantsName = null) - { - var underwear = npcUnderwear(npc); - if (underwearName != null) - { - underwear.ResetToDefault(underwearName); - } - else - { - underwear.ResetToDefault(npcDefaultUnderwear(npc)); - } - - var pants = npcPants(npc); - pants.ResetToDefault(pants,0,0); - } - // This refers to the "general" interaction that can contain dialog to getting changed or doing changes, depending on the character interacted with. It could also be both. - public static bool canGetGiveChangeNpc(NPC npc) - { - int heartLevelForNpc = Game1.player.getFriendshipHeartLevelForNPC(npc.Name); - switch (npc.Name.ToLower()) { - case "vincent": // can get changed - return heartLevelForNpc >= 6 && Game1.player.getFriendshipHeartLevelForNPC("Jodi") >= 4; - case "jas": // can get changed - return 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; - case "penny": - return heartLevelForNpc > 6; - default: - return false; - } - } - - private void RemoveDialogueFromNPC(NPC npc, 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()); - } - } //Determine if we need to handle time passing (not the same as Game time passing) private static bool ShouldTimePass() @@ -1022,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) + { + //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)) { - Underwear underwear = new Underwear(type, 1); - currentShopMenu.forSale.Add(underwear); - currentShopMenu.itemPriceAndStock.Add(underwear, new ItemStockInformation(underwear.container.price, StardewValley.Menus.ShopMenu.infiniteStock)); + 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() { @@ -1140,7 +1079,7 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) /////This is the highest priority (apparently?) if (who.CurrentTool != null && who.CurrentTool is WateringCan && e.IsDown(SButton.LeftShift)) { - this.body.DrinkWateringCan(); + body.DrinkWateringCan(); return; } @@ -1159,6 +1098,10 @@ private void ReceiveMouseChanged(object sender, ButtonPressedEventArgs e) 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(); @@ -1191,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) @@ -1247,6 +1211,13 @@ private void OnGameLaunched(object sender, GameLaunchedEventArgs e) 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, @@ -1279,6 +1250,14 @@ private void OnGameLaunched(object sender, GameLaunchedEventArgs e) 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", @@ -1373,6 +1352,14 @@ private void OnGameLaunched(object sender, GameLaunchedEventArgs e) 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", @@ -1510,23 +1497,77 @@ public void DrawStatusBars() 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; + + 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 (Game1.timeOfDay < 630) + if (newTime < 630) return; //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(this.body); + Animations.AnimateStillSoiled(body); if (rnd.NextDouble() < 0.0555555559694767 && (body.NeedsChangies(IncidentType.PEE) || body.NeedsChangies(IncidentType.POOP))) - Animations.AnimateShouldChange(this.body); + Animations.AnimateShouldChange(body); if (Game1.player.dialogueQuestionsAnswered.Contains("change_other_yes")) Game1.player.dialogueQuestionsAnswered.Remove("change_other_yes"); diff --git a/Regression/PrimevalTitmouse/Strings.cs b/Regression/PrimevalTitmouse/Strings.cs index 11d6511..d3926f0 100644 --- a/Regression/PrimevalTitmouse/Strings.cs +++ b/Regression/PrimevalTitmouse/Strings.cs @@ -72,16 +72,18 @@ public static string InsertVariables(string msg, Body b, Container c = null) if (c != null) { var gettingChangedDialog = Strings.RandString(Animations.Data.Diaper_Change_Dialog); - gettingChangedDialog = Strings.ReplaceAndOr(gettingChangedDialog, b.pants.wetness > 0, b.pants.messiness > 0); + 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)); } @@ -117,7 +119,7 @@ public static string InsertVariables(string msg, NPC b, Container c = null) { string str = msg; if (b != null && c == null) - c = Regression.npcUnderwear(b); + c = new NpcBody(b).underwear; if (c != null) { var changeOtherDialog = Strings.RandString(Animations.Data.Change_Other_Dialog); @@ -125,21 +127,25 @@ public static string InsertVariables(string msg, NPC b, Container c = null) 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, "#"); } if (b != null) { - var pants = Regression.npcPants(b); + 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")); } - 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; } @@ -173,7 +179,26 @@ 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; + // Escape the triggerKey to handle any special regex characters + string escapedKey = Regex.Escape(key); + + 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"); diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json b/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json index 0e140b3..1781f58 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Abigail.json @@ -7,9 +7,9 @@ "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\"#$h", + "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": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|You changed your mind? Sure...$h#$action DIAPER_CHANGE \"joja diaper\"#$h" + "Diaper_Change_Followup": "..." } } ] diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json b/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json index ce05142..701f041 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Jas.json @@ -15,8 +15,8 @@ //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_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.", @@ -26,60 +26,60 @@ "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_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_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", + "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_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.#$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_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#|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_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!", - "fall_26_2": "I'm going to do the whole maze tomorrow and I'm going going to be scared once!", + "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_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...!$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_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#|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_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_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 little bit 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 slowly walks off.", - "Change_Diaper_Refuse": "It's ok, i get Aunty Marnie to change me!$4", - "Change_Diaper_Followup": "#$p dirty_change_no#Aunty Marnie said she is gona change me in a minute!|But no diapers! Only big girl underpants!$s#$b#%You change jas into training pants and set her down gently. She smiles at you.#$action CHANGE_DIAPER_OTHERS \"jas\" \"training pants\"#$h" + "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": "..." }, }, ] diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json index 2147f29..a232732 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Jodi.json @@ -10,11 +10,11 @@ "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_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", @@ -26,36 +26,36 @@ "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_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.#$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_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": "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_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_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. You know that, right?^You're a good girl. You know that, right?", + "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.#$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", - "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 into one of Vincents baby print diapers< and some old pants from sam>#$action DIAPER_CHANGE \"baby print diaper\" \"sams old pants\"#$h", + "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": "..." } diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json b/Regression/Regression Dialogue/Dialogue/NPCs/Penny.json index e9f14ab..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,19 +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": "#Hop on the changing table!$l#$b#%Penny changes your diaper and smiles at you#$action DIAPER_CHANGE \"heart diaper\"#$h", + "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": "#$p dirty_change_yes#Not now sweety!(This is an error, this should not be able to happen!)|Guess who gets their bottom changed?$h#$action DIAPER_CHANGE \"heart diaper\"#$h" + "Diaper_Change_Followup": "..." }, }, diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json index c0ef549..96bcb37 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Sam.json @@ -142,9 +142,15 @@ "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", - "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", + "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": "#$p dirty_change_yes#No?(This is an error, this should not be able to happen!)|Sure thing, lets see...$h#$b#%Sam changes your diaper, he just can't it get quite right.#$action DIAPER_CHANGE \"baby print diaper\" \"sams old pants\"#$h" + "Diaper_Change_Followup": "..." } }, diff --git a/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json b/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json index a23471c..7839756 100644 --- a/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json +++ b/Regression/Regression Dialogue/Dialogue/NPCs/Vincent.json @@ -15,57 +15,57 @@ "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_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.", + "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.", + "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!#$e#She blamed it on me and Ms. Penny believed her.$2#$e#I was pretty messy though.$3", + "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", "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_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, his free hand resting on his diaper, a faint blush on his cheeks, and a little grin behind his thumb.#$e#Ahhhh.", + "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.", "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_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.", - "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_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", "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_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.#$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_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!#$e#%Vincent squats down shamelessly, grunting softly while you watch his pants droop.#$e#All done!$1", + "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?#$e#She says I gotta try and use the potty more, but if I do she won't change me anymore.$2", + "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#%Looking vincent waddle away, you feel much less certain about that than he is.", - "Change_Diaper_Followup": "(Something went wrong, try again)" + "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": "..." } } ] diff --git a/Regression/config.json b/Regression/config.json index 4b0453d..62adbc8 100644 --- a/Regression/config.json +++ b/Regression/config.json @@ -5,12 +5,14 @@ "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, // 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. diff --git a/Regression/en.json b/Regression/en.json index c02bfc2..7907690 100644 --- a/Regression/en.json +++ b/Regression/en.json @@ -1,1919 +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_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 changed like a toddler?#$r dirty_change_yes 1 Diaper_Change_Accept#Nod.#$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 $NPC_HIS_HER$ $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 slept through the whole night", - "You didn't wake up once this night", - "You wake up in the morning", - "You didn't feel the need to go tonight", - "You slept like a baby" - ], - "Accident_At_Night": [ - "you yourself $ACCIDENT_TIMES_TOTAL like a toddler", - "you yourself $ACCIDENT_ONCE_TWICE_TOTAL like the little bed you are" - ], - "Belittle_Accidents": [ - "Looks like someone really does need to be in their diapers at night", - "Someone should wear protection at night" - ], - "Underwear_Stuck": [ - "but you couldn't get your $UNDERWEAR_NAME$ off in time" - ] - }, + "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$" + ] + }, - "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_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": "-20", - "dialog_key": "Change_Diaper_Accept_Upset" - }, - "lavender pullups": { - "friendship": "20", - "dialog_key": "Change_Diaper_Accept" - }, - "training pants": { - "friendship": "30", - "dialog_key": "Change_Diaper_Accept" - }, - "big kid undies": { - "friendship": "0", - "dialog_key": "Change_Diaper_Accept_Unprotected" - }, - "dinosaur undies": { - "friendship": "2", - "dialog_key": "Change_Diaper_Accept_Unprotected" - } + "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": [ - } - }, - "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" - ] - }, - "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" - ] - }, - "kid": { - "general_fallback": [ - "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" - ] - }, - "animal": { - "soiled_nice": [ - "...", - "???" - ], - "ground": [ - "<...&!!!>" - ], - "ground_attempt": [ - "<...&???>" - ] - }, - "abigail": { - "general": [ - "You need a change?#$b#$query !DIAPER_USED#Aww...|$GETTING_CHANGED_DIALOG$" - ], - "general_fallback": [ - "%Maybe you should get to know Abigail better first!" - ], - "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?", - "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?" - ], - "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!", - "$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": [ - "Everything dry?#$b#$query !DIAPER_USED#Hmm... but come back if that changes.|$GETTING_CHANGED_DIALOG$" - ], - "general_fallback": [ - "%Maybe you should get to know Maru better first!" - ], - "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": [ - "You will catch a cold, or worse. Let's get the cloth off!$1$GETTING_CHANGED_DIALOG$g" - ] - }, - "sam": { - "general": [ - "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$" - ], - "general_fallback": [ - "%Maybe you should get to know Sam better first!" - ], - "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": [ - "Oh man. Can't let you catch a cold, can i$9?#$b#Where are vincents diapers again?$1$GETTING_CHANGED_DIALOG$" - ] - }, - "penny": { - "general": [ - "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" - ] - }, - "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" - ] - }, - "jodi": { - "general": [ - "You need a change?#$b#%Jodi checks your diaper#$b#$query !DIAPER_USED#Good for now.|$GETTING_CHANGED_DIALOG$" - ], - "general_fallback": [ - "%Maybe you should get to know Jodi better first!" - ], - "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": [ - "$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": [ - "%You wonder if Vincent might need a change. You quickly check his diaper.#$b#$query !DIAPER_USED \"vincent\"#He is wearing $NPC_PANTS_NAME$ and $NPC_INSPECT_UNDERWEAR_NAME$.|$CHANGE_OTHER_DIALOG$" - ], - "general_fallback": [ - "%Maybe you should get to know Vincent or Jodi better first!" - ], - "soiled_verynice": [ - "#$p 102#%*Giggles*|Mommy told me big kids are supposed to use the potty. #$b#I don't wanna be a big kid either!$1", - "#$p 102#%*Giggles*|%Vincent watches you yourself and giggles.#$b#Good one!$1", - "#$p 102#%*Giggles*|%You notice Vincent watching as you yourself.#$b#All better?", - "#$p 102#%*Giggles*|%Vincent watches the whole scene curiously and giggles when you look over. #$b# You !$1", - "#$p 102#%*Giggles*|If you want I could ask my Mommy to change you.#$b#No?#$b#That's okay, I like being too!$1", - "#$p 102#%*Giggles*|$FARMERNAME$'s and I'm still dry!$1#$b#...#$b#Wait...$2" - ], - "soiled_nice": [ - "#$p 102#%*Giggles*|Don't cry, Mommy says it's okay to have accidents sometimes.", - "#$p 102#%*Giggles*|Don't worry $FARMERNAME$, I still do that too!", - "#$p 102#%*Giggles*|Feel all better?", - "#$p 102#%*Giggles*|It smells like you need a diaper change!", - "#$p 102#%*Giggles*|I kney it! It does happen to bigs too!" - ], - "soiled_mean": [ - "#$p 102#%Ewww$3|%Vincent saw what happened and snickers at you.", - "#$p 102#%Ewww$3|Was that an accident?", - "#$p 102#%Ewww$3|Ha! Gross!$1", - "#$p 102#%Ewww$3|$FARMERNAME$ just !$1", - "#$p 102#%Ewww$3|Hah! I just watched you yourself!$1" - ], - "ground": [ - "#$p 102#%Ewww!$3|Ewww!$3", - "#$p 102#%Ewww!$3|Ewww! Don't there!$3", - "#$p 102#%Ewww!$3|Hey everyone! $FARMERNAME$ just on the ground!$1" - ], - "ground_attempt": [ - "#$p 102#%...$2|Eww! Why are you trying to on on the ground?$3" - ] - }, - "jas": { - "general": [ - "%You wonder if Jas might need a change. You quickly check her diaper.#$b#Wha? No, 'm a big girl now!$3#$b#$query !DIAPER_USED \"jas\"#She is wearing $NPC_PANTS_NAME$ and $NPC_INSPECT_UNDERWEAR_NAME$.|$CHANGE_OTHER_DIALOG$" - ], - "general_fallback": [ - "%Maybe you should get to know Jas or Marnie better first!" - ], - "soiled_verynice": [ - "#$p 102#%*Giggles*|Don't cry, it's okay for little s to have accidents sometimes.", - "#$p 102#%*Giggles*|Oh no, did you have an accident? That's okay, you can try again next time.", - "#$p 102#%*Giggles*|It's okay, I won't tell anyone you had an accident $FARMERNAME$", - "#$p 102#%*Giggles*|It's okay $FARMERNAME$, I still have accidents too.$1", - "#$p 102#%*Giggles*|I can see you waddling!$4", - "#$p 102#%*Giggles*|Did you have an accident? It's okay, once you're all clean you'll feel all better." - ], - "soiled_nice": [ - "#$p 102#%...$2|*Giggles* Uh oh!$1", - "#$p 102#%...$2|You're supposed to do that on the potty you know.$4", - "#$p 102#%...$2|Do you need me to get Aunt Marnie? She always helps me when I have an accident.$3" - ], - "soiled_mean": [ - "#$p 102#%Ewww!$3|Oh... gross...$3", - "#$p 102#%Ewww!$3|Ewww$3", - "#$p 102#%Ewww!$3|...$2" - ], - "ground": [ - "Ewww!$3", - "#$p 102#%Ewww!$3|Ewww! Don't there!$3", - "#$p 102#%Ewww!$3|...$2" - ], - "ground_attempt": [ - "#$p 102#%...$2|Eww! Why are you trying to on on the ground?$3" - ] - } - }, + ], + "fail": [ + "Hu?", + "Oh.", + "...", + "Wha?" + ] + }, + "post": { + "success": [ - "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. - // - //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 //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": 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": 40, - "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": 25, - "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": 1100.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": 20, - "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": 120, - "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": 8 - }, - "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": 80, - "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": 80, - "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": 120, - "washable": false, - "plural": false, - "dryingTime": 0, - "removable": false, - "durability": 0 - } - } + ], + "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 + } + } } From 0d57d71211e820b7399dad2afa254443428e9fdb Mon Sep 17 00:00:00 2001 From: Floximo Date: Tue, 14 Jan 2025 21:40:12 +0100 Subject: [PATCH 8/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dbbddfa..476aae5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Follow instructions provided by the individual prerequisite mods and programs. - [SMAPI](https://smapi.io/) (version 4.1.8) - [Content Patcher](https://www.nexusmods.com/stardewvalley/mods/1915?tab=files) (version 2.4.4) Highly recommended: (Allowes ingame configuration of the mod) -- [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098?tab=files] +- [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098?tab=files) ### 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. From d99ae5a1fa017958a415fa2acf6c668a03458901 Mon Sep 17 00:00:00 2001 From: Floximo Date: Tue, 14 Jan 2025 21:40:36 +0100 Subject: [PATCH 9/9] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 476aae5..dda15f4 100644 --- a/README.md +++ b/README.md @@ -30,8 +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) -Highly recommended: (Allowes ingame configuration of the mod) -- [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098?tab=files) +- [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.