Added mouse clicks via keyboard and made new game menu kinda accessible
parent
3591c2cec6
commit
099f5b02e1
|
@ -6,6 +6,7 @@ using HarmonyLib;
|
||||||
using StardewValley.Menus;
|
using StardewValley.Menus;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using stardew_access.Patches;
|
using stardew_access.Patches;
|
||||||
|
using AutoHotkey.Interop;
|
||||||
|
|
||||||
namespace stardew_access
|
namespace stardew_access
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ namespace stardew_access
|
||||||
{
|
{
|
||||||
private Harmony? harmony;
|
private Harmony? harmony;
|
||||||
public static IMonitor? monitor;
|
public static IMonitor? monitor;
|
||||||
|
AutoHotkeyEngine ahk;
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** Public methods
|
** Public methods
|
||||||
|
@ -23,12 +25,27 @@ namespace stardew_access
|
||||||
public override void Entry(IModHelper helper)
|
public override void Entry(IModHelper helper)
|
||||||
{
|
{
|
||||||
#region Initializations
|
#region Initializations
|
||||||
// Inititalize monitor
|
|
||||||
monitor = Monitor;
|
monitor = Monitor; // Inititalize monitor
|
||||||
// Initialize the screen reader
|
Game1.options.setGamepadMode("force_on");
|
||||||
ScreenReader.initializeScreenReader();
|
|
||||||
// Init harmony
|
// Initialize AutoHotKey
|
||||||
harmony = new Harmony(ModManifest.UniqueID);
|
try
|
||||||
|
{
|
||||||
|
ahk = AutoHotkeyEngine.Instance;
|
||||||
|
ahk.ExecRaw("^j::\nSend {LButton}");
|
||||||
|
ahk.ExecRaw("^l::\nSend {RButton}");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
monitor.Log($"Unable to initialize AutoHotKey:\n{e.Message}\n{e.StackTrace}", LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenReader.initializeScreenReader(); // Initialize the screen reader
|
||||||
|
|
||||||
|
harmony = new Harmony(ModManifest.UniqueID); // Init harmony
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Harmony Patches
|
#region Harmony Patches
|
||||||
|
@ -63,6 +80,11 @@ namespace stardew_access
|
||||||
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.ExitPagePatch))
|
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.ExitPagePatch))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
harmony.Patch(
|
||||||
|
original: AccessTools.Method(typeof(CharacterCustomization), nameof(CharacterCustomization.draw), new Type[] { typeof(SpriteBatch) }),
|
||||||
|
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.NewGameMenuPatch))
|
||||||
|
);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
helper.Events.Input.ButtonPressed += this.OnButtonPressed;
|
helper.Events.Input.ButtonPressed += this.OnButtonPressed;
|
||||||
|
@ -70,12 +92,10 @@ namespace stardew_access
|
||||||
|
|
||||||
private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
|
private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
|
||||||
{
|
{
|
||||||
// ignore if player hasn't loaded a save yet
|
if (Game1.activeClickableMenu == null)
|
||||||
if (!Context.IsWorldReady)
|
{
|
||||||
return;
|
// Narrate health and stamina
|
||||||
|
if (Equals(e.Button, SButton.H))
|
||||||
// Narrate Health And Energy
|
|
||||||
if (Equals(e.Button, SButton.I))
|
|
||||||
{
|
{
|
||||||
string toSpeak = $"Health is {CurrentPlayer.getHealth()} and Stamina is {CurrentPlayer.getStamina()}";
|
string toSpeak = $"Health is {CurrentPlayer.getHealth()} and Stamina is {CurrentPlayer.getStamina()}";
|
||||||
ScreenReader.say(toSpeak, true);
|
ScreenReader.say(toSpeak, true);
|
||||||
|
@ -87,6 +107,17 @@ namespace stardew_access
|
||||||
string toSpeak = $"X: {CurrentPlayer.getPositionX()} , Y: {CurrentPlayer.getPositionX()}";
|
string toSpeak = $"X: {CurrentPlayer.getPositionX()} , Y: {CurrentPlayer.getPositionX()}";
|
||||||
ScreenReader.say(toSpeak, true);
|
ScreenReader.say(toSpeak, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Equals(e.Button, SButton.J))
|
||||||
|
{
|
||||||
|
Game1.pressActionButton(Game1.input.GetKeyboardState(), Game1.input.GetMouseState(), Game1.input.GetGamePadState());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Equals(e.Button, SButton.L))
|
||||||
|
{
|
||||||
|
Game1.pressUseToolButton();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace stardew_access.Patches
|
||||||
string speakerName = dialogue.speaker.Name;
|
string speakerName = dialogue.speaker.Name;
|
||||||
List<string> dialogues = dialogue.dialogues;
|
List<string> dialogues = dialogue.dialogues;
|
||||||
int dialogueIndex = dialogue.currentDialogueIndex;
|
int dialogueIndex = dialogue.currentDialogueIndex;
|
||||||
MainClass.monitor.Log("" + dialogue.isCurrentStringContinuedOnNextScreen, LogLevel.Debug);
|
|
||||||
string toSpeak = $"{speakerName} said, {dialogues[dialogueIndex]}";
|
string toSpeak = $"{speakerName} said, {dialogues[dialogueIndex]}";
|
||||||
|
|
||||||
if (currentDialogue != toSpeak)
|
if (currentDialogue != toSpeak)
|
||||||
|
@ -138,7 +137,6 @@ namespace stardew_access.Patches
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int count = int.Parse(buffName.Substring(0, buffName.IndexOf(' ')));
|
int count = int.Parse(buffName.Substring(0, buffName.IndexOf(' ')));
|
||||||
MainClass.monitor.Log("" + count);
|
|
||||||
if (count != 0)
|
if (count != 0)
|
||||||
toSpeak.Append($"{buffName}\n");
|
toSpeak.Append($"{buffName}\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using StardewModdingAPI;
|
using Microsoft.Xna.Framework;
|
||||||
|
using StardewModdingAPI;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
using StardewValley.Menus;
|
using StardewValley.Menus;
|
||||||
|
|
||||||
|
@ -6,6 +7,8 @@ namespace stardew_access.Patches
|
||||||
{
|
{
|
||||||
internal class MenuPatch
|
internal class MenuPatch
|
||||||
{
|
{
|
||||||
|
private static int saveGameIndex = -1;
|
||||||
|
private static bool isRunning = false;
|
||||||
|
|
||||||
internal static void TitleMenuPatch(TitleMenu __instance)
|
internal static void TitleMenuPatch(TitleMenu __instance)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +96,95 @@ namespace stardew_access.Patches
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void NewGameMenuPatch(CharacterCustomization __instance, TextBox ___nameBox, TextBox ___farmnameBox, TextBox ___favThingBox, ClickableTextureComponent ___skipIntroButton, ClickableTextureComponent ___okButton, ClickableComponent ___backButton)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (__instance.source != CharacterCustomization.Source.NewGame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
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, ___nameBox, ___farmnameBox, ___favThingBox, ___skipIntroButton, ___okButton, ___backButton);
|
||||||
|
}
|
||||||
|
else if (isPrevArrowPressed && !isRunning)
|
||||||
|
{
|
||||||
|
_ = CycleThroughItems(false, ___nameBox, ___farmnameBox, ___favThingBox, ___skipIntroButton, ___okButton, ___backButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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, TextBox ___nameBox, TextBox ___farmnameBox, TextBox ___favThingBox, ClickableTextureComponent ___skipIntroButton, ClickableTextureComponent ___okButton, ClickableComponent ___backButton)
|
||||||
|
{
|
||||||
|
isRunning = true;
|
||||||
|
if (increase)
|
||||||
|
{
|
||||||
|
saveGameIndex++;
|
||||||
|
if (saveGameIndex > 6)
|
||||||
|
saveGameIndex = 0;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
saveGameIndex--;
|
||||||
|
if (saveGameIndex < 0)
|
||||||
|
saveGameIndex = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(200);
|
||||||
|
|
||||||
|
switch (saveGameIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
Rectangle bounds = new Rectangle(___nameBox.X, ___nameBox.Y, ___nameBox.Width, ___nameBox.Height);
|
||||||
|
Game1.input.SetMousePosition(bounds.Center.X, bounds.Center.Y);
|
||||||
|
ScreenReader.say("Enter Farmer's Name", true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Rectangle bounds = new Rectangle(___farmnameBox.X, ___farmnameBox.Y, ___farmnameBox.Width, ___farmnameBox.Height);
|
||||||
|
Game1.input.SetMousePosition(bounds.Center.X, bounds.Center.Y);
|
||||||
|
ScreenReader.say("Enter Farm's Name", true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
Rectangle bounds = new Rectangle(___favThingBox.X, ___favThingBox.Y, ___favThingBox.Width, ___favThingBox.Height);
|
||||||
|
Game1.input.SetMousePosition(bounds.Center.X, bounds.Center.Y);
|
||||||
|
ScreenReader.say("Enter Favourite Thing", true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
___skipIntroButton.snapMouseCursor();
|
||||||
|
ScreenReader.say("Skip Intro Button", true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
___okButton.snapMouseCursor();
|
||||||
|
ScreenReader.say("Ok Button", true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
___backButton.snapMouseCursor();
|
||||||
|
ScreenReader.say("Back Button", true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
internal static void ExitPagePatch(ExitPage __instance)
|
internal static void ExitPagePatch(ExitPage __instance)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
{
|
{
|
||||||
"Name": "Stardew Access",
|
"Name": "Stardew Access",
|
||||||
"Author": "Mohammad Shoaib",
|
"Author": "Mohammad Shoaib",
|
||||||
"Version": "1.0.0",
|
"Version": "1.0.1-beta",
|
||||||
"Description": "<One or two sentences about the mod>",
|
"Description": "An accessibility mod with screen reader support!",
|
||||||
"UniqueID": "shoaib.stardewaccess",
|
"UniqueID": "shoaib.stardewaccess",
|
||||||
"EntryDll": "stardew-access.dll",
|
"EntryDll": "stardew-access.dll",
|
||||||
"MinimumApiVersion": "3.0.0",
|
"MinimumApiVersion": "3.0.0",
|
||||||
"UpdateKeys": []
|
"UpdateKeys": [
|
||||||
|
"Github:stardew-access/stardew-access"
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AccessibleOutput" Version="1.0.0" />
|
<PackageReference Include="AccessibleOutput" Version="1.0.0" />
|
||||||
|
<PackageReference Include="AutoHotkey.Interop" Version="1.0.0.1" />
|
||||||
<PackageReference Include="Lib.Harmony" Version="2.1.1" />
|
<PackageReference Include="Lib.Harmony" Version="2.1.1" />
|
||||||
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="4.0.0" />
|
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="4.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
Loading…
Reference in New Issue