Merge pull request #88 from khanshoaib3/Issue79

TextBox QOL update
master
Mohammad Shoaib 2023-02-22 18:11:39 +05:30 committed by GitHub
commit d12ecf0fae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 298 additions and 1102 deletions

View File

@ -48,7 +48,7 @@ namespace stardew_access
harmony.Patch( harmony.Patch(
original: AccessTools.Method(typeof(CharacterCustomization), nameof(CharacterCustomization.draw), new Type[] { typeof(SpriteBatch) }), original: AccessTools.Method(typeof(CharacterCustomization), nameof(CharacterCustomization.draw), new Type[] { typeof(SpriteBatch) }),
postfix: new HarmonyMethod(typeof(TitleMenuPatches), nameof(CharacterCustomizationPatches.CharacterCustomizationMenuPatch)) postfix: new HarmonyMethod(typeof(CharacterCustomizationMenuPatch), nameof(CharacterCustomizationMenuPatch.DrawPatch))
); );
harmony.Patch( harmony.Patch(
@ -225,7 +225,7 @@ namespace stardew_access
#region On Menu CLose Patch #region On Menu CLose Patch
harmony.Patch( harmony.Patch(
original: AccessTools.Method(typeof(IClickableMenu), nameof(IClickableMenu.exitThisMenu)), original: AccessTools.Method(typeof(IClickableMenu), nameof(IClickableMenu.exitThisMenu)),
postfix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.IClickableMenuOnExitPatch)) postfix: new HarmonyMethod(typeof(IClickableMenuPatch), nameof(IClickableMenuPatch.ExitThisMenuPatch))
); );
harmony.Patch( harmony.Patch(
original: AccessTools.Method(typeof(Game1), nameof(Game1.exitActiveMenu)), original: AccessTools.Method(typeof(Game1), nameof(Game1.exitActiveMenu)),
@ -285,6 +285,11 @@ namespace stardew_access
original: AccessTools.Method(typeof(InstanceGame), nameof(InstanceGame.Exit)), original: AccessTools.Method(typeof(InstanceGame), nameof(InstanceGame.Exit)),
prefix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.ExitEventPatch)) prefix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.ExitEventPatch))
); );
harmony.Patch(
original: AccessTools.Method(typeof(TextBox), nameof(TextBox.Draw)),
prefix: new HarmonyMethod(typeof(TextBoxPatch), nameof(TextBoxPatch.DrawPatch))
);
} }
} }
} }

View File

@ -13,7 +13,8 @@ namespace stardew_access
public class MainClass : Mod public class MainClass : Mod
{ {
#region Global Vars & Properties #region Global Vars & Properties
#pragma warning disable CS8603
#pragma warning disable CS8603
private static int prevDate = -99; private static int prevDate = -99;
private static ModConfig? config; private static ModConfig? config;
private Harmony? harmony; private Harmony? harmony;
@ -99,7 +100,6 @@ namespace stardew_access
return warnings; return warnings;
} }
} }
#pragma warning restore CS8603
#endregion #endregion
/********* /*********
@ -210,54 +210,32 @@ namespace stardew_access
return; return;
#region Simulate left and right clicks #region Simulate left and right clicks
if (Game1.activeClickableMenu != null) if (Game1.activeClickableMenu != null && !TextBoxPatch.isAnyTextBoxActive)
{ {
bool isCustomizingCharacter = Game1.activeClickableMenu is CharacterCustomization || (TitleMenu.subMenu != null && TitleMenu.subMenu is CharacterCustomization); bool isCustomizingCharacter = Game1.activeClickableMenu is CharacterCustomization || (TitleMenu.subMenu != null && TitleMenu.subMenu is CharacterCustomization);
#region Mouse Click Simulation #region Mouse Click Simulation
// Main Keybinds if (Config.LeftClickMainKey.JustPressed() || Config.LeftClickAlternateKey.JustPressed())
if (Config.LeftClickMainKey.JustPressed())
{ {
Game1.activeClickableMenu.receiveLeftClick(Game1.getMouseX(true), Game1.getMouseY(true)); Game1.activeClickableMenu.receiveLeftClick(Game1.getMouseX(true), Game1.getMouseY(true));
} }
if (Config.RightClickMainKey.JustPressed())
{
Game1.activeClickableMenu.receiveRightClick(Game1.getMouseX(true), Game1.getMouseY(true));
}
// Alternate Keybinds if (Config.RightClickMainKey.JustPressed() || Config.RightClickAlternateKey.JustPressed())
if (!isCustomizingCharacter && Game1.activeClickableMenu is not AnimalQueryMenu && Config.LeftClickAlternateKey.JustPressed()) // Excluding the character creation menu
{
Game1.activeClickableMenu.receiveLeftClick(Game1.getMouseX(true), Game1.getMouseY(true));
}
if (!isCustomizingCharacter && Game1.activeClickableMenu is not AnimalQueryMenu && Config.RightClickAlternateKey.JustPressed()) // Excluding the character creation menu
{ {
Game1.activeClickableMenu.receiveRightClick(Game1.getMouseX(true), Game1.getMouseY(true)); Game1.activeClickableMenu.receiveRightClick(Game1.getMouseX(true), Game1.getMouseY(true));
} }
#endregion #endregion
} }
if (Game1.currentMinigame != null) if (Game1.currentMinigame != null && !TextBoxPatch.isAnyTextBoxActive)
{ {
bool isCustomizingCharacter = Game1.activeClickableMenu is CharacterCustomization || (TitleMenu.subMenu != null && TitleMenu.subMenu is CharacterCustomization);
#region Mouse Click Simulation #region Mouse Click Simulation
// Main Keybinds if (Config.LeftClickMainKey.JustPressed() || Config.LeftClickAlternateKey.JustPressed())
if (Config.LeftClickMainKey.JustPressed())
{ {
Game1.currentMinigame.receiveLeftClick(Game1.getMouseX(true), Game1.getMouseY(true)); Game1.currentMinigame.receiveLeftClick(Game1.getMouseX(true), Game1.getMouseY(true));
} }
if (Config.RightClickMainKey.JustPressed())
{
Game1.currentMinigame.receiveRightClick(Game1.getMouseX(true), Game1.getMouseY(true));
}
// Alternate Keybinds if (Config.RightClickMainKey.JustPressed() || Config.RightClickAlternateKey.JustPressed())
if (Config.LeftClickAlternateKey.JustPressed())
{
Game1.currentMinigame.receiveLeftClick(Game1.getMouseX(true), Game1.getMouseY(true));
}
if (Config.RightClickAlternateKey.JustPressed())
{ {
Game1.currentMinigame.receiveRightClick(Game1.getMouseX(true), Game1.getMouseY(true)); Game1.currentMinigame.receiveRightClick(Game1.getMouseX(true), Game1.getMouseY(true));
} }
@ -377,4 +355,4 @@ namespace stardew_access
monitor.Log(message, LogLevel.Debug); monitor.Log(message, LogLevel.Debug);
} }
} }
} }

View File

@ -27,65 +27,54 @@ namespace stardew_access.Patches
{ {
try try
{ {
if (TextBoxPatch.isAnyTextBoxActive) return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For narrating animal details bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For narrating animal details
bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box
string toSpeak = " ", details = " "; string toSpeak = " ", details = " ";
isOnFarm = ___movingAnimal; isOnFarm = ___movingAnimal;
animalQueryMenu = __instance; animalQueryMenu = __instance;
animalBeingPurchasedOrMoved = ___animal; animalBeingPurchasedOrMoved = ___animal;
if (___textBox.Selected) if (isPrimaryInfoKeyPressed & !isNarratingAnimalInfo)
{ {
toSpeak = ___textBox.Text; string name = ___animal.displayName;
string type = ___animal.displayType;
if (isEscPressed) int age = (___animal.GetDaysOwned() + 1) / 28 + 1;
string ageText = (age <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", age);
string parent = "";
if ((int)___animal.age.Value < (byte)___animal.ageWhenMature.Value)
{ {
___textBox.Selected = false; ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby");
} }
} if (___parentName != null)
else
{
if (isPrimaryInfoKeyPressed & !isNarratingAnimalInfo)
{ {
string name = ___animal.displayName; parent = Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", ___parentName);
string type = ___animal.displayType;
int age = (___animal.GetDaysOwned() + 1) / 28 + 1;
string ageText = (age <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", age);
string parent = "";
if ((int)___animal.age.Value < (byte)___animal.ageWhenMature.Value)
{
ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby");
}
if (___parentName != null)
{
parent = Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", ___parentName);
}
details = $"Name: {name} Type: {type} \n\t Age: {ageText} {parent}";
animalQueryMenuQuery = " ";
isNarratingAnimalInfo = true;
Task.Delay(200).ContinueWith(_ => { isNarratingAnimalInfo = false; });
} }
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y)) details = $"Name: {name} Type: {type} \n\t Age: {ageText} {parent}";
toSpeak = "OK button"; animalQueryMenuQuery = " ";
else if (__instance.sellButton != null && __instance.sellButton.containsPoint(x, y))
toSpeak = $"Sell for {___animal.getSellPrice()}g button"; isNarratingAnimalInfo = true;
else if (___confirmingSell && __instance.yesButton != null && __instance.yesButton.containsPoint(x, y)) Task.Delay(200).ContinueWith(_ => { isNarratingAnimalInfo = false; });
toSpeak = "Confirm selling animal";
else if (___confirmingSell && __instance.noButton != null && __instance.noButton.containsPoint(x, y))
toSpeak = "Cancel selling animal";
else if (__instance.moveHomeButton != null && __instance.moveHomeButton.containsPoint(x, y))
toSpeak = "Change home building button";
else if (__instance.allowReproductionButton != null && __instance.allowReproductionButton.containsPoint(x, y))
toSpeak = ((___animal.allowReproduction.Value) ? "Enabled" : "Disabled") + " allow reproduction button";
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
toSpeak = "Animal name text box";
} }
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
toSpeak = "OK button";
else if (__instance.sellButton != null && __instance.sellButton.containsPoint(x, y))
toSpeak = $"Sell for {___animal.getSellPrice()}g button";
else if (___confirmingSell && __instance.yesButton != null && __instance.yesButton.containsPoint(x, y))
toSpeak = "Confirm selling animal";
else if (___confirmingSell && __instance.noButton != null && __instance.noButton.containsPoint(x, y))
toSpeak = "Cancel selling animal";
else if (__instance.moveHomeButton != null && __instance.moveHomeButton.containsPoint(x, y))
toSpeak = "Change home building button";
else if (__instance.allowReproductionButton != null && __instance.allowReproductionButton.containsPoint(x, y))
toSpeak = ((___animal.allowReproduction.Value) ? "Enabled" : "Disabled") + " allow reproduction button";
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
toSpeak = "Animal name text box";
if (animalQueryMenuQuery != toSpeak) if (animalQueryMenuQuery != toSpeak)
{ {
animalQueryMenuQuery = toSpeak; animalQueryMenuQuery = toSpeak;
@ -102,6 +91,8 @@ namespace stardew_access.Patches
{ {
try try
{ {
if (TextBoxPatch.isAnyTextBoxActive) return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
purchaseAnimalsMenu = __instance; purchaseAnimalsMenu = __instance;
isOnFarm = ___onFarm; isOnFarm = ___onFarm;
@ -125,9 +116,9 @@ namespace stardew_access.Patches
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y)) else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
{ {
toSpeak = "Name Text Box"; toSpeak = "Name Text Box";
string? value = ___textBox.Text; // string? value = ___textBox.Text;
if (value != "" && value != null && value != "null") // if (value != "" && value != null && value != "null")
toSpeak = $"{toSpeak}, Value: {value}"; // toSpeak = $"{toSpeak}, Value: {value}";
} }
if (purchaseAnimalMenuQuery != toSpeak) if (purchaseAnimalMenuQuery != toSpeak)
@ -711,4 +702,4 @@ namespace stardew_access.Patches
return; return;
} }
} }
} }

View File

@ -1,8 +1,10 @@
using StardewValley; using StardewValley;
using StardewValley.Menus; using StardewValley.Menus;
namespace stardew_access.Patches { namespace stardew_access.Patches
internal class CharacterCustomizationPatches { {
internal class CharacterCustomizationMenuPatch
{
private static bool isRunning = false; private static bool isRunning = false;
private static int saveGameIndex = -1; private static int saveGameIndex = -1;
public static string characterCreationMenuQueryKey = " "; public static string characterCreationMenuQueryKey = " ";
@ -28,12 +30,14 @@ namespace stardew_access.Patches {
public static bool characterDesignToggleShouldSpeak = true; public static bool characterDesignToggleShouldSpeak = true;
public static ClickableComponent? currentComponent = null; public static ClickableComponent? currentComponent = null;
internal static void CharacterCustomizationMenuPatch(CharacterCustomization __instance, bool ___skipIntro, internal static void DrawPatch(CharacterCustomization __instance, bool ___skipIntro,
ClickableComponent ___startingCabinsLabel, ClickableComponent ___difficultyModifierLabel, TextBox ___nameBox, ClickableComponent ___startingCabinsLabel, ClickableComponent ___difficultyModifierLabel, TextBox ___nameBox,
TextBox ___farmnameBox, TextBox ___favThingBox) TextBox ___farmnameBox, TextBox ___favThingBox)
{ {
try try
{ {
if (TextBoxPatch.isAnyTextBoxActive) return;
bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box
string toSpeak = ""; string toSpeak = "";
if (characterDesignToggleShouldSpeak) if (characterDesignToggleShouldSpeak)
@ -44,37 +48,10 @@ namespace stardew_access.Patches {
string itemsToSpeak = ""; string itemsToSpeak = "";
string changesToSpeak = ""; string changesToSpeak = "";
if (___nameBox.Selected) if (MainClass.Config.CharacterCreationMenuNextKey.JustPressed() && !isRunning)
{
toSpeak = ___nameBox.Text;
if (isEscPressed)
{
___nameBox.Selected = false;
}
}
else if (___farmnameBox.Selected)
{
toSpeak = ___farmnameBox.Text;
if (isEscPressed)
{
___farmnameBox.Selected = false;
}
}
else if (___favThingBox.Selected)
{
toSpeak = ___favThingBox.Text;
if (isEscPressed)
{
___favThingBox.Selected = false;
}
}
else if (MainClass.Config.CharacterCreationMenuNextKey.JustPressed() && !isRunning)
{ {
isRunning = true; isRunning = true;
itemsToSpeak =CycleThroughItems(true, __instance, ___skipIntro, ___startingCabinsLabel, ___difficultyModifierLabel, ___nameBox, ___farmnameBox, ___favThingBox); itemsToSpeak = CycleThroughItems(true, __instance, ___skipIntro, ___startingCabinsLabel, ___difficultyModifierLabel, ___nameBox, ___farmnameBox, ___favThingBox);
if (itemsToSpeak != "") if (itemsToSpeak != "")
toSpeak = $"{itemsToSpeak} \n {toSpeak}"; toSpeak = $"{itemsToSpeak} \n {toSpeak}";
Task.Delay(200).ContinueWith(_ => { isRunning = false; }); Task.Delay(200).ContinueWith(_ => { isRunning = false; });
@ -122,7 +99,9 @@ namespace stardew_access.Patches {
if (characterDesignToggle) if (characterDesignToggle)
{ {
displayState = "shown"; displayState = "shown";
} else { }
else
{
displayState = "hidden"; displayState = "hidden";
} }
toSpeak = $"Character design controls {displayState}. \n {toSpeak}"; toSpeak = $"Character design controls {displayState}. \n {toSpeak}";
@ -210,7 +189,9 @@ namespace stardew_access.Patches {
prevEyeColorHue = currentEyeColorHue; prevEyeColorHue = currentEyeColorHue;
if (currentEyeColorHue != "") if (currentEyeColorHue != "")
toSpeak = $"{toSpeak} \n Hue: {currentEyeColorHue}"; toSpeak = $"{toSpeak} \n Hue: {currentEyeColorHue}";
} else { }
else
{
prevEyeColorHue = ""; prevEyeColorHue = "";
} }
} }
@ -222,7 +203,9 @@ namespace stardew_access.Patches {
prevEyeColorSaturation = currentEyeColorSaturation; prevEyeColorSaturation = currentEyeColorSaturation;
if (currentEyeColorSaturation != "") if (currentEyeColorSaturation != "")
toSpeak = $"{toSpeak} \n Saturation: {currentEyeColorSaturation}"; toSpeak = $"{toSpeak} \n Saturation: {currentEyeColorSaturation}";
} else { }
else
{
prevEyeColorSaturation = ""; prevEyeColorSaturation = "";
} }
} }
@ -234,7 +217,9 @@ namespace stardew_access.Patches {
prevEyeColorValue = currentEyeColorValue; prevEyeColorValue = currentEyeColorValue;
if (currentEyeColorValue != "") if (currentEyeColorValue != "")
toSpeak = $"{toSpeak} \n Value: {currentEyeColorValue}"; toSpeak = $"{toSpeak} \n Value: {currentEyeColorValue}";
} else { }
else
{
prevEyeColorValue = ""; prevEyeColorValue = "";
} }
} }
@ -256,7 +241,9 @@ namespace stardew_access.Patches {
prevHairColorHue = currentHairColorHue; prevHairColorHue = currentHairColorHue;
if (currentHairColorHue != "") if (currentHairColorHue != "")
toSpeak = $"{toSpeak} \n Hue: {currentHairColorHue}"; toSpeak = $"{toSpeak} \n Hue: {currentHairColorHue}";
} else { }
else
{
prevHairColorHue = ""; prevHairColorHue = "";
} }
} }
@ -268,7 +255,9 @@ namespace stardew_access.Patches {
prevHairColorSaturation = currentHairColorSaturation; prevHairColorSaturation = currentHairColorSaturation;
if (currentHairColorSaturation != "") if (currentHairColorSaturation != "")
toSpeak = $"{toSpeak} \n Saturation: {currentHairColorSaturation}"; toSpeak = $"{toSpeak} \n Saturation: {currentHairColorSaturation}";
} else { }
else
{
prevHairColorSaturation = ""; prevHairColorSaturation = "";
} }
} }
@ -280,7 +269,9 @@ namespace stardew_access.Patches {
prevHairColorValue = currentHairColorValue; prevHairColorValue = currentHairColorValue;
if (currentHairColorValue != "") if (currentHairColorValue != "")
toSpeak = $"{toSpeak} \n Value: {currentHairColorValue}"; toSpeak = $"{toSpeak} \n Value: {currentHairColorValue}";
} else { }
else
{
prevHairColorValue = ""; prevHairColorValue = "";
} }
} }
@ -302,7 +293,9 @@ namespace stardew_access.Patches {
prevPantsColorHue = currentPantsColorHue; prevPantsColorHue = currentPantsColorHue;
if (currentPantsColorHue != "") if (currentPantsColorHue != "")
toSpeak = $"{toSpeak} \n Hue: {currentPantsColorHue}"; toSpeak = $"{toSpeak} \n Hue: {currentPantsColorHue}";
} else { }
else
{
prevPantsColorHue = ""; prevPantsColorHue = "";
} }
} }
@ -314,7 +307,9 @@ namespace stardew_access.Patches {
prevPantsColorSaturation = currentPantsColorSaturation; prevPantsColorSaturation = currentPantsColorSaturation;
if (currentPantsColorSaturation != "") if (currentPantsColorSaturation != "")
toSpeak = $"{toSpeak} \n Saturation: {currentPantsColorSaturation}"; toSpeak = $"{toSpeak} \n Saturation: {currentPantsColorSaturation}";
} else { }
else
{
prevPantsColorSaturation = ""; prevPantsColorSaturation = "";
} }
} }
@ -326,7 +321,9 @@ namespace stardew_access.Patches {
prevPantsColorValue = currentPantsColorValue; prevPantsColorValue = currentPantsColorValue;
if (currentPantsColorValue != "") if (currentPantsColorValue != "")
toSpeak = $"{toSpeak} \n Value: {currentPantsColorValue}"; toSpeak = $"{toSpeak} \n Value: {currentPantsColorValue}";
} else { }
else
{
prevPantsColorValue = ""; prevPantsColorValue = "";
} }
} }
@ -345,13 +342,12 @@ namespace stardew_access.Patches {
if (prevPetName != currentPetName) if (prevPetName != currentPetName)
{ {
prevPetName = currentPetName; prevPetName = currentPetName;
if (currentPetName != "") if (currentPetName != "")
toSpeak = $"{toSpeak} \n Current Pet: {currentPetName}"; toSpeak = $"{toSpeak} \n Current Pet: {currentPetName}";
} }
return toSpeak.Trim(); return toSpeak.Trim();
} }
private static string CycleThroughItems(bool increase, CharacterCustomization __instance, bool ___skipIntro, private static string CycleThroughItems(bool increase, CharacterCustomization __instance, bool ___skipIntro,
ClickableComponent ___startingCabinsLabel, ClickableComponent ___difficultyModifierLabel, TextBox ___nameBox, ClickableComponent ___startingCabinsLabel, ClickableComponent ___difficultyModifierLabel, TextBox ___nameBox,
TextBox ___farmnameBox, TextBox ___favThingBox) TextBox ___farmnameBox, TextBox ___favThingBox)
@ -369,7 +365,9 @@ namespace stardew_access.Patches {
if (___nameBox.Text != "") if (___nameBox.Text != "")
{ {
postText = $": {___nameBox.Text}"; postText = $": {___nameBox.Text}";
} else { }
else
{
postText = " Text Box"; postText = " Text Box";
} }
buttons.Add(__instance.nameBoxCC, $"Farmer's Name{postText}"); buttons.Add(__instance.nameBoxCC, $"Farmer's Name{postText}");
@ -380,7 +378,9 @@ namespace stardew_access.Patches {
if (___farmnameBox.Text != "") if (___farmnameBox.Text != "")
{ {
postText = $": {___farmnameBox.Text}"; postText = $": {___farmnameBox.Text}";
} else { }
else
{
postText = " Text Box"; postText = " Text Box";
} }
buttons.Add(__instance.farmnameBoxCC, $"Farm's Name{postText}"); buttons.Add(__instance.farmnameBoxCC, $"Farm's Name{postText}");
@ -391,7 +391,9 @@ namespace stardew_access.Patches {
if (___favThingBox.Text != "") if (___favThingBox.Text != "")
{ {
postText = $": {___favThingBox.Text}"; postText = $": {___favThingBox.Text}";
} else { }
else
{
postText = " Text Box"; postText = " Text Box";
} }
buttons.Add(__instance.favThingBoxCC, $"Favourite Thing{postText}"); buttons.Add(__instance.favThingBoxCC, $"Favourite Thing{postText}");
@ -411,10 +413,10 @@ namespace stardew_access.Patches {
// Controls to rotate the farmer (Potentially useful for low vision players) are first if they're available. // Controls to rotate the farmer (Potentially useful for low vision players) are first if they're available.
// They also appear above the gender buttons, so we handle them separately here. // They also appear above the gender buttons, so we handle them separately here.
if (characterDesignToggle && new[] {__instance.leftSelectionButtons.Count, __instance.rightSelectionButtons.Count }.All(c => c >= 0)) // both have Count > 0 if (characterDesignToggle && new[] { __instance.leftSelectionButtons.Count, __instance.rightSelectionButtons.Count }.All(c => c >= 0)) // both have Count > 0
{ {
if (new[] {__instance.leftSelectionButtons[DesignControlsIndex].visible, __instance.rightSelectionButtons[DesignControlsIndex].visible }.All(v => v == true) // both visible if (new[] { __instance.leftSelectionButtons[DesignControlsIndex].visible, __instance.rightSelectionButtons[DesignControlsIndex].visible }.All(v => v == true) // both visible
&& new[] {__instance.leftSelectionButtons[DesignControlsIndex].name, __instance.rightSelectionButtons[DesignControlsIndex].name }.All(n => n == "Direction")) // both named "Direction" && new[] { __instance.leftSelectionButtons[DesignControlsIndex].name, __instance.rightSelectionButtons[DesignControlsIndex].name }.All(n => n == "Direction")) // both named "Direction"
{ {
buttons.Add(__instance.leftSelectionButtons[DesignControlsIndex], "Rotate Left Button"); buttons.Add(__instance.leftSelectionButtons[DesignControlsIndex], "Rotate Left Button");
buttons.Add(__instance.rightSelectionButtons[DesignControlsIndex], "Rotate Right Button"); buttons.Add(__instance.rightSelectionButtons[DesignControlsIndex], "Rotate Right Button");
@ -428,9 +430,9 @@ namespace stardew_access.Patches {
buttons.Add(__instance.genderButtons[1], ((!Game1.player.IsMale) ? "Selected " : "") + "Gender: Female Button"); buttons.Add(__instance.genderButtons[1], ((!Game1.player.IsMale) ? "Selected " : "") + "Gender: Female Button");
} }
if (characterDesignToggle&& new[] {__instance.leftSelectionButtons.Count, __instance.rightSelectionButtons.Count }.All(c => c >= DesignControlsIndex) && new[] {__instance.leftSelectionButtons[DesignControlsIndex].visible, __instance.rightSelectionButtons[DesignControlsIndex].visible }.All(v => v == true)) if (characterDesignToggle && new[] { __instance.leftSelectionButtons.Count, __instance.rightSelectionButtons.Count }.All(c => c >= DesignControlsIndex) && new[] { __instance.leftSelectionButtons[DesignControlsIndex].visible, __instance.rightSelectionButtons[DesignControlsIndex].visible }.All(v => v == true))
{ {
while(DesignControlsIndex < __instance.leftSelectionButtons.Count) while (DesignControlsIndex < __instance.leftSelectionButtons.Count)
{ {
ClickableComponent left = __instance.leftSelectionButtons[DesignControlsIndex]; ClickableComponent left = __instance.leftSelectionButtons[DesignControlsIndex];
ClickableComponent right = __instance.rightSelectionButtons[DesignControlsIndex]; ClickableComponent right = __instance.rightSelectionButtons[DesignControlsIndex];
@ -574,7 +576,7 @@ namespace stardew_access.Patches {
} }
currentComponent = buttons.ElementAt(saveGameIndex).Key; currentComponent = buttons.ElementAt(saveGameIndex).Key;
currentComponent!.snapMouseCursor(); currentComponent!.snapMouseCursor();
__instance.setCurrentlySnappedComponentTo(currentComponent!.myID); __instance.setCurrentlySnappedComponentTo(currentComponent!.myID);
toSpeak = buttons.ElementAt(saveGameIndex).Value; toSpeak = buttons.ElementAt(saveGameIndex).Value;
@ -655,16 +657,18 @@ namespace stardew_access.Patches {
break; break;
} }
return sb; return sb;
} else { }
else
{
return null; return null;
} }
} }
private static void AdjustCurrentSlider(bool increase, CharacterCustomization __instance, int amount=1) private static void AdjustCurrentSlider(bool increase, CharacterCustomization __instance, int amount = 1)
{ {
if (currentComponent != null && currentComponent.myID >= 522 && currentComponent.myID <= 530) if (currentComponent != null && currentComponent.myID >= 522 && currentComponent.myID <= 530)
{ {
SliderBar sb = getCurrentSliderBar(currentComponent.myID, __instance) !; SliderBar sb = getCurrentSliderBar(currentComponent.myID, __instance)!;
if (sb != null) if (sb != null)
{ {
double step = ((double)sb.bounds.Width / 100d); // size of 1% change in slider value double step = ((double)sb.bounds.Width / 100d); // size of 1% change in slider value
@ -675,7 +679,9 @@ namespace stardew_access.Patches {
{ {
value = Math.Min(value + amount, 99d); value = Math.Min(value + amount, 99d);
x = Math.Min(Math.Ceiling((value * step)), (double)sb.bounds.Width); x = Math.Min(Math.Ceiling((value * step)), (double)sb.bounds.Width);
} else { }
else
{
value = Math.Max(value - amount, 0d); value = Math.Max(value - amount, 0d);
x = Math.Max(Math.Ceiling((value * step)), 0d); x = Math.Max(Math.Ceiling((value * step)), 0d);
} }
@ -821,7 +827,9 @@ namespace stardew_access.Patches {
if (currentComponent != null && currentComponent.name == "Pet") if (currentComponent != null && currentComponent.name == "Pet")
{ {
return ((Game1.player.catPerson) ? "Cat" : "Dog") + " Breed: " + Game1.player.whichPetBreed; return ((Game1.player.catPerson) ? "Cat" : "Dog") + " Breed: " + Game1.player.whichPetBreed;
} else { }
else
{
return ""; return "";
} }
} }

View File

@ -1,5 +1,4 @@
using StardewValley; using StardewValley.Menus;
using StardewValley.Menus;
namespace stardew_access.Patches namespace stardew_access.Patches
{ {

View File

@ -0,0 +1,123 @@
using StardewValley.Menus;
namespace stardew_access.Patches
{
// These patches are global, i.e. work on every menus
internal class IClickableMenuPatch
{
internal static void ExitThisMenuPatch(IClickableMenu __instance)
{
try
{
Cleanup(__instance);
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
internal static void Cleanup(IClickableMenu menu)
{
if (menu is LetterViewerMenu)
{
DialoguePatches.currentLetterText = " ";
}
else if (menu is LevelUpMenu)
{
MenuPatches.currentLevelUpTitle = " ";
}
else if (menu is Billboard)
{
QuestPatches.currentDailyQuestText = " ";
}
else if (menu is GameMenu)
{
GameMenuPatches.gameMenuQueryKey = "";
GameMenuPatches.craftingPageQueryKey = "";
GameMenuPatches.inventoryPageQueryKey = "";
GameMenuPatches.exitPageQueryKey = "";
GameMenuPatches.optionsPageQueryKey = "";
GameMenuPatches.socialPageQuery = "";
GameMenuPatches.currentSelectedCraftingRecipe = -1;
GameMenuPatches.isSelectingRecipe = false;
}
else if (menu is JunimoNoteMenu)
{
BundleMenuPatches.currentIngredientListItem = -1;
BundleMenuPatches.currentIngredientInputSlot = -1;
BundleMenuPatches.currentInventorySlot = -1;
BundleMenuPatches.junimoNoteMenuQuery = "";
}
else if (menu is ShopMenu)
{
GameMenuPatches.shopMenuQueryKey = "";
}
else if (menu is ItemGrabMenu)
{
GameMenuPatches.itemGrabMenuQueryKey = "";
}
else if (menu is GeodeMenu)
{
GameMenuPatches.geodeMenuQueryKey = "";
}
else if (menu is CarpenterMenu)
{
BuildingNAnimalMenuPatches.carpenterMenuQuery = "";
BuildingNAnimalMenuPatches.isUpgrading = false;
BuildingNAnimalMenuPatches.isDemolishing = false;
BuildingNAnimalMenuPatches.isPainting = false;
BuildingNAnimalMenuPatches.isMoving = false;
BuildingNAnimalMenuPatches.isConstructing = false;
BuildingNAnimalMenuPatches.carpenterMenu = null;
}
else if (menu is PurchaseAnimalsMenu)
{
BuildingNAnimalMenuPatches.purchaseAnimalMenuQuery = "";
BuildingNAnimalMenuPatches.firstTimeInNamingMenu = true;
BuildingNAnimalMenuPatches.purchaseAnimalsMenu = null;
}
else if (menu is DialogueBox)
{
DialoguePatches.isDialogueAppearingFirstTime = true;
DialoguePatches.currentDialogue = " ";
}
else if (menu is JojaCDMenu)
{
BundleMenuPatches.jojaCDMenuQuery = "";
}
else if (menu is QuestLog)
{
QuestPatches.questLogQuery = " ";
}
else if (menu is TailoringMenu)
{
MenuPatches.tailoringMenuQuery = " ";
}
else if (menu is ForgeMenu)
{
MenuPatches.forgeMenuQuery = " ";
}
else if (menu is ItemListMenu)
{
MenuPatches.itemListMenuQuery = " ";
}
else if (menu is FieldOfficeMenu)
{
DonationMenuPatches.fieldOfficeMenuQuery = " ";
}
else if (menu is MuseumMenu)
{
DonationMenuPatches.museumQueryKey = " ";
}
else if (menu is PondQueryMenu)
{
MenuPatches.pondQueryMenuQuery = " ";
}
InventoryUtils.hoveredItemQueryKey = "";
InventoryUtils.prevSlotIndex = -999;
TextBoxPatch.activeTextBoxes = "";
}
}
}

View File

@ -420,35 +420,24 @@ namespace stardew_access.Patches
{ {
try try
{ {
string toSpeak = "";
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box
if (firstTimeInNamingMenu) if (firstTimeInNamingMenu)
{ {
firstTimeInNamingMenu = false; firstTimeInNamingMenu = false;
___textBox.Selected = false; ___textBox.Selected = false;
} }
if (___textBox.Selected) if (TextBoxPatch.isAnyTextBoxActive) return;
{
___textBox.Update();
toSpeak = ___textBox.Text;
if (isEscPressed) string toSpeak = "";
{ int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
___textBox.Selected = false; bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box
}
} if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
else toSpeak = $"{___title} text box";
{ else if (__instance.doneNamingButton != null && __instance.doneNamingButton.containsPoint(x, y))
if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y)) toSpeak = $"Done naming button";
toSpeak = $"{___title} text box"; else if (__instance.randomButton != null && __instance.randomButton.containsPoint(x, y))
else if (__instance.doneNamingButton != null && __instance.doneNamingButton.containsPoint(x, y)) toSpeak = $"Random button";
toSpeak = $"Done naming button";
else if (__instance.randomButton != null && __instance.randomButton.containsPoint(x, y))
toSpeak = $"Random button";
}
if (toSpeak != "") if (toSpeak != "")
MainClass.ScreenReader.SayWithChecker(toSpeak, true); MainClass.ScreenReader.SayWithChecker(toSpeak, true);
@ -615,12 +604,11 @@ namespace stardew_access.Patches
} }
} }
#region Cleanup on exitting a menu
internal static void Game1ExitActiveMenuPatch() internal static void Game1ExitActiveMenuPatch()
{ {
try try
{ {
Cleanup(Game1.activeClickableMenu); IClickableMenuPatch.Cleanup(Game1.activeClickableMenu);
} }
catch (Exception e) catch (Exception e)
{ {
@ -628,121 +616,6 @@ namespace stardew_access.Patches
} }
} }
internal static void IClickableMenuOnExitPatch(IClickableMenu __instance)
{
try
{
Cleanup(__instance);
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
private static void Cleanup(IClickableMenu menu)
{
if (menu is LetterViewerMenu)
{
DialoguePatches.currentLetterText = " ";
}
else if (menu is LevelUpMenu)
{
currentLevelUpTitle = " ";
}
else if (menu is Billboard)
{
QuestPatches.currentDailyQuestText = " ";
}
else if (menu is GameMenu)
{
GameMenuPatches.gameMenuQueryKey = "";
GameMenuPatches.craftingPageQueryKey = "";
GameMenuPatches.inventoryPageQueryKey = "";
GameMenuPatches.exitPageQueryKey = "";
GameMenuPatches.optionsPageQueryKey = "";
GameMenuPatches.socialPageQuery = "";
GameMenuPatches.currentSelectedCraftingRecipe = -1;
GameMenuPatches.isSelectingRecipe = false;
}
else if (menu is JunimoNoteMenu)
{
BundleMenuPatches.currentIngredientListItem = -1;
BundleMenuPatches.currentIngredientInputSlot = -1;
BundleMenuPatches.currentInventorySlot = -1;
BundleMenuPatches.junimoNoteMenuQuery = "";
}
else if (menu is ShopMenu)
{
GameMenuPatches.shopMenuQueryKey = "";
}
else if (menu is ItemGrabMenu)
{
GameMenuPatches.itemGrabMenuQueryKey = "";
}
else if (menu is GeodeMenu)
{
GameMenuPatches.geodeMenuQueryKey = "";
}
else if (menu is CarpenterMenu)
{
BuildingNAnimalMenuPatches.carpenterMenuQuery = "";
BuildingNAnimalMenuPatches.isUpgrading = false;
BuildingNAnimalMenuPatches.isDemolishing = false;
BuildingNAnimalMenuPatches.isPainting = false;
BuildingNAnimalMenuPatches.isMoving = false;
BuildingNAnimalMenuPatches.isConstructing = false;
BuildingNAnimalMenuPatches.carpenterMenu = null;
}
else if (menu is PurchaseAnimalsMenu)
{
BuildingNAnimalMenuPatches.purchaseAnimalMenuQuery = "";
BuildingNAnimalMenuPatches.firstTimeInNamingMenu = true;
BuildingNAnimalMenuPatches.purchaseAnimalsMenu = null;
}
else if (menu is DialogueBox)
{
DialoguePatches.isDialogueAppearingFirstTime = true;
DialoguePatches.currentDialogue = " ";
}
else if (menu is JojaCDMenu)
{
BundleMenuPatches.jojaCDMenuQuery = "";
}
else if (menu is QuestLog)
{
QuestPatches.questLogQuery = " ";
}
else if (menu is TailoringMenu)
{
tailoringMenuQuery = " ";
}
else if (menu is ForgeMenu)
{
forgeMenuQuery = " ";
}
else if (menu is ItemListMenu)
{
itemListMenuQuery = " ";
}
else if (menu is FieldOfficeMenu)
{
DonationMenuPatches.fieldOfficeMenuQuery = " ";
}
else if (menu is MuseumMenu)
{
DonationMenuPatches.museumQueryKey = " ";
}
else if (menu is PondQueryMenu)
{
pondQueryMenuQuery = " ";
}
InventoryUtils.hoveredItemQueryKey = "";
InventoryUtils.prevSlotIndex = -999;
}
#endregion
internal static void ExitEventPatch() internal static void ExitEventPatch()
{ {
if (MainClass.ScreenReader != null) if (MainClass.ScreenReader != null)

View File

@ -0,0 +1,42 @@
namespace stardew_access.Patches
{
internal class TextBoxPatch
{
internal static string textBoxQuery = " ";
internal static string activeTextBoxes = "";
internal static bool isAnyTextBoxActive => activeTextBoxes != "";
internal static void DrawPatch(StardewValley.Menus.TextBox __instance)
{
try
{
string uniqueIdentifier = $"{__instance.X}:{__instance.Y}:{__instance.Height}:{__instance.Width}";
if (!__instance.Selected)
{
if (activeTextBoxes.Contains(uniqueIdentifier)) activeTextBoxes = activeTextBoxes.Replace(uniqueIdentifier, "");
return;
}
if (!activeTextBoxes.Contains(uniqueIdentifier)) activeTextBoxes += uniqueIdentifier;
bool isEscPressed = StardewValley.Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape);
string toSpeak = __instance.Text;
if (isEscPressed)
{
__instance.Selected = false;
}
if (textBoxQuery != toSpeak)
{
textBoxQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
}
catch (Exception e)
{
MainClass.ErrorLog($"An error occured in DrawPatch() in TextBoxPatch:\n{e.Message}\n{e.StackTrace}");
}
}
}
}

View File

@ -1,37 +1,12 @@
using StardewValley; using StardewValley;
using StardewValley.Menus; using StardewValley.Menus;
using static StardewValley.Menus.CharacterCustomization;
using static StardewValley.Menus.LoadGameMenu; using static StardewValley.Menus.LoadGameMenu;
namespace stardew_access.Patches namespace stardew_access.Patches
{ {
internal class TitleMenuPatches internal class TitleMenuPatches
{ {
private static int saveGameIndex = -1;
private static bool isRunning = false;
public static string characterCreationMenuQueryKey = " ";
public static string advancedGameOptionsQueryKey = " "; public static string advancedGameOptionsQueryKey = " ";
public static string prevPants = " ";
public static string prevShirt = " ";
public static string prevHair = " ";
public static string prevAccessory = " ";
public static string prevSkin = " ";
public static string prevEyeColor = " ";
public static string prevEyeColorHue = " ";
public static string prevEyeColorSaturation = " ";
public static string prevEyeColorValue = " ";
public static string prevHairColor = " ";
public static string prevHairColorHue = " ";
public static string prevHairColorSaturation = " ";
public static string prevHairColorValue = " ";
public static string prevPantsColor = " ";
public static string prevPantsColorHue = " ";
public static string prevPantsColorSaturation = " ";
public static string prevPantsColorValue = " ";
public static string prevPetName = " ";
public static bool characterDesignToggle = false;
public static bool characterDesignToggleShouldSpeak = true;
public static ClickableComponent? currentComponent = null;
internal static void AdvancedGameOptionsPatch(AdvancedGameOptions __instance) internal static void AdvancedGameOptionsPatch(AdvancedGameOptions __instance)
{ {
@ -259,803 +234,5 @@ namespace stardew_access.Patches
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
} }
} }
internal static void CharacterCustomizationMenuPatch(CharacterCustomization __instance, bool ___skipIntro,
ClickableComponent ___startingCabinsLabel, ClickableComponent ___difficultyModifierLabel, TextBox ___nameBox,
TextBox ___farmnameBox, TextBox ___favThingBox)
{
try
{
bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box
string toSpeak = "";
if (characterDesignToggleShouldSpeak)
{
toSpeak = "Press left control + space to toggle character appearance controls";
characterDesignToggleShouldSpeak = false;
}
string itemsToSpeak = "";
string changesToSpeak = "";
if (___nameBox.Selected)
{
toSpeak = ___nameBox.Text;
if (isEscPressed)
{
___nameBox.Selected = false;
}
}
else if (___farmnameBox.Selected)
{
toSpeak = ___farmnameBox.Text;
if (isEscPressed)
{
___farmnameBox.Selected = false;
}
}
else if (___favThingBox.Selected)
{
toSpeak = ___favThingBox.Text;
if (isEscPressed)
{
___favThingBox.Selected = false;
}
}
else if (MainClass.Config.CharacterCreationMenuNextKey.JustPressed() && !isRunning)
{
isRunning = true;
itemsToSpeak =CycleThroughItems(true, __instance, ___skipIntro, ___startingCabinsLabel, ___difficultyModifierLabel, ___nameBox, ___farmnameBox, ___favThingBox);
if (itemsToSpeak != "")
toSpeak = $"{itemsToSpeak} \n {toSpeak}";
Task.Delay(200).ContinueWith(_ => { isRunning = false; });
}
else if (MainClass.Config.CharacterCreationMenuPreviousKey.JustPressed() && !isRunning)
{
isRunning = true;
toSpeak = CycleThroughItems(false, __instance, ___skipIntro, ___startingCabinsLabel, ___difficultyModifierLabel, ___nameBox, ___farmnameBox, ___favThingBox);
Task.Delay(200).ContinueWith(_ => { isRunning = false; });
}
else if (characterDesignToggle && MainClass.Config.CharacterCreationMenuSliderIncreaseKey.JustPressed() && !isRunning)
{
isRunning = true;
AdjustCurrentSlider(true, __instance);
Task.Delay(200).ContinueWith(_ => { isRunning = false; });
}
else if (characterDesignToggle && MainClass.Config.CharacterCreationMenuSliderLargeIncreaseKey.JustPressed() && !isRunning)
{
isRunning = true;
AdjustCurrentSlider(true, __instance, 10);
Task.Delay(200).ContinueWith(_ => { isRunning = false; });
}
else if (characterDesignToggle && MainClass.Config.CharacterCreationMenuSliderDecreaseKey.JustPressed() && !isRunning)
{
isRunning = true;
AdjustCurrentSlider(false, __instance);
Task.Delay(200).ContinueWith(_ => { isRunning = false; });
}
else if (characterDesignToggle && MainClass.Config.CharacterCreationMenuSliderLargeDecreaseKey.JustPressed() && !isRunning)
{
isRunning = true;
AdjustCurrentSlider(false, __instance, 10);
Task.Delay(200).ContinueWith(_ => { isRunning = false; });
}
else if (Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.LeftControl) && MainClass.Config.CharacterCreationMenuDesignToggleKey.JustPressed() && !isRunning)
{
string displayState = "";
characterDesignToggle = !characterDesignToggle;
saveGameIndex = Math.Min(saveGameIndex, 5); // move to random skin button if focus was beyond that point
if (characterDesignToggle)
{
displayState = "shown";
} else {
displayState = "hidden";
}
toSpeak = $"Character design controls {displayState}. \n {toSpeak}";
}
changesToSpeak = getChangesToSpeak(__instance);
if (changesToSpeak != "")
toSpeak = $"{toSpeak} \n {changesToSpeak}";
if (characterCreationMenuQueryKey != toSpeak && toSpeak.Trim() != "")
{
characterCreationMenuQueryKey = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
private static string getChangesToSpeak(CharacterCustomization __instance)
{
string toSpeak = "";
string currentPetName = getCurrentPetName();
string currentSkin = getCurrentSkin();
string currentHair = getCurrentHair();
string currentShirt = getCurrentShirt();
string currentPants = getCurrentPants();
string currentAccessory = getCurrentAccessory();
string currentEyeColor = getCurrentEyeColor();
string currentEyeColorHue = getCurrentEyeColorHue(__instance);
string currentEyeColorSaturation = getCurrentEyeColorSaturation(__instance);
string currentEyeColorValue = getCurrentEyeColorValue(__instance);
string currentHairColor = getCurrentHairColor();
string currentHairColorHue = getCurrentHairColorHue(__instance);
string currentHairColorSaturation = getCurrentHairColorSaturation(__instance);
string currentHairColorValue = getCurrentHairColorValue(__instance);
string currentPantsColor = getCurrentPantsColor();
string currentPantsColorHue = getCurrentPantsColorHue(__instance);
string currentPantsColorSaturation = getCurrentPantsColorSaturation(__instance);
string currentPantsColorValue = getCurrentPantsColorValue(__instance);
if (characterDesignToggle)
{
if (prevSkin != currentSkin)
{
prevSkin = currentSkin;
if (currentSkin != "")
toSpeak = $"{toSpeak} \n {currentSkin}";
}
if (prevHair != currentHair)
{
prevHair = currentHair;
if (currentHair != "")
toSpeak = $"{toSpeak} \n {currentHair}";
}
if (prevShirt != currentShirt)
{
prevShirt = currentShirt;
if (currentShirt != "")
toSpeak = $"{toSpeak} \n {currentShirt}";
}
if (prevPants != currentPants)
{
prevPants = currentPants;
if (currentPants != "")
toSpeak = $"{toSpeak} \n {currentPants}";
}
if (prevAccessory != currentAccessory)
{
prevAccessory = currentAccessory;
if (currentAccessory != "")
toSpeak = $"{toSpeak} \n {currentAccessory}";
}
if (prevEyeColorHue != currentEyeColorHue)
{
if (currentComponent != null && currentComponent.myID == 522)
{
prevEyeColorHue = currentEyeColorHue;
if (currentEyeColorHue != "")
toSpeak = $"{toSpeak} \n Hue: {currentEyeColorHue}";
} else {
prevEyeColorHue = "";
}
}
if (prevEyeColorSaturation != currentEyeColorSaturation)
{
if (currentComponent != null && currentComponent.myID == 523)
{
prevEyeColorSaturation = currentEyeColorSaturation;
if (currentEyeColorSaturation != "")
toSpeak = $"{toSpeak} \n Saturation: {currentEyeColorSaturation}";
} else {
prevEyeColorSaturation = "";
}
}
if (prevEyeColorValue != currentEyeColorValue)
{
if (currentComponent != null && currentComponent.myID == 524)
{
prevEyeColorValue = currentEyeColorValue;
if (currentEyeColorValue != "")
toSpeak = $"{toSpeak} \n Value: {currentEyeColorValue}";
} else {
prevEyeColorValue = "";
}
}
if (prevEyeColor != currentEyeColor)
{
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 522 || currentComponent.myID <= 524)))
{
prevEyeColor = currentEyeColor;
if (currentEyeColor != "")
toSpeak = $"{toSpeak} \n {currentEyeColor}";
}
}
if (prevHairColorHue != currentHairColorHue)
{
if (currentComponent != null && currentComponent.myID == 525)
{
prevHairColorHue = currentHairColorHue;
if (currentHairColorHue != "")
toSpeak = $"{toSpeak} \n Hue: {currentHairColorHue}";
} else {
prevHairColorHue = "";
}
}
if (prevHairColorSaturation != currentHairColorSaturation)
{
if (currentComponent != null && currentComponent.myID == 526)
{
prevHairColorSaturation = currentHairColorSaturation;
if (currentHairColorSaturation != "")
toSpeak = $"{toSpeak} \n Saturation: {currentHairColorSaturation}";
} else {
prevHairColorSaturation = "";
}
}
if (prevHairColorValue != currentHairColorValue)
{
if (currentComponent != null && currentComponent.myID == 527)
{
prevHairColorValue = currentHairColorValue;
if (currentHairColorValue != "")
toSpeak = $"{toSpeak} \n Value: {currentHairColorValue}";
} else {
prevHairColorValue = "";
}
}
if (prevHairColor != currentHairColor)
{
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 525 || currentComponent.myID <= 527)))
{
prevHairColor = currentHairColor;
if (currentHairColor != "")
toSpeak = $"{toSpeak} \n {currentHairColor}";
}
}
if (prevPantsColorHue != currentPantsColorHue)
{
if (currentComponent != null && currentComponent.myID == 528)
{
prevPantsColorHue = currentPantsColorHue;
if (currentPantsColorHue != "")
toSpeak = $"{toSpeak} \n Hue: {currentPantsColorHue}";
} else {
prevPantsColorHue = "";
}
}
if (prevPantsColorSaturation != currentPantsColorSaturation)
{
if (currentComponent != null && currentComponent.myID == 529)
{
prevPantsColorSaturation = currentPantsColorSaturation;
if (currentPantsColorSaturation != "")
toSpeak = $"{toSpeak} \n Saturation: {currentPantsColorSaturation}";
} else {
prevPantsColorSaturation = "";
}
}
if (prevPantsColorValue != currentPantsColorValue)
{
if (currentComponent != null && currentComponent.myID == 530)
{
prevPantsColorValue = currentPantsColorValue;
if (currentPantsColorValue != "")
toSpeak = $"{toSpeak} \n Value: {currentPantsColorValue}";
} else {
prevPantsColorValue = "";
}
}
if (prevPantsColor != currentPantsColor)
{
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 528 || currentComponent.myID <= 530)))
{
prevPantsColor = currentPantsColor;
if (currentPantsColor != "")
toSpeak = $"{toSpeak} \n {currentPantsColor}";
}
}
}
if (prevPetName != currentPetName)
{
prevPetName = currentPetName;
if (currentPetName != "")
toSpeak = $"{toSpeak} \n Current Pet: {currentPetName}";
}
return toSpeak.Trim();
}
private static string CycleThroughItems(bool increase, CharacterCustomization __instance, bool ___skipIntro,
ClickableComponent ___startingCabinsLabel, ClickableComponent ___difficultyModifierLabel, TextBox ___nameBox,
TextBox ___farmnameBox, TextBox ___favThingBox)
{
string toSpeak = " ";
int DesignControlsIndex = 0;
Dictionary<ClickableComponent, string> buttons = new();
#region Add buttons with their names IF they are available
#region Character related
string postText = "";
if (__instance.nameBoxCC != null && __instance.nameBoxCC.visible)
{
if (___nameBox.Text != "")
{
postText = $": {___nameBox.Text}";
} else {
postText = " Text Box";
}
buttons.Add(__instance.nameBoxCC, $"Farmer's Name{postText}");
}
if (__instance.farmnameBoxCC != null && __instance.farmnameBoxCC.visible)
{
if (___farmnameBox.Text != "")
{
postText = $": {___farmnameBox.Text}";
} else {
postText = " Text Box";
}
buttons.Add(__instance.farmnameBoxCC, $"Farm's Name{postText}");
}
if (__instance.favThingBoxCC != null && __instance.favThingBoxCC.visible)
{
if (___favThingBox.Text != "")
{
postText = $": {___favThingBox.Text}";
} else {
postText = " Text Box";
}
buttons.Add(__instance.favThingBoxCC, $"Favourite Thing{postText}");
}
if (__instance.petPortraitBox.HasValue) // Cannot get petButtons like with others
{
ClickableComponent petPrev = __instance.getComponentWithID(511);
buttons.Add(petPrev, "Previous pet button");
ClickableComponent petNext = __instance.getComponentWithID(510);
buttons.Add(petNext, "Next pet button");
}
if (__instance.randomButton != null && __instance.randomButton.visible)
buttons.Add(__instance.randomButton, "Random Skin Button");
// Controls to rotate the farmer (Potentially useful for low vision players) are first if they're available.
// They also appear above the gender buttons, so we handle them separately here.
if (characterDesignToggle && new[] {__instance.leftSelectionButtons.Count, __instance.rightSelectionButtons.Count }.All(c => c >= 0)) // both have Count > 0
{
if (new[] {__instance.leftSelectionButtons[DesignControlsIndex].visible, __instance.rightSelectionButtons[DesignControlsIndex].visible }.All(v => v == true) // both visible
&& new[] {__instance.leftSelectionButtons[DesignControlsIndex].name, __instance.rightSelectionButtons[DesignControlsIndex].name }.All(n => n == "Direction")) // both named "Direction"
{
buttons.Add(__instance.leftSelectionButtons[DesignControlsIndex], "Rotate Left Button");
buttons.Add(__instance.rightSelectionButtons[DesignControlsIndex], "Rotate Right Button");
++DesignControlsIndex;
}
}
if (__instance.genderButtons.Count > 0)
{
buttons.Add(__instance.genderButtons[0], ((Game1.player.IsMale) ? "Selected " : "") + "Gender: Male Button");
buttons.Add(__instance.genderButtons[1], ((!Game1.player.IsMale) ? "Selected " : "") + "Gender: Female Button");
}
if (characterDesignToggle&& new[] {__instance.leftSelectionButtons.Count, __instance.rightSelectionButtons.Count }.All(c => c >= DesignControlsIndex) && new[] {__instance.leftSelectionButtons[DesignControlsIndex].visible, __instance.rightSelectionButtons[DesignControlsIndex].visible }.All(v => v == true))
{
while(DesignControlsIndex < __instance.leftSelectionButtons.Count)
{
ClickableComponent left = __instance.leftSelectionButtons[DesignControlsIndex];
ClickableComponent right = __instance.rightSelectionButtons[DesignControlsIndex];
string name = left.name;
// minor cleanup on names to be slightly more descriptive
switch (name)
{
case "Skin":
name += " Tone";
break;
case "Hair":
name += " Style";
break;
case "Acc":
name = "Accessory";
break;
default:
break;
}
if (!buttons.ContainsKey(left) || !buttons.ContainsKey(right))
{
buttons.Add(left, $"Previous {name} button");
buttons.Add(right, $"Next {name} button");
}
//MainClass.ScreenReader.Say($"Left {DesignControlsIndex}: {__instance.leftSelectionButtons[DesignControlsIndex]} {__instance.leftSelectionButtons[DesignControlsIndex].name}\n", true);
//MainClass.ScreenReader.Say($"Right {DesignControlsIndex}: {__instance.rightSelectionButtons[DesignControlsIndex]} {__instance.rightSelectionButtons[DesignControlsIndex].name}\n", true);
++DesignControlsIndex;
}
ClickableComponent eyeColorHue = __instance.getComponentWithID(522);
if (eyeColorHue != null && eyeColorHue.visible)
buttons.Add(eyeColorHue, "eye color hue slider");
ClickableComponent eyeColorSaturation = __instance.getComponentWithID(523);
if (eyeColorSaturation != null && eyeColorSaturation.visible)
buttons.Add(eyeColorSaturation, "eye color saturation slider");
ClickableComponent eyeColorValue = __instance.getComponentWithID(524);
if (eyeColorValue != null && eyeColorValue.visible)
buttons.Add(eyeColorValue, "eye color Value slider");
ClickableComponent hairColorHue = __instance.getComponentWithID(525);
if (hairColorHue != null && hairColorHue.visible)
buttons.Add(hairColorHue, "hair color hue slider");
ClickableComponent hairColorSaturation = __instance.getComponentWithID(526);
if (hairColorSaturation != null && hairColorSaturation.visible)
buttons.Add(hairColorSaturation, "hair color saturation slider");
ClickableComponent hairColorValue = __instance.getComponentWithID(527);
if (hairColorValue != null && hairColorValue.visible)
buttons.Add(hairColorValue, "hair color Value slider");
ClickableComponent pantsColorHue = __instance.getComponentWithID(528);
if (pantsColorHue != null && pantsColorHue.visible)
buttons.Add(pantsColorHue, "pants color hue slider");
ClickableComponent pantsColorSaturation = __instance.getComponentWithID(529);
if (pantsColorSaturation != null && pantsColorSaturation.visible)
buttons.Add(pantsColorSaturation, "pants color saturation slider");
ClickableComponent pantsColorValue = __instance.getComponentWithID(530);
if (pantsColorValue != null && pantsColorValue.visible)
buttons.Add(pantsColorValue, "pants color Value slider");
}
#endregion
#region Farm layout related
if (__instance.farmTypeButtons.Count > 0)
{
for (int i = 0; i < __instance.farmTypeButtons.Count; i++)
{
buttons.Add(__instance.farmTypeButtons[i], ((i == Game1.whichFarm) ? "Selected " : "") + getFarmHoverText(__instance.farmTypeButtons[i]));
}
}
if (__instance.farmTypeNextPageButton != null && __instance.farmTypeNextPageButton.visible)
buttons.Add(__instance.farmTypeNextPageButton, "Next Farm Type Page Button");
if (__instance.farmTypePreviousPageButton != null && __instance.farmTypePreviousPageButton.visible)
buttons.Add(__instance.farmTypePreviousPageButton, "Previous Farm Type Page Button");
#endregion
#region Co-op related
if (__instance.source == Source.HostNewFarm)
{
ClickableComponent cabinLeft = __instance.getComponentWithID(621);
if (Game1.startingCabins > 0)
buttons.Add(cabinLeft, "Decrease starting cabins button");
buttons.Add(___startingCabinsLabel, $"Starting cabins: {Game1.startingCabins}");
ClickableComponent cabinRight = __instance.getComponentWithID(622);
if (Game1.startingCabins < 3)
buttons.Add(cabinRight, "Increase starting cabins button");
if (Game1.startingCabins > 0)
{
buttons.Add(__instance.cabinLayoutButtons[0], "Cabin layout to nearby Button");
buttons.Add(__instance.cabinLayoutButtons[1], "Cabin layout to separate Button");
}
ClickableComponent difficultyLeft = __instance.getComponentWithID(627);
buttons.Add(difficultyLeft, "Increase profit margin button");
buttons.Add(___difficultyModifierLabel, "Profit Margin: " + (((Game1.player.difficultyModifier * 100) == 100f) ? "normal" : Game1.player.difficultyModifier.ToString()));
ClickableComponent difficultyRight = __instance.getComponentWithID(628);
buttons.Add(difficultyRight, "Decrease profit margin button");
ClickableComponent walletLeft = __instance.getComponentWithID(631);
buttons.Add(walletLeft, "Money style to " + ((!Game1.player.team.useSeparateWallets.Value) ? "separate wallets" : "shared wallets") + " button");
}
#endregion
if (__instance.skipIntroButton != null && __instance.skipIntroButton.visible)
buttons.Add(__instance.skipIntroButton, (___skipIntro ? "Enabled" : "Disabled") + " Skip Intro Button");
if (__instance.advancedOptionsButton != null && __instance.advancedOptionsButton.visible)
buttons.Add(__instance.advancedOptionsButton, "Advanced Options Button");
if (__instance.okButton != null && __instance.okButton.visible)
buttons.Add(__instance.okButton, "OK Button");
if (__instance.backButton != null && __instance.backButton.visible)
buttons.Add(__instance.backButton, "Back Button");
#endregion
int size = buttons.Count - 1;
if (increase)
{
saveGameIndex++;
if (saveGameIndex > size)
saveGameIndex = 0;
}
else
{
saveGameIndex--;
if (saveGameIndex < 0)
saveGameIndex = size;
}
currentComponent = buttons.ElementAt(saveGameIndex).Key;
currentComponent!.snapMouseCursor();
__instance.setCurrentlySnappedComponentTo(currentComponent!.myID);
toSpeak = buttons.ElementAt(saveGameIndex).Value;
return toSpeak.Trim();
}
private static SliderBar? getCurrentSliderBar(int id, CharacterCustomization __instance)
{
if (id >= 522 && id <= 530)
{
// Three ColorPickers with 3 SliderBars each.
// First group ids by ColorPicker.
// Maps 522-524 -> 0, 525-527 -> 1, 528-530 -> 2
int whichColorPicker = (int)Math.Floor(((float)id - 522f) / 3f);
// Next group ids by slider type.
// Maps [522,525,528] -> 0, [523,526,529] -> 1, [524,527,530] -> 2
int whichSliderBar = (int)Math.Floor((float)id % 3f);
ColorPicker cp;
switch (whichColorPicker)
{
default:
case 0:
// 522-524 == eye color
cp = __instance.eyeColorPicker;
break;
case 1:
// 525-527 == hair color
cp = __instance.hairColorPicker;
break;
case 2:
// 528-530 == pants color
cp = __instance.pantsColorPicker;
break;
}
SliderBar sb;
switch (whichSliderBar)
{
default:
case 0:
// 522, 525, 528 == hue slider
sb = cp.hueBar;
break;
case 1:
// 523, 526, 529 == saturation slider
sb = cp.saturationBar;
break;
case 2:
// 524, 527, 530 == value slider
sb = cp.valueBar;
break;
}
return sb;
} else {
return null;
}
}
private static void AdjustCurrentSlider(bool increase, CharacterCustomization __instance, int amount=1)
{
if (currentComponent != null && currentComponent.myID >= 522 && currentComponent.myID <= 530)
{
SliderBar sb = getCurrentSliderBar(currentComponent.myID, __instance) !;
if (sb != null)
{
double step = ((double)sb.bounds.Width / 100d); // size of 1% change in slider value
double value = (double)sb.value;
double x = 0d;
int y = currentComponent.bounds.Center.Y;
if (increase)
{
value = Math.Min(value + amount, 99d);
x = Math.Min(Math.Ceiling((value * step)), (double)sb.bounds.Width);
} else {
value = Math.Max(value - amount, 0d);
x = Math.Max(Math.Ceiling((value * step)), 0d);
}
x += (double)currentComponent.bounds.Left;
Game1.setMousePosition((int)x, y);
Game1.activeClickableMenu.receiveLeftClick((int)x, y);
}
}
}
// Most values (exception noted below) are 0 indexed internally but visually start from 1. Thus we increment before returning.
private static string getCurrentSkin()
{
if (currentComponent != null && (currentComponent.myID == 507 || currentComponent.name == "Skin"))
return $"Skin tone: {Game1.player.skin.Value + 1}";
return "";
}
private static string getCurrentHair()
{
if (currentComponent != null && (currentComponent.myID == 507 || currentComponent.name == "Hair"))
return $"hair style: {Game1.player.hair.Value + 1}";
return "";
}
private static string getCurrentShirt()
{
if (currentComponent != null && (currentComponent.myID == 507 || currentComponent.name == "Shirt"))
return $"Shirt: {Game1.player.shirt.Value + 1}";
return "";
}
private static string getCurrentPants()
{
if (currentComponent != null && (currentComponent.myID == 507 || currentComponent.name == "Pants Style"))
return $"Pants: {Game1.player.pants.Value + 1}";
return "";
}
private static string getCurrentAccessory()
{
// Internally accessory starts from -1 while displaying +1 on screen.
if (currentComponent != null && (currentComponent.myID == 507 || currentComponent.name == "Acc"))
return $"accessory: {Game1.player.accessory.Value + 2}";
return "";
}
private static string getCurrentEyeColor()
{
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 522 && currentComponent.myID <= 524)))
return $"Eye color: {Game1.player.newEyeColor.R}, {Game1.player.newEyeColor.G}, {Game1.player.newEyeColor.B}";
return "";
}
private static string getCurrentEyeColorHue(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(522, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 522 && currentComponent.myID <= 524)))
return sb.value!.ToString();
return "";
}
private static string getCurrentEyeColorSaturation(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(523, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 522 && currentComponent.myID <= 524)))
return sb.value!.ToString();
return "";
}
private static string getCurrentEyeColorValue(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(524, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 522 && currentComponent.myID <= 524)))
return sb.value!.ToString();
return "";
}
private static string getCurrentHairColor()
{
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 525 && currentComponent.myID <= 527)))
return $"Hair color: {Game1.player.hairstyleColor.R}, {Game1.player.hairstyleColor.G}, {Game1.player.hairstyleColor.B}";
return "";
}
private static string getCurrentHairColorHue(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(525, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 525 && currentComponent.myID <= 527)))
return sb.value!.ToString();
return "";
}
private static string getCurrentHairColorSaturation(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(526, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 525 && currentComponent.myID <= 527)))
return sb.value!.ToString();
return "";
}
private static string getCurrentHairColorValue(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(527, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 525 && currentComponent.myID <= 527)))
return sb.value!.ToString();
return "";
}
private static string getCurrentPantsColor()
{
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 528 && currentComponent.myID <= 530)))
return $"Pants color: {Game1.player.pantsColor.R}, {Game1.player.pantsColor.G}, {Game1.player.pantsColor.B}";
return "";
}
private static string getCurrentPantsColorHue(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(528, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 528 && currentComponent.myID <= 530)))
return sb.value!.ToString();
return "";
}
private static string getCurrentPantsColorSaturation(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(529, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 528 && currentComponent.myID <= 530)))
return sb.value!.ToString();
return "";
}
private static string getCurrentPantsColorValue(CharacterCustomization __instance)
{
SliderBar sb = getCurrentSliderBar(530, __instance)!;
if (currentComponent != null && (currentComponent.myID == 507 || (currentComponent.myID >= 528 && currentComponent.myID <= 530)))
return sb.value!.ToString();
return "";
}
private static string getCurrentPetName()
{
if (currentComponent != null && currentComponent.name == "Pet")
{
return ((Game1.player.catPerson) ? "Cat" : "Dog") + " Breed: " + Game1.player.whichPetBreed;
} else {
return "";
}
}
private static string getFarmHoverText(ClickableTextureComponent farm)
{
string hoverTitle = " ", hoverText = " ";
if (!farm.name.Contains("Gray"))
{
if (farm.hoverText.Contains('_'))
{
hoverTitle = farm.hoverText.Split('_')[0];
hoverText = farm.hoverText.Split('_')[1];
}
else
{
hoverTitle = " ";
hoverText = farm.hoverText;
}
}
else
{
if (farm.name.Contains("Gray"))
{
hoverText = "Reach level 10 " + Game1.content.LoadString("Strings\\UI:Character_" + farm.name.Split('_')[1]) + " to unlock.";
}
}
return $"{hoverTitle}: {hoverText}";
}
} }
} }