stardew-access/stardew-access/ModEntry.cs

288 lines
11 KiB
C#
Raw Normal View History

using stardew_access.Game;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using HarmonyLib;
2021-12-07 14:32:15 +00:00
using StardewValley.Menus;
using Microsoft.Xna.Framework.Graphics;
using stardew_access.Patches;
using AutoHotkey.Interop;
2021-12-14 18:21:11 +00:00
using Microsoft.Xna.Framework;
using StardewValley.TerrainFeatures;
namespace stardew_access
{
public class MainClass : Mod
{
private Harmony? harmony;
2021-12-15 14:28:25 +00:00
private static bool isReadingTile = false, readTile = false, snapMouse = true;
2021-12-15 13:56:18 +00:00
private static Vector2 prevTile;
public static IMonitor? monitor;
AutoHotkeyEngine ahk;
/*********
** Public methods
*********/
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
#region Initializations
2021-12-14 18:21:11 +00:00
monitor = Monitor; // Inititalize monitor
Game1.options.setGamepadMode("force_on");
// Initialize AutoHotKey
try
{
ahk = AutoHotkeyEngine.Instance;
ahk.ExecRaw("[::\nSend {LButton}");
ahk.ExecRaw("]::\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
2021-12-14 18:21:11 +00:00
harmony = new Harmony(ModManifest.UniqueID); // Init harmony
#endregion
#region Harmony Patches
harmony.Patch(
original: AccessTools.Method(typeof(DialogueBox), nameof(DialogueBox.draw), new Type[] { typeof(SpriteBatch) }),
2021-12-10 18:05:04 +00:00
postfix: new HarmonyMethod(typeof(DialoguePatcher), nameof(DialoguePatcher.DialoguePatch))
);
harmony.Patch(
original: AccessTools.Method(typeof(DialogueBox), nameof(DialogueBox.receiveLeftClick)),
postfix: new HarmonyMethod(typeof(DialoguePatcher), nameof(DialoguePatcher.ClearDialogueString))
);
harmony.Patch(
original: AccessTools.Method(typeof(IClickableMenu), nameof(IClickableMenu.drawHoverText), new Type[] { typeof(SpriteBatch), typeof(string), typeof(SpriteFont), typeof(int), typeof(int), typeof(int), typeof(string), typeof(int), typeof(string[]), typeof(Item), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(float), typeof(CraftingRecipe), typeof(IList<Item>) }),
2021-12-10 18:05:04 +00:00
postfix: new HarmonyMethod(typeof(DialoguePatcher), nameof(DialoguePatcher.HoverTextPatch))
2021-12-09 10:15:07 +00:00
);
harmony.Patch(
original: AccessTools.Method(typeof(TitleMenu), nameof(TitleMenu.draw), new Type[] { typeof(SpriteBatch) }),
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.TitleMenuPatch))
);
harmony.Patch(
original: AccessTools.Method(typeof(LoadGameMenu.SaveFileSlot), nameof(LoadGameMenu.SaveFileSlot.Draw), new Type[] { typeof(SpriteBatch), typeof(int) }),
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.LoadGameMenuPatch))
);
harmony.Patch(
original: AccessTools.Method(typeof(ExitPage), nameof(ExitPage.draw), new Type[] { typeof(SpriteBatch) }),
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))
);
harmony.Patch(
original: AccessTools.Method(typeof(LetterViewerMenu), nameof(LetterViewerMenu.draw), new Type[] { typeof(SpriteBatch) }),
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.LetterViewerMenuPatch))
);
2021-12-13 15:30:07 +00:00
harmony.Patch(
original: AccessTools.Method(typeof(QuestLog), nameof(QuestLog.draw), new Type[] { typeof(SpriteBatch) }),
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.QuestLogPatch))
);
harmony.Patch(
original: AccessTools.Method(typeof(Billboard), nameof(Billboard.draw), new Type[] { typeof(SpriteBatch) }),
postfix: new HarmonyMethod(typeof(MenuPatch), nameof(MenuPatch.BillboardPatch))
);
#endregion
2021-12-10 18:05:04 +00:00
#region Custom Commands
helper.ConsoleCommands.Add("read_tile", "Toggle read tile feature", (string arg1, string[] arg2) =>
{
readTile = !readTile;
monitor.Log("Read Tile is " + (readTile ? "on" : "off"), LogLevel.Info);
});
helper.ConsoleCommands.Add("snap_mouse", "Toggle snap mouse feature", (string arg1, string[] arg2) =>
{
snapMouse = !snapMouse;
monitor.Log("Snap Mouse is " + (snapMouse ? "on" : "off"), LogLevel.Info);
});
#endregion
helper.Events.Input.ButtonPressed += this.OnButtonPressed;
helper.Events.GameLoop.UpdateTicked += this.onUpdateTicked;
}
private void onUpdateTicked(object sender, UpdateTickedEventArgs e)
{
if (!Context.IsPlayerFree)
return;
MenuPatch.resetGlobalVars();
2021-12-15 13:56:18 +00:00
if(snapMouse)
SnapMouseToPlayer();
2021-12-15 14:15:19 +00:00
if(!isReadingTile && readTile)
2021-12-15 13:56:18 +00:00
ReadTile();
}
private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
{
if (Game1.activeClickableMenu == null)
{
// Narrate health and stamina
if (Equals(e.Button, SButton.H))
{
string toSpeak = $"Health is {CurrentPlayer.getHealth()} and Stamina is {CurrentPlayer.getStamina()}";
ScreenReader.say(toSpeak, true);
}
// Narrate Position
if (Equals(e.Button, SButton.K))
{
string toSpeak = $"X: {CurrentPlayer.getPositionX()} , Y: {CurrentPlayer.getPositionY()}";
ScreenReader.say(toSpeak, true);
}
if (Equals(e.Button, SButton.J))
{
Game1.pressActionButton(Game1.input.GetKeyboardState(), Game1.input.GetMouseState(), Game1.input.GetGamePadState());
}
2021-12-14 18:21:11 +00:00
if (Equals(e.Button, SButton.L))
{
Game1.pressUseToolButton();
}
2021-12-15 13:56:18 +00:00
}
}
2021-12-14 18:21:11 +00:00
2021-12-15 14:15:19 +00:00
private void SnapMouseToPlayer()
{
int x = Game1.player.GetBoundingBox().Center.X - Game1.viewport.X;
int y = Game1.player.GetBoundingBox().Center.Y - Game1.viewport.Y;
2021-12-15 17:28:49 +00:00
int offset = 64;
switch (Game1.player.FacingDirection)
{
case 0:
y -= offset;
break;
case 1:
x += offset;
break;
case 2:
y += offset;
break;
case 3:
x -= offset;
break;
}
2021-12-15 14:15:19 +00:00
Game1.setMousePosition(x, y);
}
2021-12-15 13:56:18 +00:00
private static async void ReadTile()
{
isReadingTile = true;
2021-12-15 17:28:49 +00:00
try
2021-12-15 13:56:18 +00:00
{
2021-12-15 17:28:49 +00:00
#region Get Correct Grab Tile
int x = Game1.player.GetBoundingBox().Center.X;
int y = Game1.player.GetBoundingBox().Center.Y;
int offset = 64;
switch (Game1.player.FacingDirection)
2021-12-14 18:21:11 +00:00
{
2021-12-15 17:28:49 +00:00
case 0:
y -= offset;
break;
case 1:
x += offset;
break;
case 2:
y += offset;
break;
case 3:
x -= offset;
break;
}
2021-12-14 18:21:11 +00:00
2021-12-15 17:28:49 +00:00
x /= Game1.tileSize;
y /= Game1.tileSize;
Vector2 gt = new Vector2(x, y);
#endregion
2021-12-14 18:21:11 +00:00
2021-12-15 17:28:49 +00:00
if (Context.IsPlayerFree)
{
Dictionary<Vector2, Netcode.NetRef<TerrainFeature>> terrainFeature = Game1.currentLocation.terrainFeatures.FieldDict;
2021-12-14 18:21:11 +00:00
2021-12-15 17:28:49 +00:00
StardewValley.Object obj = Game1.currentLocation.getObjectAtTile((int)gt.X, (int)gt.Y);
if (!Equals(gt, prevTile))
2021-12-15 13:56:18 +00:00
{
2021-12-15 17:28:49 +00:00
prevTile = gt;
if (obj != null)
{
string name = obj.name;
ScreenReader.say(name, true);
2021-12-15 13:56:18 +00:00
2021-12-15 17:28:49 +00:00
}
else if (terrainFeature.ContainsKey(gt))
2021-12-15 13:56:18 +00:00
{
2021-12-15 17:28:49 +00:00
Netcode.NetRef<TerrainFeature> terrain = terrainFeature[gt];
if (terrain.Get() is HoeDirt)
2021-12-14 18:21:11 +00:00
{
2021-12-15 17:28:49 +00:00
HoeDirt dirt = (HoeDirt)terrain.Get();
if (dirt.crop != null)
{
string cropName = Game1.objectInformation[dirt.crop.indexOfHarvest];
cropName = cropName.Substring(0, cropName.IndexOf("/"));
string toSpeak = $"{cropName}";
bool isWatered = dirt.state.Value == HoeDirt.watered;
bool isHarvestable = dirt.crop.fullyGrown.Get();
if(isWatered)
toSpeak = "Watered " + toSpeak;
2021-12-14 18:21:11 +00:00
2021-12-15 17:28:49 +00:00
if (isHarvestable)
toSpeak = "Harvestable " + toSpeak;
ScreenReader.say(toSpeak, true);
}
2021-12-15 13:56:18 +00:00
}
2021-12-15 17:28:49 +00:00
}
2021-12-14 18:21:11 +00:00
}
2021-12-15 13:56:18 +00:00
}
}
2021-12-15 17:28:49 +00:00
catch (Exception e)
{
monitor.Log($"Error in Read Tile:\n{e.Message}\n{e.StackTrace}");
}
2021-12-15 13:56:18 +00:00
await Task.Delay(100);
isReadingTile = false;
}
}
}