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)) | ||||
|             ); | ||||
|  | ||||
|             harmony.Patch( | ||||
|                 original: AccessTools.Method(typeof(MuseumMenu), nameof(MuseumMenu.receiveKeyPress), new Type[] { typeof(Keys) }), | ||||
|                 prefix: new HarmonyMethod(typeof(DonationMenuPatches), nameof(DonationMenuPatches.MuseumMenuKeyPressPatch)) | ||||
|             ); | ||||
|  | ||||
|             harmony.Patch( | ||||
|                 original: AccessTools.Method(typeof(ChooseFromListMenu), nameof(ChooseFromListMenu.draw), new Type[] { typeof(SpriteBatch) }), | ||||
|                 postfix: new HarmonyMethod(typeof(MenuPatches), nameof(MenuPatches.ChooseFromListMenuPatch)) | ||||
| @@ -255,12 +250,17 @@ namespace stardew_access | ||||
|             #region Donation Menus | ||||
|             harmony.Patch( | ||||
|                 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( | ||||
|                 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 | ||||
|  | ||||
|   | ||||
| @@ -159,5 +159,16 @@ namespace stardew_access.Patches | ||||
|                 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,8 +19,8 @@ namespace stardew_access.Patches | ||||
|                     bool isPrevButtonPressed = MainClass.Config.ChatMenuNextKey.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) | ||||
|                     { | ||||
| @@ -36,7 +36,6 @@ namespace stardew_access.Patches | ||||
|                     } | ||||
|                     #endregion | ||||
|                 } | ||||
|                 } | ||||
|                 else if (___messages.Count > 0) | ||||
|                 { | ||||
|                     #region To narrate latest chat message | ||||
|   | ||||
| @@ -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) | ||||
|             { | ||||
|                 CarpenterMenuPatch.carpenterMenuQuery = ""; | ||||
|                 CarpenterMenuPatch.isUpgrading = false; | ||||
|                 CarpenterMenuPatch.isDemolishing = false; | ||||
|                 CarpenterMenuPatch.isPainting = false; | ||||
|                 CarpenterMenuPatch.isMoving = false; | ||||
|                 CarpenterMenuPatch.isConstructing = false; | ||||
|                 CarpenterMenuPatch.carpenterMenu = null; | ||||
|                 CarpenterMenuPatch.Cleanup(); | ||||
|             } | ||||
|             else if (menu is PurchaseAnimalsMenu) | ||||
|             { | ||||
| @@ -305,11 +299,11 @@ namespace stardew_access.Patches | ||||
|             } | ||||
|             else if (menu is FieldOfficeMenu) | ||||
|             { | ||||
|                 DonationMenuPatches.fieldOfficeMenuQuery = " "; | ||||
|                 FieldOfficeMenuPatch.Cleanup(); | ||||
|             } | ||||
|             else if (menu is MuseumMenu) | ||||
|             { | ||||
|                 DonationMenuPatches.museumQueryKey = " "; | ||||
|                 MuseumMenuPatch.Cleanup(); | ||||
|             } | ||||
|             else if (menu is PondQueryMenu) | ||||
|             { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user