Organised code for donation menu patches
This commit is contained in:
		| @@ -167,11 +167,6 @@ namespace stardew_access | |||||||
|                 postfix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.LanguageSelectionMenuPatch)) |                 postfix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.LanguageSelectionMenuPatch)) | ||||||
|             ); |             ); | ||||||
|  |  | ||||||
|             harmony.Patch( |  | ||||||
|                 original: AccessTools.Method(typeof(MuseumMenu), nameof(MuseumMenu.receiveKeyPress), new Type[] { typeof(Keys) }), |  | ||||||
|                 prefix: new HarmonyMethod(typeof(DonationMenuPatches), nameof(DonationMenuPatches.MuseumMenuKeyPressPatch)) |  | ||||||
|             ); |  | ||||||
|  |  | ||||||
|             harmony.Patch( |             harmony.Patch( | ||||||
|                 original: AccessTools.Method(typeof(ChooseFromListMenu), nameof(ChooseFromListMenu.draw), new Type[] { typeof(SpriteBatch) }), |                 original: AccessTools.Method(typeof(ChooseFromListMenu), nameof(ChooseFromListMenu.draw), new Type[] { typeof(SpriteBatch) }), | ||||||
|                 postfix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.ChooseFromListMenuPatch)) |                 postfix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.ChooseFromListMenuPatch)) | ||||||
| @@ -255,12 +250,17 @@ namespace stardew_access | |||||||
|             #region Donation Menus |             #region Donation Menus | ||||||
|             harmony.Patch( |             harmony.Patch( | ||||||
|                 original: AccessTools.Method(typeof(MuseumMenu), nameof(MuseumMenu.draw), new Type[] { typeof(SpriteBatch) }), |                 original: AccessTools.Method(typeof(MuseumMenu), nameof(MuseumMenu.draw), new Type[] { typeof(SpriteBatch) }), | ||||||
|                 postfix: new HarmonyMethod(typeof(DonationMenuPatches), nameof(DonationMenuPatches.MuseumMenuPatch)) |                 postfix: new HarmonyMethod(typeof(MuseumMenuPatch), nameof(MuseumMenuPatch.DrawPatch)) | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             harmony.Patch( | ||||||
|  |                 original: AccessTools.Method(typeof(MuseumMenu), nameof(MuseumMenu.receiveKeyPress), new Type[] { typeof(Keys) }), | ||||||
|  |                 prefix: new HarmonyMethod(typeof(MuseumMenuPatch), nameof(MuseumMenuPatch.RecieveKeyPressPatch)) | ||||||
|             ); |             ); | ||||||
|  |  | ||||||
|             harmony.Patch( |             harmony.Patch( | ||||||
|                 original: AccessTools.Method(typeof(FieldOfficeMenu), nameof(FieldOfficeMenu.draw), new Type[] { typeof(SpriteBatch) }), |                 original: AccessTools.Method(typeof(FieldOfficeMenu), nameof(FieldOfficeMenu.draw), new Type[] { typeof(SpriteBatch) }), | ||||||
|                 postfix: new HarmonyMethod(typeof(DonationMenuPatches), nameof(DonationMenuPatches.FieldOfficeMenuPatch)) |                 postfix: new HarmonyMethod(typeof(FieldOfficeMenuPatch), nameof(FieldOfficeMenuPatch.DrawPatch)) | ||||||
|             ); |             ); | ||||||
|             #endregion |             #endregion | ||||||
|  |  | ||||||
|   | |||||||
| @@ -159,5 +159,16 @@ namespace stardew_access.Patches | |||||||
|                 MainClass.ScreenReader.Say(toSpeak, true); |                 MainClass.ScreenReader.Say(toSpeak, true); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         internal static void Cleanup() | ||||||
|  |         { | ||||||
|  |             CarpenterMenuPatch.carpenterMenuQuery = ""; | ||||||
|  |             CarpenterMenuPatch.isUpgrading = false; | ||||||
|  |             CarpenterMenuPatch.isDemolishing = false; | ||||||
|  |             CarpenterMenuPatch.isPainting = false; | ||||||
|  |             CarpenterMenuPatch.isMoving = false; | ||||||
|  |             CarpenterMenuPatch.isConstructing = false; | ||||||
|  |             CarpenterMenuPatch.carpenterMenu = null; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,23 +19,22 @@ namespace stardew_access.Patches | |||||||
|                     bool isPrevButtonPressed = MainClass.Config.ChatMenuNextKey.JustPressed(); |                     bool isPrevButtonPressed = MainClass.Config.ChatMenuNextKey.JustPressed(); | ||||||
|                     bool isNextButtonPressed = MainClass.Config.ChatMenuPreviousKey.JustPressed(); |                     bool isNextButtonPressed = MainClass.Config.ChatMenuPreviousKey.JustPressed(); | ||||||
|  |  | ||||||
|                     if (___messages.Count > 0) |                     if (___messages.Count <= 0) return; | ||||||
|  |  | ||||||
|  |                     #region To narrate previous and next chat messages | ||||||
|  |                     if (isNextButtonPressed && !isChatRunning) | ||||||
|                     { |                     { | ||||||
|                         #region To narrate previous and next chat messages |                         isChatRunning = true; | ||||||
|                         if (isNextButtonPressed && !isChatRunning) |                         CycleThroughChatMessages(true, ___messages); | ||||||
|                         { |                         Task.Delay(200).ContinueWith(_ => { isChatRunning = false; }); | ||||||
|                             isChatRunning = true; |  | ||||||
|                             CycleThroughChatMessages(true, ___messages); |  | ||||||
|                             Task.Delay(200).ContinueWith(_ => { isChatRunning = false; }); |  | ||||||
|                         } |  | ||||||
|                         else if (isPrevButtonPressed && !isChatRunning) |  | ||||||
|                         { |  | ||||||
|                             isChatRunning = true; |  | ||||||
|                             CycleThroughChatMessages(false, ___messages); |  | ||||||
|                             Task.Delay(200).ContinueWith(_ => { isChatRunning = false; }); |  | ||||||
|                         } |  | ||||||
|                         #endregion |  | ||||||
|                     } |                     } | ||||||
|  |                     else if (isPrevButtonPressed && !isChatRunning) | ||||||
|  |                     { | ||||||
|  |                         isChatRunning = true; | ||||||
|  |                         CycleThroughChatMessages(false, ___messages); | ||||||
|  |                         Task.Delay(200).ContinueWith(_ => { isChatRunning = false; }); | ||||||
|  |                     } | ||||||
|  |                     #endregion | ||||||
|                 } |                 } | ||||||
|                 else if (___messages.Count > 0) |                 else if (___messages.Count > 0) | ||||||
|                 { |                 { | ||||||
|   | |||||||
| @@ -1,328 +0,0 @@ | |||||||
| using Microsoft.Xna.Framework; |  | ||||||
| using Microsoft.Xna.Framework.Content; |  | ||||||
| using StardewValley; |  | ||||||
| using StardewValley.Locations; |  | ||||||
| using StardewValley.Menus; |  | ||||||
|  |  | ||||||
| namespace stardew_access.Patches |  | ||||||
| { |  | ||||||
|     internal class DonationMenuPatches |  | ||||||
|     { |  | ||||||
|         internal static string museumQueryKey = " "; |  | ||||||
|         internal static string fieldOfficeMenuQuery = " "; |  | ||||||
|         private static bool isMoving = false; |  | ||||||
|         private static (int x, int y)[] donationTiles = |  | ||||||
|         { |  | ||||||
|             (26,5),(26,6),(26,7),(26,8),(26,9),(26,10),(26,11), |  | ||||||
|             (29,5),(30,5),(31,5),(32,5),(33,5),(34,5),(35,5),(36,5), |  | ||||||
|             (28,6),(29,6),(30,6),(31,6),(32,6),(33,6),(34,6),(35,6),(36,6),(37,6), |  | ||||||
|             (28,9),(29,9),(30,9),(31,9),(32,9),(33,9),(34,9),(35,9),(36,9), |  | ||||||
|             (28,10),(29,10),(30,10),(31,10),(32,10),(33,10),(34,10),(35,10),(36,10), |  | ||||||
|             (30,13),(31,13),(32,13),(33,13),(34,13), |  | ||||||
|             (30,14),(31,14),(32,14),(33,14),(34,14), |  | ||||||
|             (28,15),(29,15),(30,15),(31,15),(32,15),(33,15),(34,15),(35,15),(36,15), |  | ||||||
|             (28,16),(29,16),(30,16),(31,16),(32,16),(33,16),(34,16),(35,16),(36,16), |  | ||||||
|             (39,6),(40,6),(41,6),(42,6),(43,6),(44,6),(45,6),(46,6), |  | ||||||
|             (39,7),(40,7),(41,7),(42,7),(43,7),(44,7),(45,7),(46,7), |  | ||||||
|             (48,5),(48,6),(48,7), |  | ||||||
|             (42,15),(43,15),(44,15),(45,15),(46,15),(47,15), |  | ||||||
|             (42,16),(43,16),(44,16),(45,16),(46,16),(47,16), |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         #region Museum |  | ||||||
|  |  | ||||||
|         internal static bool MuseumMenuKeyPressPatch() |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 if (isMoving) |  | ||||||
|                     return false; |  | ||||||
|  |  | ||||||
|                 if (!isMoving) |  | ||||||
|                 { |  | ||||||
|                     isMoving = true; |  | ||||||
|                     Task.Delay(200).ContinueWith(_ => { isMoving = false; }); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|             } |  | ||||||
|             catch (Exception e) |  | ||||||
|             { |  | ||||||
|                 MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         internal static void MuseumMenuPatch(MuseumMenu __instance, bool ___holdingMuseumPiece) |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position |  | ||||||
|  |  | ||||||
|                 if (__instance.heldItem != null) |  | ||||||
|                 { |  | ||||||
|                     // Museum Inventory |  | ||||||
|                     string toSpeak = " "; |  | ||||||
|                     int tileX = (int)(Utility.ModifyCoordinateFromUIScale(x) + (float)Game1.viewport.X) / 64; |  | ||||||
|                     int tileY = (int)(Utility.ModifyCoordinateFromUIScale(y) + (float)Game1.viewport.Y) / 64; |  | ||||||
|                     LibraryMuseum libraryMuseum = (LibraryMuseum)Game1.currentLocation; |  | ||||||
|  |  | ||||||
|                     if (libraryMuseum.isTileSuitableForMuseumPiece(tileX, tileY)) |  | ||||||
|                         toSpeak = $"slot {tileX}x {tileY}y"; |  | ||||||
|  |  | ||||||
|                     if (museumQueryKey != toSpeak) |  | ||||||
|                     { |  | ||||||
|                         museumQueryKey = toSpeak; |  | ||||||
|                         MainClass.ScreenReader.Say(toSpeak, true); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     // Player Inventory |  | ||||||
|                     int i = InventoryUtils.narrateHoveredSlotAndReturnIndex(__instance.inventory, __instance.inventory.inventory, __instance.inventory.actualInventory, x, y, |  | ||||||
|                             handleHighlightedItem: true, highlightedItemPrefix: "Donatable "); |  | ||||||
|                     if (i != -9999) |  | ||||||
|                     { |  | ||||||
|                         bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For donating hovered item |  | ||||||
|  |  | ||||||
|                         if (isPrimaryInfoKeyPressed && __instance.inventory.actualInventory[i] != null) |  | ||||||
|                         { |  | ||||||
|                             foreach (var tile in donationTiles) |  | ||||||
|                             { |  | ||||||
|                                 #region Manually donates the hovered item (https://github.com/veywrn/StardewValley/blob/3ff171b6e9e6839555d7881a391b624ccd820a83/StardewValley/Menus/MuseumMenu.cs#L206-L247) |  | ||||||
|                                 int tileX = tile.x; |  | ||||||
|                                 int tileY = tile.y; |  | ||||||
|  |  | ||||||
|                                 if (((LibraryMuseum)Game1.currentLocation).isTileSuitableForMuseumPiece(tileX, tileY) && ((LibraryMuseum)Game1.currentLocation).isItemSuitableForDonation(__instance.inventory.actualInventory[i])) |  | ||||||
|                                 { |  | ||||||
|                                     int objectID = __instance.inventory.actualInventory[i].ParentSheetIndex; |  | ||||||
|                                     int rewardsCount = ((LibraryMuseum)Game1.currentLocation).getRewardsForPlayer(Game1.player).Count; |  | ||||||
|                                     ((LibraryMuseum)Game1.currentLocation).museumPieces.Add(new Vector2(tileX, tileY), ((StardewValley.Object)__instance.inventory.actualInventory[i]).ParentSheetIndex); |  | ||||||
|                                     Game1.playSound("stoneStep"); |  | ||||||
|                                     if (((LibraryMuseum)Game1.currentLocation).getRewardsForPlayer(Game1.player).Count > rewardsCount) |  | ||||||
|                                     { |  | ||||||
|                                         Game1.playSound("reward"); |  | ||||||
|                                     } |  | ||||||
|                                     else |  | ||||||
|                                     { |  | ||||||
|                                         Game1.playSound("newArtifact"); |  | ||||||
|                                     } |  | ||||||
|                                     Game1.player.completeQuest(24); |  | ||||||
|                                     __instance.inventory.actualInventory[i].Stack--; |  | ||||||
|                                     if (__instance.inventory.actualInventory[i].Stack <= 0) |  | ||||||
|                                     { |  | ||||||
|                                         __instance.inventory.actualInventory[i] = null; |  | ||||||
|                                     } |  | ||||||
|                                     int pieces = ((LibraryMuseum)Game1.currentLocation).museumPieces.Count(); |  | ||||||
|                                     Game1.stats.checkForArchaeologyAchievements(); |  | ||||||
|                                     switch (pieces) |  | ||||||
|                                     { |  | ||||||
|                                         case 95: |  | ||||||
|                                             globalChatInfoMessage("MuseumComplete", Game1.player.farmName.Value); |  | ||||||
|                                             break; |  | ||||||
|                                         case 40: |  | ||||||
|                                             globalChatInfoMessage("Museum40", Game1.player.farmName.Value); |  | ||||||
|                                             break; |  | ||||||
|                                         default: |  | ||||||
|                                             globalChatInfoMessage("donation", Game1.player.Name, "object:" + objectID); |  | ||||||
|                                             break; |  | ||||||
|                                     } |  | ||||||
|                                     break; |  | ||||||
|                                 } |  | ||||||
|                                 #endregion |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                     else if (__instance.okButton != null && __instance.okButton.containsPoint(x, y)) |  | ||||||
|                     { |  | ||||||
|                         if (museumQueryKey != $"ok button") |  | ||||||
|                         { |  | ||||||
|                             museumQueryKey = $"ok button"; |  | ||||||
|                             MainClass.ScreenReader.Say("ok button", true); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             catch (Exception e) |  | ||||||
|             { |  | ||||||
|                 MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|          |  | ||||||
|         #region These methods are taken from the game's source code, https://github.com/veywrn/StardewValley/blob/3ff171b6e9e6839555d7881a391b624ccd820a83/StardewValley/Multiplayer.cs#L1331-L1395 |  | ||||||
|         internal static void globalChatInfoMessage(string messageKey, params string[] args) |  | ||||||
|         { |  | ||||||
|             if (Game1.IsMultiplayer || Game1.multiplayerMode != 0) |  | ||||||
|             { |  | ||||||
|                 receiveChatInfoMessage(Game1.player, messageKey, args); |  | ||||||
|                 sendChatInfoMessage(messageKey, args); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         internal static void sendChatInfoMessage(string messageKey, params string[] args) |  | ||||||
|         { |  | ||||||
|             if (Game1.IsClient) |  | ||||||
|             { |  | ||||||
|                 Game1.client.sendMessage(15, messageKey, args); |  | ||||||
|             } |  | ||||||
|             else if (Game1.IsServer) |  | ||||||
|             { |  | ||||||
|                 foreach (long id in Game1.otherFarmers.Keys) |  | ||||||
|                 { |  | ||||||
|                     Game1.server.sendMessage(id, 15, Game1.player, messageKey, args); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         internal static void receiveChatInfoMessage(Farmer sourceFarmer, string messageKey, string[] args) |  | ||||||
|         { |  | ||||||
|             if (Game1.chatBox != null) |  | ||||||
|             { |  | ||||||
|                 try |  | ||||||
|                 { |  | ||||||
|                     string[] processedArgs = args.Select(delegate (string arg) |  | ||||||
|                     { |  | ||||||
|                         if (arg.StartsWith("achievement:")) |  | ||||||
|                         { |  | ||||||
|                             int key = Convert.ToInt32(arg.Substring("achievement:".Length)); |  | ||||||
|                             return Game1.content.Load<Dictionary<int, string>>("Data\\Achievements")[key].Split('^')[0]; |  | ||||||
|                         } |  | ||||||
|                         return arg.StartsWith("object:") ? new StardewValley.Object(Convert.ToInt32(arg.Substring("object:".Length)), 1).DisplayName : arg; |  | ||||||
|                     }).ToArray(); |  | ||||||
|                     ChatBox chatBox = Game1.chatBox; |  | ||||||
|                     LocalizedContentManager content = Game1.content; |  | ||||||
|                     string path = "Strings\\UI:Chat_" + messageKey; |  | ||||||
|                     object[] substitutions = processedArgs; |  | ||||||
|                     chatBox.addInfoMessage(content.LoadString(path, substitutions)); |  | ||||||
|                 } |  | ||||||
|                 catch (ContentLoadException) |  | ||||||
|                 { |  | ||||||
|                 } |  | ||||||
|                 catch (FormatException) |  | ||||||
|                 { |  | ||||||
|                 } |  | ||||||
|                 catch (OverflowException) |  | ||||||
|                 { |  | ||||||
|                 } |  | ||||||
|                 catch (KeyNotFoundException) |  | ||||||
|                 { |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         #endregion |  | ||||||
|  |  | ||||||
|         #endregion |  | ||||||
|  |  | ||||||
|         #region Field Office |  | ||||||
|  |  | ||||||
|         internal static void FieldOfficeMenuPatch(FieldOfficeMenu __instance) |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position |  | ||||||
|                 string toSpeak = " "; |  | ||||||
|  |  | ||||||
|                 if (__instance.trashCan != null && __instance.trashCan.containsPoint(x, y)) |  | ||||||
|                 { |  | ||||||
|                     toSpeak = "Trashcan"; |  | ||||||
|                 } |  | ||||||
|                 else if (__instance.okButton != null && __instance.okButton.containsPoint(x, y)) |  | ||||||
|                 { |  | ||||||
|                     toSpeak = "ok button"; |  | ||||||
|                 } |  | ||||||
|                 else if (__instance.dropItemInvisibleButton != null && __instance.dropItemInvisibleButton.containsPoint(x, y)) |  | ||||||
|                 { |  | ||||||
|                     toSpeak = "drop item"; |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     if (InventoryUtils.narrateHoveredSlot(__instance.inventory, __instance.inventory.inventory, __instance.inventory.actualInventory, x, y)) |  | ||||||
|                         return; |  | ||||||
|  |  | ||||||
|                     for (int i = 0; i < __instance.pieceHolders.Count; i++) |  | ||||||
|                     { |  | ||||||
|                         if (!__instance.pieceHolders[i].containsPoint(x, y)) |  | ||||||
|                             continue; |  | ||||||
|  |  | ||||||
|                         if (__instance.pieceHolders[i].item == null) |  | ||||||
|                             toSpeak = i switch |  | ||||||
|                             { |  | ||||||
|                                 0 => "Center skeleton slot", |  | ||||||
|                                 1 => "Center skeleton slot", |  | ||||||
|                                 2 => "Center skeleton slot", |  | ||||||
|                                 3 => "Center skeleton slot", |  | ||||||
|                                 4 => "Center skeleton slot", |  | ||||||
|                                 5 => "Center skeleton slot", |  | ||||||
|                                 6 => "Snake slot", |  | ||||||
|                                 7 => "Snake slot", |  | ||||||
|                                 8 => "Snake slot", |  | ||||||
|                                 9 => "Bat slot", |  | ||||||
|                                 10 => "Frog slot", |  | ||||||
|                                 _ => "Donation slot" |  | ||||||
|                             }; |  | ||||||
|                         else |  | ||||||
|                             toSpeak = $"Slot {i + 1} finished: {__instance.pieceHolders[i].item.DisplayName}"; |  | ||||||
|  |  | ||||||
|                         if (!MainClass.Config.DisableInventoryVerbosity && __instance.heldItem != null && __instance.pieceHolders[i].item == null) |  | ||||||
|                         { |  | ||||||
|                             int highlight = getPieceIndexForDonationItem(__instance.heldItem.ParentSheetIndex); |  | ||||||
|                             if (highlight != -1 && highlight == i) |  | ||||||
|                                 toSpeak += "Donatable "; |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         if (fieldOfficeMenuQuery != $"{toSpeak}:{i}") |  | ||||||
|                         { |  | ||||||
|                             fieldOfficeMenuQuery = $"{toSpeak}:{i}"; |  | ||||||
|                             MainClass.ScreenReader.Say(toSpeak, true); |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (fieldOfficeMenuQuery != toSpeak) |  | ||||||
|                 { |  | ||||||
|                     fieldOfficeMenuQuery = toSpeak; |  | ||||||
|                     MainClass.ScreenReader.Say(toSpeak, true); |  | ||||||
|  |  | ||||||
|                     if (__instance.dropItemInvisibleButton != null && __instance.dropItemInvisibleButton.containsPoint(x, y)) |  | ||||||
|                         Game1.playSound("drop_item"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             catch (System.Exception e) |  | ||||||
|             { |  | ||||||
|                 MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         internal static int getPieceIndexForDonationItem(int itemIndex) |  | ||||||
|         { |  | ||||||
|             switch (itemIndex) |  | ||||||
|             { |  | ||||||
|                 case 820: |  | ||||||
|                     return 5; |  | ||||||
|                 case 821: |  | ||||||
|                     return 4; |  | ||||||
|                 case 822: |  | ||||||
|                     return 3; |  | ||||||
|                 case 823: |  | ||||||
|                     return 0; |  | ||||||
|                 case 824: |  | ||||||
|                     return 1; |  | ||||||
|                 case 825: |  | ||||||
|                     return 8; |  | ||||||
|                 case 826: |  | ||||||
|                     return 7; |  | ||||||
|                 case 827: |  | ||||||
|                     return 9; |  | ||||||
|                 case 828: |  | ||||||
|                     return 10; |  | ||||||
|                 default: |  | ||||||
|                     return -1; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         #endregion |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -0,0 +1,122 @@ | |||||||
|  | using StardewValley; | ||||||
|  | using StardewValley.Menus; | ||||||
|  |  | ||||||
|  | namespace stardew_access.Patches | ||||||
|  | { | ||||||
|  |     internal class FieldOfficeMenuPatch | ||||||
|  |     { | ||||||
|  |         private static string fieldOfficeMenuQuery = ""; | ||||||
|  |  | ||||||
|  |         internal static void DrawPatch(FieldOfficeMenu __instance) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position | ||||||
|  |                 string toSpeak = " "; | ||||||
|  |  | ||||||
|  |                 if (__instance.trashCan != null && __instance.trashCan.containsPoint(x, y)) | ||||||
|  |                 { | ||||||
|  |                     toSpeak = "Trashcan"; | ||||||
|  |                 } | ||||||
|  |                 else if (__instance.okButton != null && __instance.okButton.containsPoint(x, y)) | ||||||
|  |                 { | ||||||
|  |                     toSpeak = "ok button"; | ||||||
|  |                 } | ||||||
|  |                 else if (__instance.dropItemInvisibleButton != null && __instance.dropItemInvisibleButton.containsPoint(x, y)) | ||||||
|  |                 { | ||||||
|  |                     toSpeak = "drop item"; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     if (InventoryUtils.narrateHoveredSlot(__instance.inventory, __instance.inventory.inventory, __instance.inventory.actualInventory, x, y)) | ||||||
|  |                         return; | ||||||
|  |  | ||||||
|  |                     for (int i = 0; i < __instance.pieceHolders.Count; i++) | ||||||
|  |                     { | ||||||
|  |                         if (!__instance.pieceHolders[i].containsPoint(x, y)) | ||||||
|  |                             continue; | ||||||
|  |  | ||||||
|  |                         if (__instance.pieceHolders[i].item == null) | ||||||
|  |                             toSpeak = i switch | ||||||
|  |                             { | ||||||
|  |                                 0 => "Center skeleton slot", | ||||||
|  |                                 1 => "Center skeleton slot", | ||||||
|  |                                 2 => "Center skeleton slot", | ||||||
|  |                                 3 => "Center skeleton slot", | ||||||
|  |                                 4 => "Center skeleton slot", | ||||||
|  |                                 5 => "Center skeleton slot", | ||||||
|  |                                 6 => "Snake slot", | ||||||
|  |                                 7 => "Snake slot", | ||||||
|  |                                 8 => "Snake slot", | ||||||
|  |                                 9 => "Bat slot", | ||||||
|  |                                 10 => "Frog slot", | ||||||
|  |                                 _ => "Donation slot" | ||||||
|  |                             }; | ||||||
|  |                         else | ||||||
|  |                             toSpeak = $"Slot {i + 1} finished: {__instance.pieceHolders[i].item.DisplayName}"; | ||||||
|  |  | ||||||
|  |                         if (!MainClass.Config.DisableInventoryVerbosity && __instance.heldItem != null && __instance.pieceHolders[i].item == null) | ||||||
|  |                         { | ||||||
|  |                             int highlight = getPieceIndexForDonationItem(__instance.heldItem.ParentSheetIndex); | ||||||
|  |                             if (highlight != -1 && highlight == i) | ||||||
|  |                                 toSpeak += "Donatable "; | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         if (fieldOfficeMenuQuery != $"{toSpeak}:{i}") | ||||||
|  |                         { | ||||||
|  |                             fieldOfficeMenuQuery = $"{toSpeak}:{i}"; | ||||||
|  |                             MainClass.ScreenReader.Say(toSpeak, true); | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (fieldOfficeMenuQuery != toSpeak) | ||||||
|  |                 { | ||||||
|  |                     fieldOfficeMenuQuery = toSpeak; | ||||||
|  |                     MainClass.ScreenReader.Say(toSpeak, true); | ||||||
|  |  | ||||||
|  |                     if (__instance.dropItemInvisibleButton != null && __instance.dropItemInvisibleButton.containsPoint(x, y)) | ||||||
|  |                         Game1.playSound("drop_item"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (System.Exception e) | ||||||
|  |             { | ||||||
|  |                 MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal static int getPieceIndexForDonationItem(int itemIndex) | ||||||
|  |         { | ||||||
|  |             switch (itemIndex) | ||||||
|  |             { | ||||||
|  |                 case 820: | ||||||
|  |                     return 5; | ||||||
|  |                 case 821: | ||||||
|  |                     return 4; | ||||||
|  |                 case 822: | ||||||
|  |                     return 3; | ||||||
|  |                 case 823: | ||||||
|  |                     return 0; | ||||||
|  |                 case 824: | ||||||
|  |                     return 1; | ||||||
|  |                 case 825: | ||||||
|  |                     return 8; | ||||||
|  |                 case 826: | ||||||
|  |                     return 7; | ||||||
|  |                 case 827: | ||||||
|  |                     return 9; | ||||||
|  |                 case 828: | ||||||
|  |                     return 10; | ||||||
|  |                 default: | ||||||
|  |                     return -1; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal static void Cleanup() | ||||||
|  |         { | ||||||
|  |             fieldOfficeMenuQuery = ""; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										245
									
								
								stardew-access/Patches/DonationMenuPatches/MuseumMenuPatch.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								stardew-access/Patches/DonationMenuPatches/MuseumMenuPatch.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | |||||||
|  | using Microsoft.Xna.Framework; | ||||||
|  | using StardewValley; | ||||||
|  | using StardewValley.Locations; | ||||||
|  | using StardewValley.Menus; | ||||||
|  |  | ||||||
|  | namespace stardew_access.Patches | ||||||
|  | { | ||||||
|  |     internal class MuseumMenuPatch | ||||||
|  |     { | ||||||
|  |         private static string museumQueryKey = ""; | ||||||
|  |         private static bool isMoving = false; | ||||||
|  |         private static (int x, int y)[] donationTiles = | ||||||
|  |         { | ||||||
|  |             (26,5),(26,6),(26,7),(26,8),(26,9),(26,10),(26,11), | ||||||
|  |             (29,5),(30,5),(31,5),(32,5),(33,5),(34,5),(35,5),(36,5), | ||||||
|  |             (28,6),(29,6),(30,6),(31,6),(32,6),(33,6),(34,6),(35,6),(36,6),(37,6), | ||||||
|  |             (28,9),(29,9),(30,9),(31,9),(32,9),(33,9),(34,9),(35,9),(36,9), | ||||||
|  |             (28,10),(29,10),(30,10),(31,10),(32,10),(33,10),(34,10),(35,10),(36,10), | ||||||
|  |             (30,13),(31,13),(32,13),(33,13),(34,13), | ||||||
|  |             (30,14),(31,14),(32,14),(33,14),(34,14), | ||||||
|  |             (28,15),(29,15),(30,15),(31,15),(32,15),(33,15),(34,15),(35,15),(36,15), | ||||||
|  |             (28,16),(29,16),(30,16),(31,16),(32,16),(33,16),(34,16),(35,16),(36,16), | ||||||
|  |             (39,6),(40,6),(41,6),(42,6),(43,6),(44,6),(45,6),(46,6), | ||||||
|  |             (39,7),(40,7),(41,7),(42,7),(43,7),(44,7),(45,7),(46,7), | ||||||
|  |             (48,5),(48,6),(48,7), | ||||||
|  |             (42,15),(43,15),(44,15),(45,15),(46,15),(47,15), | ||||||
|  |             (42,16),(43,16),(44,16),(45,16),(46,16),(47,16), | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         internal static bool RecieveKeyPressPatch() | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 if (isMoving) | ||||||
|  |                     return false; | ||||||
|  |  | ||||||
|  |                 if (!isMoving) | ||||||
|  |                 { | ||||||
|  |                     isMoving = true; | ||||||
|  |                     Task.Delay(200).ContinueWith(_ => { isMoving = false; }); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |             catch (Exception e) | ||||||
|  |             { | ||||||
|  |                 MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal static void DrawPatch(MuseumMenu __instance, bool ___holdingMuseumPiece) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position | ||||||
|  |  | ||||||
|  |                 narrateMuseumInventory(__instance, x, y); | ||||||
|  |  | ||||||
|  |                 narratePlayerInventory(__instance, x, y); | ||||||
|  |             } | ||||||
|  |             catch (Exception e) | ||||||
|  |             { | ||||||
|  |                 MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void narrateMuseumInventory(MuseumMenu __instance, int x, int y) | ||||||
|  |         { | ||||||
|  |             if (__instance.heldItem == null) return; | ||||||
|  |  | ||||||
|  |             string toSpeak = ""; | ||||||
|  |             int tileX = (int)(Utility.ModifyCoordinateFromUIScale(x) + (float)Game1.viewport.X) / 64; | ||||||
|  |             int tileY = (int)(Utility.ModifyCoordinateFromUIScale(y) + (float)Game1.viewport.Y) / 64; | ||||||
|  |             LibraryMuseum libraryMuseum = (LibraryMuseum)Game1.currentLocation; | ||||||
|  |  | ||||||
|  |             if (libraryMuseum.isTileSuitableForMuseumPiece(tileX, tileY)) | ||||||
|  |                 toSpeak = $"slot {tileX}x {tileY}y"; | ||||||
|  |  | ||||||
|  |             if (museumQueryKey != toSpeak) | ||||||
|  |             { | ||||||
|  |                 museumQueryKey = toSpeak; | ||||||
|  |                 MainClass.ScreenReader.Say(toSpeak, true); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void narratePlayerInventory(MuseumMenu __instance, int x, int y) | ||||||
|  |         { | ||||||
|  |             if (__instance.heldItem != null) return; | ||||||
|  |  | ||||||
|  |             int hoveredItemIndex = InventoryUtils.narrateHoveredSlotAndReturnIndex(__instance.inventory, __instance.inventory.inventory, __instance.inventory.actualInventory, x, y, | ||||||
|  |                     handleHighlightedItem: true, highlightedItemPrefix: "Donatable "); | ||||||
|  |             if (hoveredItemIndex != -9999) | ||||||
|  |             { | ||||||
|  |                 bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For donating hovered item | ||||||
|  |  | ||||||
|  |                 if (isPrimaryInfoKeyPressed && hoveredItemIndex >= 0 && hoveredItemIndex < __instance.inventory.actualInventory.Count && __instance.inventory.actualInventory[hoveredItemIndex] != null) | ||||||
|  |                 { | ||||||
|  |                     manuallyDonateItem(__instance, hoveredItemIndex); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 string toSpeak = ""; | ||||||
|  |                 bool isDropItemButton = false; | ||||||
|  |  | ||||||
|  |                 if (__instance.okButton != null && __instance.okButton.containsPoint(x, y)) | ||||||
|  |                 { | ||||||
|  |                     toSpeak = "Ok button"; | ||||||
|  |                 } | ||||||
|  |                 else if (__instance.dropItemInvisibleButton != null && __instance.dropItemInvisibleButton.containsPoint(x, y)) | ||||||
|  |                 { | ||||||
|  |                     toSpeak = "Drop Item"; | ||||||
|  |                     isDropItemButton = true; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (museumQueryKey != toSpeak) | ||||||
|  |                 { | ||||||
|  |                     museumQueryKey = toSpeak; | ||||||
|  |                     MainClass.ScreenReader.Say(toSpeak, true); | ||||||
|  |                     if (isDropItemButton) Game1.playSound("drop_item"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void manuallyDonateItem(MuseumMenu __instance, int i) | ||||||
|  |         { | ||||||
|  |             foreach (var tile in donationTiles) | ||||||
|  |             { | ||||||
|  |                 #region Manually donates the hovered item (https://github.com/veywrn/StardewValley/blob/3ff171b6e9e6839555d7881a391b624ccd820a83/StardewValley/Menus/MuseumMenu.cs#L206-L247) | ||||||
|  |                 int tileX = tile.x; | ||||||
|  |                 int tileY = tile.y; | ||||||
|  |  | ||||||
|  |                 if (((LibraryMuseum)Game1.currentLocation).isTileSuitableForMuseumPiece(tileX, tileY) && ((LibraryMuseum)Game1.currentLocation).isItemSuitableForDonation(__instance.inventory.actualInventory[i])) | ||||||
|  |                 { | ||||||
|  |                     int objectID = __instance.inventory.actualInventory[i].ParentSheetIndex; | ||||||
|  |                     int rewardsCount = ((LibraryMuseum)Game1.currentLocation).getRewardsForPlayer(Game1.player).Count; | ||||||
|  |                     ((LibraryMuseum)Game1.currentLocation).museumPieces.Add(new Vector2(tileX, tileY), ((StardewValley.Object)__instance.inventory.actualInventory[i]).ParentSheetIndex); | ||||||
|  |                     Game1.playSound("stoneStep"); | ||||||
|  |                     if (((LibraryMuseum)Game1.currentLocation).getRewardsForPlayer(Game1.player).Count > rewardsCount) | ||||||
|  |                     { | ||||||
|  |                         Game1.playSound("reward"); | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         Game1.playSound("newArtifact"); | ||||||
|  |                     } | ||||||
|  |                     Game1.player.completeQuest(24); | ||||||
|  |                     __instance.inventory.actualInventory[i].Stack--; | ||||||
|  |                     if (__instance.inventory.actualInventory[i].Stack <= 0) | ||||||
|  |                     { | ||||||
|  |                         __instance.inventory.actualInventory[i] = null; | ||||||
|  |                     } | ||||||
|  |                     int pieces = ((LibraryMuseum)Game1.currentLocation).museumPieces.Count(); | ||||||
|  |                     Game1.stats.checkForArchaeologyAchievements(); | ||||||
|  |                     switch (pieces) | ||||||
|  |                     { | ||||||
|  |                         case 95: | ||||||
|  |                             globalChatInfoMessage("MuseumComplete", Game1.player.farmName.Value); | ||||||
|  |                             break; | ||||||
|  |                         case 40: | ||||||
|  |                             globalChatInfoMessage("Museum40", Game1.player.farmName.Value); | ||||||
|  |                             break; | ||||||
|  |                         default: | ||||||
|  |                             globalChatInfoMessage("donation", Game1.player.Name, "object:" + objectID); | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 #endregion | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #region These methods are taken from the game's source code, https://github.com/veywrn/StardewValley/blob/3ff171b6e9e6839555d7881a391b624ccd820a83/StardewValley/Multiplayer.cs#L1331-L1395 | ||||||
|  |         internal static void globalChatInfoMessage(string messageKey, params string[] args) | ||||||
|  |         { | ||||||
|  |             if (Game1.IsMultiplayer || Game1.multiplayerMode != 0) | ||||||
|  |             { | ||||||
|  |                 receiveChatInfoMessage(Game1.player, messageKey, args); | ||||||
|  |                 sendChatInfoMessage(messageKey, args); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal static void sendChatInfoMessage(string messageKey, params string[] args) | ||||||
|  |         { | ||||||
|  |             if (Game1.IsClient) | ||||||
|  |             { | ||||||
|  |                 Game1.client.sendMessage(15, messageKey, args); | ||||||
|  |             } | ||||||
|  |             else if (Game1.IsServer) | ||||||
|  |             { | ||||||
|  |                 foreach (long id in Game1.otherFarmers.Keys) | ||||||
|  |                 { | ||||||
|  |                     Game1.server.sendMessage(id, 15, Game1.player, messageKey, args); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal static void receiveChatInfoMessage(Farmer sourceFarmer, string messageKey, string[] args) | ||||||
|  |         { | ||||||
|  |             if (Game1.chatBox != null) | ||||||
|  |             { | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     string[] processedArgs = args.Select(delegate (string arg) | ||||||
|  |                     { | ||||||
|  |                         if (arg.StartsWith("achievement:")) | ||||||
|  |                         { | ||||||
|  |                             int key = Convert.ToInt32(arg.Substring("achievement:".Length)); | ||||||
|  |                             return Game1.content.Load<Dictionary<int, string>>("Data\\Achievements")[key].Split('^')[0]; | ||||||
|  |                         } | ||||||
|  |                         return arg.StartsWith("object:") ? new StardewValley.Object(Convert.ToInt32(arg.Substring("object:".Length)), 1).DisplayName : arg; | ||||||
|  |                     }).ToArray(); | ||||||
|  |                     ChatBox chatBox = Game1.chatBox; | ||||||
|  |                     LocalizedContentManager content = Game1.content; | ||||||
|  |                     string path = "Strings\\UI:Chat_" + messageKey; | ||||||
|  |                     object[] substitutions = processedArgs; | ||||||
|  |                     chatBox.addInfoMessage(content.LoadString(path, substitutions)); | ||||||
|  |                 } | ||||||
|  |                 catch (Microsoft.Xna.Framework.Content.ContentLoadException) | ||||||
|  |                 { | ||||||
|  |                 } | ||||||
|  |                 catch (FormatException) | ||||||
|  |                 { | ||||||
|  |                 } | ||||||
|  |                 catch (OverflowException) | ||||||
|  |                 { | ||||||
|  |                 } | ||||||
|  |                 catch (KeyNotFoundException) | ||||||
|  |                 { | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |         internal static void Cleanup() | ||||||
|  |         { | ||||||
|  |             museumQueryKey = ""; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -263,13 +263,7 @@ namespace stardew_access.Patches | |||||||
|             } |             } | ||||||
|             else if (menu is CarpenterMenu) |             else if (menu is CarpenterMenu) | ||||||
|             { |             { | ||||||
|                 CarpenterMenuPatch.carpenterMenuQuery = ""; |                 CarpenterMenuPatch.Cleanup(); | ||||||
|                 CarpenterMenuPatch.isUpgrading = false; |  | ||||||
|                 CarpenterMenuPatch.isDemolishing = false; |  | ||||||
|                 CarpenterMenuPatch.isPainting = false; |  | ||||||
|                 CarpenterMenuPatch.isMoving = false; |  | ||||||
|                 CarpenterMenuPatch.isConstructing = false; |  | ||||||
|                 CarpenterMenuPatch.carpenterMenu = null; |  | ||||||
|             } |             } | ||||||
|             else if (menu is PurchaseAnimalsMenu) |             else if (menu is PurchaseAnimalsMenu) | ||||||
|             { |             { | ||||||
| @@ -305,11 +299,11 @@ namespace stardew_access.Patches | |||||||
|             } |             } | ||||||
|             else if (menu is FieldOfficeMenu) |             else if (menu is FieldOfficeMenu) | ||||||
|             { |             { | ||||||
|                 DonationMenuPatches.fieldOfficeMenuQuery = " "; |                 FieldOfficeMenuPatch.Cleanup(); | ||||||
|             } |             } | ||||||
|             else if (menu is MuseumMenu) |             else if (menu is MuseumMenu) | ||||||
|             { |             { | ||||||
|                 DonationMenuPatches.museumQueryKey = " "; |                 MuseumMenuPatch.Cleanup(); | ||||||
|             } |             } | ||||||
|             else if (menu is PondQueryMenu) |             else if (menu is PondQueryMenu) | ||||||
|             { |             { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user