2022-01-03 21:53:29 +05:30
using StardewModdingAPI ;
using StardewValley ;
using StardewValley.Menus ;
2022-01-07 14:17:00 +05:30
using StardewValley.Objects ;
2022-01-03 21:53:29 +05:30
namespace stardew_access.Patches
{
internal class GameMenuPatches
{
2022-01-06 21:59:27 +05:30
internal static string hoveredItemQueryKey = "" ;
2022-01-06 18:52:23 +05:30
internal static string geodeMenuQueryKey = "" ;
2022-01-07 14:57:57 +05:30
internal static string gameMenuQueryKey = "" ;
2022-01-06 21:59:27 +05:30
internal static string itemGrabMenuQueryKey = "" ;
internal static string craftingPageQueryKey = "" ;
internal static string inventoryPageQueryKey = "" ;
2022-01-07 14:57:57 +05:30
internal static string exitPageQueryKey = "" ;
internal static string optionsPageQueryKey = "" ;
internal static void GameMenuPatch ( GameMenu __instance )
{
try
{
// Continue if only in the Inventory Page or Crafting Page
if ( __instance . currentTab != 0 && __instance . currentTab != 4 && __instance . currentTab != 6 && __instance . currentTab != 7 )
return ;
int x = Game1 . getMousePosition ( true ). X , y = Game1 . getMousePosition ( true ). Y ; // Mouse x and y position
for ( int i = 0 ; i < __instance . tabs . Count ; i ++)
{
if ( __instance . tabs [ i ]. containsPoint ( x , y ))
{
string toSpeak = $"{GameMenu.getLabelOfTabFromIndex(i)} Tab" ;
if ( gameMenuQueryKey != toSpeak )
{
gameMenuQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
}
}
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
2022-01-06 18:52:23 +05:30
internal static void GeodeMenuPatch ( GeodeMenu __instance )
{
try
{
int x = Game1 . getMousePosition ( true ). X , y = Game1 . getMousePosition ( true ). Y ; // Mouse x and y position
2022-01-06 19:08:06 +05:30
#region Narrate the treasure recieved on breaking the geode
if ( __instance . geodeTreasure != null )
{
string name = __instance . geodeTreasure . DisplayName ;
int stack = __instance . geodeTreasure . Stack ;
string toSpeak = $"Recieved {stack} {name}" ;
if ( geodeMenuQueryKey != toSpeak )
{
geodeMenuQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
}
#endregion
#region Narrate hovered buttons in the menu
2022-01-06 18:52:23 +05:30
if ( __instance . geodeSpot != null && __instance . geodeSpot . containsPoint ( x , y ))
{
string toSpeak = "Place geode here" ;
if ( geodeMenuQueryKey != toSpeak )
{
geodeMenuQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
}
if ( __instance . dropItemInvisibleButton != null && __instance . dropItemInvisibleButton . containsPoint ( x , y ))
{
string toSpeak = "Drop item here" ;
if ( geodeMenuQueryKey != toSpeak )
{
geodeMenuQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
2022-01-06 21:59:27 +05:30
Game1 . playSound ( "sa_drop_item" );
2022-01-06 18:52:23 +05:30
}
return ;
}
if ( __instance . trashCan != null && __instance . trashCan . containsPoint ( x , y ))
{
string toSpeak = "Trash can" ;
if ( geodeMenuQueryKey != toSpeak )
{
geodeMenuQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
}
if ( __instance . okButton != null && __instance . okButton . containsPoint ( x , y ))
{
string toSpeak = "Ok button" ;
if ( geodeMenuQueryKey != toSpeak )
{
geodeMenuQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
2022-01-06 19:41:28 +05:30
}
2022-01-06 19:08:06 +05:30
#endregion
2022-01-06 18:52:23 +05:30
2022-01-06 19:08:06 +05:30
#region Narrate hovered item
2022-01-06 21:59:27 +05:30
if ( narrateHoveredItemInInventory ( __instance . inventory . inventory , __instance . inventory . actualInventory , x , y ))
geodeMenuQueryKey = "" ;
2022-01-06 19:08:06 +05:30
#endregion
2022-01-06 18:52:23 +05:30
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
2022-01-05 20:41:36 +05:30
internal static void ItemGrabMenuPatch ( ItemGrabMenu __instance )
{
try
{
int x = Game1 . getMousePosition ( true ). X , y = Game1 . getMousePosition ( true ). Y ; // Mouse x and y position
2022-01-06 19:41:28 +05:30
bool isIPressed = Game1 . input . GetKeyboardState (). IsKeyDown ( Microsoft . Xna . Framework . Input . Keys . I );
bool isLeftShiftPressed = Game1 . input . GetKeyboardState (). IsKeyDown ( Microsoft . Xna . Framework . Input . Keys . LeftShift );
2022-01-05 20:41:36 +05:30
2022-01-06 19:41:28 +05:30
if ( isLeftShiftPressed && isIPressed && __instance . inventory != null )
{
__instance . inventory . inventory [ 0 ]. snapMouseCursorToCenter ();
} else if (! isLeftShiftPressed && isIPressed && __instance . ItemsToGrabMenu != null )
{
__instance . ItemsToGrabMenu . inventory [ 0 ]. snapMouseCursorToCenter ();
}
#region Narrate buttons in the menu
2022-01-05 20:41:36 +05:30
if ( __instance . okButton != null && __instance . okButton . containsPoint ( x , y ))
{
2022-01-06 21:59:27 +05:30
string toSpeak = "Ok Button" ;
if ( itemGrabMenuQueryKey != toSpeak )
{
itemGrabMenuQueryKey = toSpeak ;
2022-01-07 14:04:58 +05:30
hoveredItemQueryKey = "" ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-06 21:59:27 +05:30
ScreenReader . say ( toSpeak , true );
}
2022-01-05 20:41:36 +05:30
return ;
}
if ( __instance . trashCan != null && __instance . trashCan . containsPoint ( x , y ))
{
2022-01-06 21:59:27 +05:30
string toSpeak = "Trash Can" ;
if ( itemGrabMenuQueryKey != toSpeak )
{
itemGrabMenuQueryKey = toSpeak ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
hoveredItemQueryKey = "" ;
2022-01-06 21:59:27 +05:30
ScreenReader . say ( toSpeak , true );
}
2022-01-05 20:41:36 +05:30
return ;
}
if ( __instance . dropItemInvisibleButton != null && __instance . dropItemInvisibleButton . containsPoint ( x , y ))
{
2022-01-06 21:59:27 +05:30
string toSpeak = "Drop Item" ;
if ( itemGrabMenuQueryKey != toSpeak )
{
itemGrabMenuQueryKey = toSpeak ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
hoveredItemQueryKey = "" ;
2022-01-06 21:59:27 +05:30
ScreenReader . say ( toSpeak , true );
Game1 . playSound ( "sa_drop_item" );
}
2022-01-05 20:41:36 +05:30
return ;
}
2022-01-06 19:41:28 +05:30
#endregion
#region Narrate the last shipped item if in the shipping bin
2022-01-05 20:41:36 +05:30
if ( __instance . shippingBin && Game1 . getFarm (). lastItemShipped != null && __instance . lastShippedHolder . containsPoint ( x , y ))
{
Item lastShippedItem = Game1 . getFarm (). lastItemShipped ;
string name = lastShippedItem . DisplayName ;
int count = lastShippedItem . Stack ;
string toSpeak = $"Last Shipped: {count} {name}" ;
2022-01-07 14:04:58 +05:30
if ( itemGrabMenuQueryKey != toSpeak )
{
itemGrabMenuQueryKey = toSpeak ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
}
2022-01-05 20:41:36 +05:30
return ;
2022-01-06 19:41:28 +05:30
}
#endregion
#region Narrate hovered item
if ( narrateHoveredItemInInventory ( __instance . inventory . inventory , __instance . inventory . actualInventory , x , y , true ))
2022-01-07 14:04:58 +05:30
{
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
itemGrabMenuQueryKey = "" ;
2022-01-06 19:41:28 +05:30
return ;
2022-01-07 14:04:58 +05:30
}
2022-01-06 19:41:28 +05:30
2022-01-07 14:04:58 +05:30
if ( narrateHoveredItemInInventory ( __instance . ItemsToGrabMenu . inventory , __instance . ItemsToGrabMenu . actualInventory , x , y , true ))
{
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
itemGrabMenuQueryKey = "" ;
2022-01-06 19:41:28 +05:30
return ;
2022-01-07 14:04:58 +05:30
}
2022-01-06 19:41:28 +05:30
#endregion
2022-01-05 20:41:36 +05:30
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
2022-01-07 14:04:58 +05:30
internal static void CraftingPagePatch ( CraftingPage __instance , CraftingRecipe ___hoverRecipe )
2022-01-03 21:53:29 +05:30
{
try
{
int x = Game1 . getMousePosition ( true ). X , y = Game1 . getMousePosition ( true ). Y ; // Mouse x and y position
2022-01-07 14:04:58 +05:30
#region Narrate buttons in the menu
if ( __instance . upButton != null && __instance . upButton . containsPoint ( x , y ))
2022-01-03 21:53:29 +05:30
{
2022-01-07 14:04:58 +05:30
string toSpeak = "Previous Recipe List" ;
if ( craftingPageQueryKey != toSpeak )
{
craftingPageQueryKey = toSpeak ;
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
}
2022-01-03 21:53:29 +05:30
return ;
}
2022-01-07 14:04:58 +05:30
2022-01-03 21:53:29 +05:30
if ( __instance . downButton != null && __instance . downButton . containsPoint ( x , y ))
{
2022-01-07 14:04:58 +05:30
string toSpeak = "Next Recipe List" ;
if ( craftingPageQueryKey != toSpeak )
{
craftingPageQueryKey = toSpeak ;
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
}
2022-01-03 21:53:29 +05:30
return ;
}
2022-01-07 14:04:58 +05:30
if ( __instance . trashCan . containsPoint ( x , y ))
2022-01-03 21:53:29 +05:30
{
2022-01-07 14:04:58 +05:30
string toSpeak = "Trash Can" ;
if ( craftingPageQueryKey != toSpeak )
{
craftingPageQueryKey = toSpeak ;
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
}
2022-01-03 21:53:29 +05:30
return ;
}
2022-01-07 14:04:58 +05:30
if ( __instance . dropItemInvisibleButton . containsPoint ( x , y ))
2022-01-05 20:41:36 +05:30
{
2022-01-07 14:04:58 +05:30
string toSpeak = "Drop Item" ;
if ( craftingPageQueryKey != toSpeak )
{
craftingPageQueryKey = toSpeak ;
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
Game1 . playSound ( "sa_drop_item" );
}
2022-01-05 20:41:36 +05:30
return ;
}
2022-01-07 14:04:58 +05:30
#endregion
#region Narrate hovered recipe
if ( ___hoverRecipe != null )
{
string name = ___hoverRecipe . DisplayName ;
int numberOfProduce = ___hoverRecipe . numberProducedPerCraft ;
string description = "" ;
string ingredients = "" ;
string buffs = "" ;
2022-01-07 14:17:00 +05:30
string craftable = "" ;
2022-01-07 14:04:58 +05:30
description = $"Description:\n{___hoverRecipe.description}" ;
2022-01-07 14:17:00 +05:30
craftable = ___hoverRecipe . doesFarmerHaveIngredientsInInventory ( getContainerContents ( __instance . _materialContainers )) ? "Craftable" : "Not Craftable" ;
2022-01-07 14:04:58 +05:30
#region Crafting ingredients
ingredients = "Ingredients:\n" ;
for ( int i = 0 ; i < ___hoverRecipe . recipeList . Count ; i ++)
{
int recipeCount = ___hoverRecipe . recipeList . ElementAt ( i ). Value ;
int recipeItem = ___hoverRecipe . recipeList . ElementAt ( i ). Key ;
string recipeName = ___hoverRecipe . getNameFromIndex ( recipeItem );
ingredients += $" ,{recipeCount} {recipeName}" ;
}
#endregion
#region Health & stamina and buff items ( effects like + 1 walking speed )
Item producesItem = ___hoverRecipe . createItem ();
if ( producesItem is StardewValley . Object && ( producesItem as StardewValley . Object ). Edibility != - 300 )
{
int stamina_recovery = ( producesItem as StardewValley . Object ). staminaRecoveredOnConsumption ();
buffs += $"{stamina_recovery} Energy" ;
if ( stamina_recovery >= 0 )
{
int health_recovery = ( producesItem as StardewValley . Object ). healthRecoveredOnConsumption ();
buffs += $"\n{health_recovery} Health" ;
}
}
// These variables are taken from the game's code itself (IClickableMenu.cs -> 1016 line)
bool edibleItem = producesItem != null && producesItem is StardewValley . Object && ( int )( producesItem as StardewValley . Object ). edibility != - 300 ;
string [] buffIconsToDisplay = ( edibleItem && Game1 . objectInformation [( producesItem as StardewValley . Object ). parentSheetIndex ]. Split ( '/' ). Length > 7 ) ? producesItem . ModifyItemBuffs ( Game1 . objectInformation [( producesItem as StardewValley . Object ). parentSheetIndex ]. Split ( '/' )[ 7 ]. Split ( ' ' )) : null ;
if ( buffIconsToDisplay != null )
{
for ( int j = 0 ; j < buffIconsToDisplay . Length ; j ++)
{
string buffName = (( Convert . ToInt32 ( buffIconsToDisplay [ j ]) > 0 ) ? "+" : "" ) + buffIconsToDisplay [ j ] + " " ;
if ( j <= 11 )
{
buffName = Game1 . content . LoadString ( "Strings\\UI:ItemHover_Buff" + j , buffName );
}
try
{
int count = int . Parse ( buffName . Substring ( 0 , buffName . IndexOf ( ' ' )));
if ( count != 0 )
buffs += $"{buffName}\n" ;
}
catch ( Exception ) { }
}
buffs = $"Buffs and boosts:\n {buffs}" ;
}
#endregion
2022-01-07 14:17:00 +05:30
string toSpeak = $"{numberOfProduce} {name}, {craftable}, \n\t{ingredients}, \n\t{description} \n\t{buffs}" ;
2022-01-07 14:04:58 +05:30
if ( craftingPageQueryKey != toSpeak )
{
craftingPageQueryKey = toSpeak ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
}
return ;
}
#endregion
#region Narrate hovered item
if ( narrateHoveredItemInInventory ( __instance . inventory . inventory , __instance . inventory . actualInventory , x , y ))
{
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
craftingPageQueryKey = "" ;
return ;
}
#endregion
2022-01-05 20:41:36 +05:30
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
2022-01-07 14:17:00 +05:30
// This method is used to get the inventory items to check if the player has enough ingredients for a recipe
// Taken from CraftingPage.cs -> 169 line
internal static IList < Item > getContainerContents ( List < Chest > materialContainers )
{
if ( materialContainers == null )
{
return null ;
}
List < Item > items = new List < Item >();
for ( int i = 0 ; i < materialContainers . Count ; i ++)
{
items . AddRange ( materialContainers [ i ]. items );
}
return items ;
}
2022-01-06 19:41:28 +05:30
internal static void InventoryPagePatch ( InventoryPage __instance )
2022-01-05 20:41:36 +05:30
{
try
{
int x = Game1 . getMousePosition ( true ). X , y = Game1 . getMousePosition ( true ). Y ; // Mouse x and y position
2022-01-06 19:41:28 +05:30
if ( __instance . inventory . dropItemInvisibleButton != null && __instance . inventory . dropItemInvisibleButton . containsPoint ( x , y ))
2022-01-03 21:53:29 +05:30
{
2022-01-07 14:04:58 +05:30
string toSpeak = "Drop Item" ;
if ( inventoryPageQueryKey != toSpeak )
{
inventoryPageQueryKey = toSpeak ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:04:58 +05:30
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
Game1 . playSound ( "sa_drop_item" );
}
2022-01-03 21:53:29 +05:30
return ;
}
2022-01-06 19:41:28 +05:30
2022-01-07 14:36:15 +05:30
#region Narrate equipment slots
for ( int i = 0 ; i < __instance . equipmentIcons . Count ; i ++)
{
if ( __instance . equipmentIcons [ i ]. containsPoint ( x , y ))
{
string toSpeak = "" ;
#region Get name and description of the item
switch ( __instance . equipmentIcons [ i ]. name )
{
case "Hat" :
{
if ( Game1 . player . hat . Value != null )
{
toSpeak = $"{Game1.player.hat.Value.DisplayName}, {Game1.player.hat.Value.getDescription()}" ;
}
else
{
toSpeak = "Hat slot" ;
}
}
break ;
case "Left Ring" :
{
if ( Game1 . player . leftRing . Value != null )
{
toSpeak = $"{Game1.player.leftRing.Value.DisplayName}, {Game1.player.leftRing.Value.getDescription()}" ;
}
else
{
toSpeak = "Left Ring slot" ;
}
}
break ;
case "Right Ring" :
{
if ( Game1 . player . rightRing . Value != null )
{
toSpeak = $"{Game1.player.rightRing.Value.DisplayName}, {Game1.player.rightRing.Value.getDescription()}" ;
}
else
{
toSpeak = "Right ring slot" ;
}
}
break ;
case "Boots" :
{
if ( Game1 . player . boots . Value != null )
{
toSpeak = $"{Game1.player.boots.Value.DisplayName}, {Game1.player.boots.Value.getDescription()}" ;
}
else
{
toSpeak = "Boots slot" ;
}
}
break ;
case "Shirt" :
{
if ( Game1 . player . shirtItem . Value != null )
{
toSpeak = $"{Game1.player.shirtItem.Value.DisplayName}, {Game1.player.shirtItem.Value.getDescription()}" ;
}
else
{
toSpeak = "Shirt slot" ;
}
}
break ;
case "Pants" :
{
if ( Game1 . player . pantsItem . Value != null )
{
toSpeak = $"{Game1.player.pantsItem.Value.DisplayName}, {Game1.player.pantsItem.Value.getDescription()}" ;
}
else
{
toSpeak = "Pants slot" ;
}
}
break ;
}
#endregion
if ( inventoryPageQueryKey != toSpeak )
{
inventoryPageQueryKey = toSpeak ;
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-07 14:36:15 +05:30
hoveredItemQueryKey = "" ;
ScreenReader . say ( toSpeak , true );
}
return ;
}
}
#endregion
2022-01-06 19:41:28 +05:30
#region Narrate hovered item
2022-01-07 14:04:58 +05:30
if ( narrateHoveredItemInInventory ( __instance . inventory . inventory , __instance . inventory . actualInventory , x , y , true ))
{
2022-01-07 14:57:57 +05:30
gameMenuQueryKey = "" ;
2022-01-06 21:59:27 +05:30
inventoryPageQueryKey = "" ;
2022-01-07 14:04:58 +05:30
return ;
}
2022-01-06 19:41:28 +05:30
#endregion
2022-01-03 21:53:29 +05:30
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
internal static void OptionsPagePatch ( OptionsPage __instance )
{
try
{
int currentItemIndex = Math . Max ( 0 , Math . Min ( __instance . options . Count - 7 , __instance . currentItemIndex ));
int x = Game1 . getMousePosition ( true ). X , y = Game1 . getMousePosition ( true ). Y ;
for ( int i = 0 ; i < __instance . optionSlots . Count ; i ++)
{
if ( __instance . optionSlots [ i ]. bounds . Contains ( x , y ) && currentItemIndex + i < __instance . options . Count && __instance . options [ currentItemIndex + i ]. bounds . Contains ( x - __instance . optionSlots [ i ]. bounds . X , y - __instance . optionSlots [ i ]. bounds . Y ))
{
OptionsElement optionsElement = __instance . options [ currentItemIndex + i ];
string toSpeak = optionsElement . label ;
if ( optionsElement is OptionsButton )
toSpeak = $" {toSpeak} Button" ;
else if ( optionsElement is OptionsCheckbox )
toSpeak = (( optionsElement as OptionsCheckbox ). isChecked ? "Enabled" : "Disabled" ) + $" {toSpeak} Checkbox" ;
else if ( optionsElement is OptionsDropDown )
toSpeak = $"{toSpeak} Dropdown, option {(optionsElement as OptionsDropDown).dropDownDisplayOptions[(optionsElement as OptionsDropDown).selectedOption]} selected" ;
else if ( optionsElement is OptionsSlider )
toSpeak = $"{(optionsElement as OptionsSlider).value}% {toSpeak} Slider" ;
else if ( optionsElement is OptionsPlusMinus )
toSpeak = $"{(optionsElement as OptionsPlusMinus).displayOptions[(optionsElement as OptionsPlusMinus).selected]} selected of {toSpeak}" ;
else if ( optionsElement is OptionsInputListener )
{
string buttons = "" ;
( optionsElement as OptionsInputListener ). buttonNames . ForEach ( name => { buttons += $", {name}" ; });
toSpeak = $"{toSpeak} is bound to {buttons}. Left click to change." ;
}
else
{
if ( toSpeak . Contains ( ":" ))
toSpeak = toSpeak . Replace ( ":" , "" );
toSpeak = $"{toSpeak} Options:" ;
}
2022-01-07 14:57:57 +05:30
if ( optionsPageQueryKey != toSpeak )
{
gameMenuQueryKey = "" ;
optionsPageQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
2022-01-03 21:53:29 +05:30
}
}
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
internal static void ExitPagePatch ( ExitPage __instance )
{
try
{
if ( __instance . exitToTitle . visible &&
__instance . exitToTitle . containsPoint ( Game1 . getMousePosition ( true ). X , Game1 . getMousePosition ( true ). Y ))
{
2022-01-07 14:57:57 +05:30
string toSpeak = "Exit to Title Button" ;
if ( exitPageQueryKey != toSpeak )
{
gameMenuQueryKey = "" ;
exitPageQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
2022-01-03 21:53:29 +05:30
}
if ( __instance . exitToDesktop . visible &&
__instance . exitToDesktop . containsPoint ( Game1 . getMousePosition ( true ). X , Game1 . getMousePosition ( true ). Y ))
{
2022-01-07 14:57:57 +05:30
string toSpeak = "Exit to Desktop Button" ;
if ( exitPageQueryKey != toSpeak )
{
gameMenuQueryKey = "" ;
exitPageQueryKey = toSpeak ;
ScreenReader . say ( toSpeak , true );
}
return ;
2022-01-03 21:53:29 +05:30
}
}
catch ( Exception e )
{
MainClass . monitor . Log ( $"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}" , LogLevel . Error );
}
}
2022-01-06 19:41:28 +05:30
2022-01-06 20:06:22 +05:30
internal static bool narrateHoveredItemInInventory ( List < ClickableComponent > inventory , IList < Item > actualInventory , int x , int y , bool giveExtraDetails = false )
2022-01-06 19:41:28 +05:30
{
#region Narrate hovered item
for ( int i = 0 ; i < inventory . Count ; i ++)
{
if ( inventory [ i ]. containsPoint ( x , y ))
{
string toSpeak = "" ;
if (( i + 1 ) <= actualInventory . Count )
{
if ( actualInventory [ i ] != null )
{
string name = actualInventory [ i ]. DisplayName ;
int stack = actualInventory [ i ]. Stack ;
string quality = "" ;
2022-01-06 20:06:22 +05:30
string healthNStamine = "" ;
string buffs = "" ;
string description = "" ;
2022-01-06 19:41:28 +05:30
#region Add quality of item
if ( actualInventory [ i ] is StardewValley . Object && ( actualInventory [ i ] as StardewValley . Object ). quality > 0 )
{
int qualityIndex = ( actualInventory [ i ] as StardewValley . Object ). quality ;
if ( qualityIndex == 1 )
{
quality = "Silver quality" ;
}
else if ( qualityIndex == 2 || qualityIndex == 3 )
{
quality = "Gold quality" ;
}
else if ( qualityIndex >= 4 )
{
quality = "Iridium quality" ;
}
}
#endregion
2022-01-06 20:06:22 +05:30
if ( giveExtraDetails )
{
description = actualInventory [ i ]. getDescription ();
#region Add health & stamina provided by the item
if ( actualInventory [ i ] is StardewValley . Object && ( actualInventory [ i ] as StardewValley . Object ). Edibility != - 300 )
{
int stamina_recovery = ( actualInventory [ i ] as StardewValley . Object ). staminaRecoveredOnConsumption ();
healthNStamine += $"{stamina_recovery} Energy" ;
if ( stamina_recovery >= 0 )
{
int health_recovery = ( actualInventory [ i ] as StardewValley . Object ). healthRecoveredOnConsumption ();
healthNStamine += $"\n\t{health_recovery} Health" ;
}
}
#endregion
2022-01-06 19:41:28 +05:30
2022-01-06 20:06:22 +05:30
#region Add buff items ( effects like + 1 walking speed )
// These variables are taken from the game's code itself (IClickableMenu.cs -> 1016 line)
bool edibleItem = actualInventory [ i ] != null && actualInventory [ i ] is StardewValley . Object && ( int )( actualInventory [ i ] as StardewValley . Object ). edibility != - 300 ;
string [] buffIconsToDisplay = ( edibleItem && Game1 . objectInformation [( actualInventory [ i ] as StardewValley . Object ). parentSheetIndex ]. Split ( '/' ). Length > 7 ) ? actualInventory [ i ]. ModifyItemBuffs ( Game1 . objectInformation [( actualInventory [ i ] as StardewValley . Object ). parentSheetIndex ]. Split ( '/' )[ 7 ]. Split ( ' ' )) : null ;
if ( buffIconsToDisplay != null )
{
for ( int j = 0 ; j < buffIconsToDisplay . Length ; j ++)
{
string buffName = (( Convert . ToInt32 ( buffIconsToDisplay [ j ]) > 0 ) ? "+" : "" ) + buffIconsToDisplay [ j ] + " " ;
if ( j <= 11 )
{
buffName = Game1 . content . LoadString ( "Strings\\UI:ItemHover_Buff" + j , buffName );
}
try
{
int count = int . Parse ( buffName . Substring ( 0 , buffName . IndexOf ( ' ' )));
if ( count != 0 )
buffs += $"{buffName}\n" ;
}
catch ( Exception ) { }
}
}
#endregion
}
if ( giveExtraDetails )
{
if ( stack > 1 )
toSpeak = $"{stack} {name} {quality}, \n{description}, \n{healthNStamine}, \n{buffs}" ;
else
toSpeak = $"{name} {quality}, \n{description}, \n{healthNStamine}, \n{buffs}" ;
}
else
{
if ( stack > 1 )
toSpeak = $"{stack} {name} {quality}" ;
else
toSpeak = $"{name} {quality}" ;
}
2022-01-06 19:41:28 +05:30
}
else
{
// For empty slot
toSpeak = "Empty Slot" ;
}
}
else
{
// For empty slot
toSpeak = "Empty Slot" ;
}
2022-01-06 21:59:27 +05:30
if ( hoveredItemQueryKey != $"{toSpeak}:{i}" )
2022-01-06 19:41:28 +05:30
{
2022-01-06 21:59:27 +05:30
hoveredItemQueryKey = $"{toSpeak}:{i}" ;
2022-01-06 19:41:28 +05:30
ScreenReader . say ( toSpeak , true );
}
return true ;
}
}
#endregion
return false ;
}
2022-01-03 21:53:29 +05:30
}
}