678 lines
25 KiB
C#
678 lines
25 KiB
C#
using Microsoft.Xna.Framework;
|
|
using StardewModdingAPI;
|
|
using StardewValley;
|
|
using StardewValley.Menus;
|
|
using static StardewValley.Menus.LoadGameMenu;
|
|
|
|
namespace stardew_access.Patches
|
|
{
|
|
internal class TitleMenuPatches
|
|
{
|
|
private static int saveGameIndex = -1;
|
|
private static bool isRunning = false;
|
|
private const int MAX_COMPONENTS = 20;
|
|
|
|
internal static void CoopMenuPatch(CoopMenu __instance, CoopMenu.Tab ___currentTab)
|
|
{
|
|
try
|
|
{
|
|
int x = Game1.getMouseX(), y = Game1.getMouseY();
|
|
string toSpeak = " ";
|
|
|
|
#region Join/Host Button (Important! This should be checked before checking other buttons)
|
|
if (__instance.slotButtons[0].containsPoint(x, y))
|
|
{
|
|
if (___currentTab == CoopMenu.Tab.JOIN_TAB)
|
|
toSpeak = "Join lan game";
|
|
if (___currentTab == CoopMenu.Tab.HOST_TAB)
|
|
toSpeak = "Host new farm";
|
|
}
|
|
#endregion
|
|
|
|
#region Other Buttons
|
|
if (__instance.joinTab.containsPoint(x, y))
|
|
{
|
|
toSpeak = "Join Tab Button";
|
|
}
|
|
else if (__instance.hostTab.containsPoint(x, y))
|
|
{
|
|
toSpeak = "Host Tab Button";
|
|
}
|
|
else if (__instance.refreshButton.containsPoint(x, y))
|
|
{
|
|
toSpeak = "Refresh Button";
|
|
}
|
|
#endregion
|
|
|
|
if (toSpeak != " ")
|
|
MainClass.ScreenReader.SayWithChecker(toSpeak, true);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MainClass.Monitor.Log($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}", LogLevel.Error);
|
|
}
|
|
}
|
|
|
|
internal static void TitleMenuPatch(TitleMenu __instance, bool ___isTransitioningButtons)
|
|
{
|
|
try
|
|
{
|
|
if (___isTransitioningButtons)
|
|
return;
|
|
|
|
string toSpeak = "";
|
|
|
|
__instance.buttons.ForEach(component =>
|
|
{
|
|
if (component.containsPoint(Game1.getMouseX(), Game1.getMouseY()))
|
|
{
|
|
string name = component.name;
|
|
string label = component.label;
|
|
toSpeak = $"{name} {label} Button";
|
|
}
|
|
});
|
|
|
|
if (__instance.muteMusicButton.containsPoint(Game1.getMouseX(), Game1.getMouseY()))
|
|
{
|
|
toSpeak = "Mute Music Button";
|
|
}
|
|
|
|
if (__instance.aboutButton.containsPoint(Game1.getMouseX(), Game1.getMouseY()))
|
|
{
|
|
toSpeak = "About Button";
|
|
}
|
|
|
|
if (__instance.languageButton.containsPoint(Game1.getMouseX(), Game1.getMouseY()))
|
|
{
|
|
toSpeak = "Language Button";
|
|
}
|
|
|
|
if (__instance.windowedButton.containsPoint(Game1.getMouseX(), Game1.getMouseY()))
|
|
{
|
|
toSpeak = "Fullscreen toggle Button";
|
|
}
|
|
|
|
if (TitleMenu.subMenu != null && __instance.backButton.containsPoint(Game1.getMouseX(), Game1.getMouseY()))
|
|
{
|
|
string text = "Back Button";
|
|
MainClass.ScreenReader.SayWithChecker(text, true);
|
|
}
|
|
|
|
if (TitleMenu.subMenu == null && toSpeak != "")
|
|
MainClass.ScreenReader.SayWithChecker(toSpeak, true);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MainClass.Monitor.Log($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}", LogLevel.Error);
|
|
}
|
|
}
|
|
|
|
internal static void LoadGameMenuPatch(SaveFileSlot __instance, LoadGameMenu ___menu, int i)
|
|
{
|
|
try
|
|
{
|
|
int x = Game1.getMouseX(), y = Game1.getMouseY();
|
|
if (___menu.slotButtons[i].containsPoint(x, y))
|
|
{
|
|
if (__instance.Farmer != null)
|
|
{
|
|
#region Farms
|
|
if (___menu.deleteButtons.Count > 0 && ___menu.deleteButtons[i].containsPoint(x, y))
|
|
{
|
|
MainClass.ScreenReader.SayWithChecker($"Delete {__instance.Farmer.farmName} Farm", true);
|
|
return;
|
|
}
|
|
|
|
if (___menu.deleteConfirmationScreen)
|
|
{
|
|
// Used diff. functions to narrate to prevent it from speaking the message again on selecting another button.
|
|
string message = "Really delete farm?";
|
|
|
|
MainClass.ScreenReader.SayWithChecker(message, true);
|
|
if (___menu.okDeleteButton.containsPoint(x, y))
|
|
{
|
|
MainClass.ScreenReader.SayWithMenuChecker("Ok Button", false);
|
|
}
|
|
else if (___menu.cancelDeleteButton.containsPoint(x, y))
|
|
{
|
|
MainClass.ScreenReader.SayWithMenuChecker("Cancel Button", false);
|
|
}
|
|
return;
|
|
}
|
|
|
|
String farmerName = __instance.Farmer.displayName;
|
|
String farmName = __instance.Farmer.farmName;
|
|
String money = __instance.Farmer.Money.ToString();
|
|
String hoursPlayed = Utility.getHoursMinutesStringFromMilliseconds(__instance.Farmer.millisecondsPlayed);
|
|
string dateStringForSaveGame = ((!__instance.Farmer.dayOfMonthForSaveGame.HasValue ||
|
|
!__instance.Farmer.seasonForSaveGame.HasValue ||
|
|
!__instance.Farmer.yearForSaveGame.HasValue) ? __instance.Farmer.dateStringForSaveGame : Utility.getDateStringFor(__instance.Farmer.dayOfMonthForSaveGame.Value, __instance.Farmer.seasonForSaveGame.Value, __instance.Farmer.yearForSaveGame.Value));
|
|
|
|
string toSpeak = $"{farmName} Farm Selected, \t\n Farmer:{farmerName}, \t\nMoney:{money}, \t\nHours Played:{hoursPlayed}, \t\nDate:{dateStringForSaveGame}";
|
|
|
|
MainClass.ScreenReader.SayWithChecker(toSpeak, true);
|
|
#endregion
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MainClass.Monitor.Log($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}", LogLevel.Error);
|
|
}
|
|
}
|
|
|
|
internal static void NewGameMenuPatch(CharacterCustomization __instance, bool ___skipIntro)
|
|
{
|
|
try
|
|
{
|
|
bool isNextArrowPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Right);
|
|
bool isPrevArrowPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Left);
|
|
|
|
if (isNextArrowPressed && !isRunning)
|
|
{
|
|
_ = CycleThroughItems(true, __instance, ___skipIntro);
|
|
}
|
|
else if (isPrevArrowPressed && !isRunning)
|
|
{
|
|
_ = CycleThroughItems(false, __instance, ___skipIntro);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MainClass.Monitor.Log($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}", LogLevel.Error);
|
|
}
|
|
}
|
|
|
|
private static async Task CycleThroughItems(bool increase, CharacterCustomization __instance, bool ___skipIntro)
|
|
{
|
|
isRunning = true;
|
|
string toSpeak = " ";
|
|
|
|
if (increase)
|
|
{
|
|
saveGameIndex++;
|
|
if (saveGameIndex > MAX_COMPONENTS)
|
|
saveGameIndex = 1;
|
|
}
|
|
else
|
|
{
|
|
saveGameIndex--;
|
|
if (saveGameIndex < 1)
|
|
saveGameIndex = MAX_COMPONENTS;
|
|
}
|
|
|
|
|
|
switch (saveGameIndex)
|
|
{
|
|
case 1:
|
|
{
|
|
#region Skip if button is not available
|
|
if (!__instance.nameBoxCC.visible)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 2;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case MAX_COMPONENTS;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.nameBoxCC.snapMouseCursorToCenter();
|
|
toSpeak = "Enter Farmer's Name";
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
{
|
|
#region Skip if button is not available
|
|
if (!__instance.farmnameBoxCC.visible)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 3;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 1;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmnameBoxCC.snapMouseCursorToCenter();
|
|
toSpeak = "Enter Farm's Name";
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
#region Skip if button is not available
|
|
if (!__instance.favThingBoxCC.visible)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 4;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 2;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.favThingBoxCC.snapMouseCursorToCenter();
|
|
toSpeak = "Enter Favourite Thing";
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
#region Skip if button is not available
|
|
if (!__instance.skipIntroButton.visible)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 5;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 3;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.skipIntroButton.snapMouseCursor();
|
|
toSpeak = (___skipIntro ? "Enabled" : "Disabled") + " Skip Intro Button";
|
|
}
|
|
break;
|
|
case 5:
|
|
{
|
|
#region Skip if button is not available
|
|
if (!__instance.randomButton.visible)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 6;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 5;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.randomButton.snapMouseCursor();
|
|
toSpeak = "Random Skin Button";
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.genderButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 8;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 6;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.genderButtons[0].snapMouseCursor();
|
|
toSpeak = "Gender Male Button";
|
|
break;
|
|
}
|
|
case 7:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.genderButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 8;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 6;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.genderButtons[1].snapMouseCursor();
|
|
toSpeak = "Gender Female Button";
|
|
break;
|
|
}
|
|
case 8:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 9;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 7;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[0].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[0]);
|
|
break;
|
|
}
|
|
case 9:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 10;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 8;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[1].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[1]);
|
|
break;
|
|
}
|
|
case 10:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 11;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 9;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[2].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[2]);
|
|
break;
|
|
}
|
|
case 11:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 12;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 10;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[3].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[3]);
|
|
break;
|
|
}
|
|
case 12:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 13;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 11;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[4].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[4]);
|
|
break;
|
|
}
|
|
case 13:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 14;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 12;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[5].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[5]);
|
|
break;
|
|
}
|
|
case 14:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 15;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 13;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeButtons[6].snapMouseCursor();
|
|
toSpeak = getFarmHoverText(__instance.farmTypeButtons[6]);
|
|
break;
|
|
}
|
|
case 15:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypeNextPageButton == null)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 16;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 14;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypeNextPageButton.snapMouseCursor();
|
|
toSpeak = "Next Farm Type Page Button";
|
|
break;
|
|
}
|
|
case 16:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.farmTypePreviousPageButton == null)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 17;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 15;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.farmTypePreviousPageButton.snapMouseCursor();
|
|
toSpeak = "Previous Farm Type Page Button";
|
|
break;
|
|
}
|
|
case 17:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.cabinLayoutButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 18;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 16;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.cabinLayoutButtons[0].snapMouseCursor();
|
|
toSpeak = "Cabin layout nearby";
|
|
break;
|
|
}
|
|
case 18:
|
|
{
|
|
#region Skip if button is not available
|
|
if (__instance.cabinLayoutButtons.Count <= 0)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 19;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 17;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.cabinLayoutButtons[1].snapMouseCursor();
|
|
toSpeak = "Cabin layout separate";
|
|
break;
|
|
}
|
|
case 19:
|
|
{
|
|
#region Skip if button is not available
|
|
if (!__instance.okButton.visible)
|
|
{
|
|
if (increase)
|
|
{
|
|
++saveGameIndex;
|
|
goto case 18;
|
|
}
|
|
else
|
|
{
|
|
--saveGameIndex;
|
|
goto case 20;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
__instance.okButton.snapMouseCursor();
|
|
toSpeak = "Ok Button";
|
|
}
|
|
break;
|
|
case 20:
|
|
{
|
|
#region Exit if button is not available
|
|
if (!__instance.backButton.visible)
|
|
{
|
|
break;
|
|
}
|
|
#endregion
|
|
|
|
__instance.backButton.snapMouseCursor();
|
|
toSpeak = "Back Button";
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (toSpeak != " ")
|
|
{
|
|
MainClass.ScreenReader.Say(toSpeak, true);
|
|
}
|
|
|
|
await Task.Delay(200);
|
|
isRunning = false;
|
|
}
|
|
|
|
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}";
|
|
}
|
|
}
|
|
}
|