Refactored code BuildingNAnimalMenuPatches.cs

master
Mohammad Shoaib Khan 2023-02-23 21:41:05 +05:30
parent d12ecf0fae
commit 6d3962ea4d
No known key found for this signature in database
GPG Key ID: D8040D966320B620
9 changed files with 782 additions and 741 deletions

View File

@ -1,4 +1,5 @@
using Microsoft.Xna.Framework;
using stardew_access.Features;
using stardew_access.Patches;
using StardewModdingAPI;
using StardewValley;
@ -327,18 +328,18 @@ namespace stardew_access
return;
}
BuildingNAnimalMenuPatches.marked[index] = new Vector2((int)Game1.player.getTileX(), (int)Game1.player.getTileY());
BuildingOperations.marked[index] = new Vector2((int)Game1.player.getTileX(), (int)Game1.player.getTileY());
MainClass.InfoLog($"Location {(int)Game1.player.getTileX()}x {(int)Game1.player.getTileY()}y added at {index} index.");
});
helper.ConsoleCommands.Add("marklist", "List all marked positions.", (string commmand, string[] args) =>
{
string toPrint = "";
for (int i = 0; i < BuildingNAnimalMenuPatches.marked.Length; i++)
for (int i = 0; i < BuildingOperations.marked.Length; i++)
{
if (BuildingNAnimalMenuPatches.marked[i] != Vector2.Zero)
if (BuildingOperations.marked[i] != Vector2.Zero)
{
toPrint = $"{toPrint}\n Index {i}: {BuildingNAnimalMenuPatches.marked[i].X}x {BuildingNAnimalMenuPatches.marked[i].Y}y";
toPrint = $"{toPrint}\n Index {i}: {BuildingOperations.marked[i].X}x {BuildingOperations.marked[i].Y}y";
}
}
@ -355,7 +356,7 @@ namespace stardew_access
helper.ConsoleCommands.Add("buildsel", "Select the building index which you want to upgrade/demolish/paint", (string commmand, string[] args) =>
{
if ((Game1.activeClickableMenu is not CarpenterMenu && Game1.activeClickableMenu is not PurchaseAnimalsMenu && Game1.activeClickableMenu is not AnimalQueryMenu) || !BuildingNAnimalMenuPatches.isOnFarm)
if ((Game1.activeClickableMenu is not CarpenterMenu && Game1.activeClickableMenu is not PurchaseAnimalsMenu && Game1.activeClickableMenu is not AnimalQueryMenu) || !CarpenterMenuPatch.isOnFarm)
{
MainClass.InfoLog($"Cannot select building.");
return;
@ -380,12 +381,12 @@ namespace stardew_access
string? positionIndexInString = args.ElementAtOrDefault(1);
int positionIndex = 0;
if (BuildingNAnimalMenuPatches.isMoving)
if (CarpenterMenuPatch.isMoving)
{
if (BuildingNAnimalMenuPatches.isConstructing || BuildingNAnimalMenuPatches.isMoving)
if (CarpenterMenuPatch.isConstructing || CarpenterMenuPatch.isMoving)
{
if (BuildingNAnimalMenuPatches.availableBuildings[index] == null)
if (BuildingOperations.availableBuildings[index] == null)
{
MainClass.InfoLog($"No building found with index {index}. Use buildlist.");
return;
@ -406,9 +407,9 @@ namespace stardew_access
}
}
}
else if (BuildingNAnimalMenuPatches.isConstructing && !BuildingNAnimalMenuPatches.isUpgrading)
else if (CarpenterMenuPatch.isConstructing && !CarpenterMenuPatch.isUpgrading)
{
if (BuildingNAnimalMenuPatches.marked[index] == Vector2.Zero)
if (BuildingOperations.marked[index] == Vector2.Zero)
{
MainClass.InfoLog($"No marked position found at {index} index.");
return;
@ -416,7 +417,7 @@ namespace stardew_access
}
else
{
if (BuildingNAnimalMenuPatches.availableBuildings[index] == null)
if (BuildingOperations.availableBuildings[index] == null)
{
MainClass.InfoLog($"No building found with index {index}. Use buildlist.");
return;
@ -427,19 +428,19 @@ namespace stardew_access
if (Game1.activeClickableMenu is PurchaseAnimalsMenu)
{
BuildingNAnimalMenuPatches.PurchaseAnimal(BuildingNAnimalMenuPatches.availableBuildings[index]);
BuildingOperations.PurchaseAnimal(BuildingOperations.availableBuildings[index]);
}
else if (Game1.activeClickableMenu is AnimalQueryMenu)
{
BuildingNAnimalMenuPatches.MoveAnimal(BuildingNAnimalMenuPatches.availableBuildings[index]);
BuildingOperations.MoveAnimal(BuildingOperations.availableBuildings[index]);
}
else
{
if (BuildingNAnimalMenuPatches.isConstructing && !BuildingNAnimalMenuPatches.isUpgrading) { response = BuildingNAnimalMenuPatches.Contstruct(BuildingNAnimalMenuPatches.marked[index]); }
else if (BuildingNAnimalMenuPatches.isMoving) { response = BuildingNAnimalMenuPatches.Move(BuildingNAnimalMenuPatches.availableBuildings[index], BuildingNAnimalMenuPatches.marked[positionIndex]); }
else if (BuildingNAnimalMenuPatches.isDemolishing) { response = BuildingNAnimalMenuPatches.Demolish(BuildingNAnimalMenuPatches.availableBuildings[index]); }
else if (BuildingNAnimalMenuPatches.isUpgrading) { response = BuildingNAnimalMenuPatches.Upgrade(BuildingNAnimalMenuPatches.availableBuildings[index]); }
else if (BuildingNAnimalMenuPatches.isPainting) { response = BuildingNAnimalMenuPatches.Paint(BuildingNAnimalMenuPatches.availableBuildings[index]); }
if (CarpenterMenuPatch.isConstructing && !CarpenterMenuPatch.isUpgrading) { response = BuildingOperations.Contstruct(BuildingOperations.marked[index]); }
else if (CarpenterMenuPatch.isMoving) { response = BuildingOperations.Move(BuildingOperations.availableBuildings[index], BuildingOperations.marked[positionIndex]); }
else if (CarpenterMenuPatch.isDemolishing) { response = BuildingOperations.Demolish(BuildingOperations.availableBuildings[index]); }
else if (CarpenterMenuPatch.isUpgrading) { response = BuildingOperations.Upgrade(BuildingOperations.availableBuildings[index]); }
else if (CarpenterMenuPatch.isPainting) { response = BuildingOperations.Paint(BuildingOperations.availableBuildings[index]); }
}
if (response != null)
@ -517,7 +518,7 @@ namespace stardew_access
string? name = buildings[i].nameOfIndoorsWithoutUnique;
name = (name == "null") ? buildings[i].buildingType.Value : name;
BuildingNAnimalMenuPatches.availableBuildings[buildingIndex] = buildings[i];
BuildingOperations.availableBuildings[buildingIndex] = buildings[i];
toPrint = $"{toPrint}\nIndex {buildingIndex}: {name}: At {buildings[i].tileX}x and {buildings[i].tileY}y";
++buildingIndex;
}

View File

@ -0,0 +1,366 @@
using Microsoft.Xna.Framework;
using stardew_access.Patches;
using StardewValley;
using StardewValley.Buildings;
using StardewValley.Locations;
using StardewValley.Objects;
namespace stardew_access.Features
{
internal class BuildingOperations
{
internal static Building?[] availableBuildings = new Building[100];
internal static Vector2[] marked = new Vector2[10];
public static string? Demolish(Building? toDemolish)
{
if (toDemolish == null)
return null;
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::654)
Farm farm = (Farm)Game1.getLocationFromName("Farm");
Action buildingLockFailed = delegate
{
if (CarpenterMenuPatch.isDemolishing)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_LockFailed");
}
};
Action continueDemolish = delegate
{
if (CarpenterMenuPatch.isDemolishing && toDemolish != null && farm.buildings.Contains(toDemolish))
{
if ((int)toDemolish.daysOfConstructionLeft.Value > 0 || (int)toDemolish.daysUntilUpgrade.Value > 0)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_DuringConstruction");
}
else if (toDemolish.indoors.Value != null && toDemolish.indoors.Value is AnimalHouse && ((AnimalHouse)toDemolish.indoors.Value).animalsThatLiveHere.Count > 0)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_AnimalsHere");
}
else if (toDemolish.indoors.Value != null && toDemolish.indoors.Value.farmers.Any())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_PlayerHere");
}
else
{
if (toDemolish.indoors.Value != null && toDemolish.indoors.Value is Cabin)
{
foreach (Farmer current in Game1.getAllFarmers())
{
if (current.currentLocation != null && current.currentLocation.Name == ((Cabin)toDemolish.indoors.Value).GetCellarName())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_PlayerHere");
return;
}
}
}
if (toDemolish.indoors.Value is Cabin && ((Cabin)toDemolish.indoors.Value).farmhand.Value.isActive())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_FarmhandOnline");
}
else
{
toDemolish.BeforeDemolish();
Chest? chest = null;
if (toDemolish.indoors.Value is Cabin)
{
List<Item> list = ((Cabin)toDemolish.indoors.Value).demolish();
if (list.Count > 0)
{
chest = new Chest(playerChest: true);
chest.fixLidFrame();
chest.items.Set(list);
}
}
if (farm.destroyStructure(toDemolish))
{
_ = (int)toDemolish.tileY.Value;
_ = (int)toDemolish.tilesHigh.Value;
Game1.flashAlpha = 1f;
toDemolish.showDestroyedAnimation(Game1.getFarm());
Game1.playSound("explosion");
Utility.spreadAnimalsAround(toDemolish, farm);
if (CarpenterMenuPatch.carpenterMenu != null)
DelayedAction.functionAfterDelay(CarpenterMenuPatch.carpenterMenu.returnToCarpentryMenu, 1500);
// freeze = true;
if (chest != null)
{
farm.objects[new Vector2((int)toDemolish.tileX.Value + (int)toDemolish.tilesWide.Value / 2, (int)toDemolish.tileY.Value + (int)toDemolish.tilesHigh.Value / 2)] = chest;
}
}
}
}
}
};
if (toDemolish != null)
{
if (toDemolish.indoors.Value != null && toDemolish.indoors.Value is Cabin && !Game1.IsMasterGame)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_LockFailed");
toDemolish = null;
return response;
}
if (CarpenterMenuPatch.carpenterMenu != null && !CarpenterMenuPatch.carpenterMenu.CanDemolishThis(toDemolish))
{
toDemolish = null;
return response;
}
if (CarpenterMenuPatch.carpenterMenu != null && !Game1.IsMasterGame && !CarpenterMenuPatch.carpenterMenu.hasPermissionsToDemolish(toDemolish))
{
toDemolish = null;
return response;
}
}
if (toDemolish != null && toDemolish.indoors.Value is Cabin)
{
Cabin cabin = (Cabin)toDemolish.indoors.Value;
if (cabin.farmhand.Value != null && (bool)cabin.farmhand.Value.isCustomized.Value)
{
Game1.currentLocation.createQuestionDialogue(Game1.content.LoadString("Strings\\UI:Carpenter_DemolishCabinConfirm", cabin.farmhand.Value.Name), Game1.currentLocation.createYesNoResponses(), delegate (Farmer f, string answer)
{
if (answer == "Yes")
{
Game1.activeClickableMenu = CarpenterMenuPatch.carpenterMenu;
Game1.player.team.demolishLock.RequestLock(continueDemolish, buildingLockFailed);
}
else
{
if (CarpenterMenuPatch.carpenterMenu != null)
DelayedAction.functionAfterDelay(CarpenterMenuPatch.carpenterMenu.returnToCarpentryMenu, 1000);
}
});
return response;
}
}
if (toDemolish != null)
{
Game1.player.team.demolishLock.RequestLock(continueDemolish, buildingLockFailed);
}
return response;
}
public static string? Contstruct(Vector2 position)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::874)
Game1.player.team.buildLock.RequestLock(delegate
{
if (CarpenterMenuPatch.isOnFarm && Game1.locationRequest == null)
{
if (tryToBuild(position))
{
if (CarpenterMenuPatch.carpenterMenu != null)
{
CarpenterMenuPatch.carpenterMenu.CurrentBlueprint.consumeResources();
DelayedAction.functionAfterDelay(CarpenterMenuPatch.carpenterMenu.returnToCarpentryMenuAfterSuccessfulBuild, 2000);
}
// freeze = true;
}
else
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantBuild");
}
}
Game1.player.team.buildLock.ReleaseLock();
});
return response;
}
public static bool tryToBuild(Vector2 position)
{
if (CarpenterMenuPatch.carpenterMenu == null)
return false;
return ((Farm)Game1.getLocationFromName("Farm")).buildStructure(CarpenterMenuPatch.carpenterMenu.CurrentBlueprint, position, Game1.player, CarpenterMenuPatch.isMagicalConstruction);
}
public static string? Upgrade(Building? toUpgrade)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::775)
if (CarpenterMenuPatch.carpenterMenu != null && toUpgrade != null && CarpenterMenuPatch.carpenterMenu.CurrentBlueprint.name != null && toUpgrade.buildingType.Equals(CarpenterMenuPatch.carpenterMenu.CurrentBlueprint.nameOfBuildingToUpgrade))
{
CarpenterMenuPatch.carpenterMenu.CurrentBlueprint.consumeResources();
toUpgrade.daysUntilUpgrade.Value = 2;
toUpgrade.showUpgradeAnimation(Game1.getFarm());
Game1.playSound("axe");
DelayedAction.functionAfterDelay(CarpenterMenuPatch.carpenterMenu.returnToCarpentryMenuAfterSuccessfulBuild, 1500);
// freeze = true;
// Game1.multiplayer.globalChatInfoMessage("BuildingBuild", Game1.player.Name, Utility.AOrAn(carpenterMenu.CurrentBlueprint.displayName), carpenterMenu.CurrentBlueprint.displayName, Game1.player.farmName.Value);
}
else if (toUpgrade != null)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantUpgrade_BuildingType");
}
return response;
}
public static string? Paint(Building? toPaint)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::793)
Farm farm_location = Game1.getFarm();
if (toPaint != null)
{
if (!toPaint.CanBePainted())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint");
return response;
}
if (CarpenterMenuPatch.carpenterMenu != null && !CarpenterMenuPatch.carpenterMenu.HasPermissionsToPaint(toPaint))
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint_Permission");
return response;
}
toPaint.color.Value = Color.White;
if (CarpenterMenuPatch.carpenterMenu != null)
CarpenterMenuPatch.carpenterMenu.SetChildMenu(new StardewValley.Menus.BuildingPaintMenu(toPaint));
}
/* TODO Add painting of farm house
else if (farm_location.GetHouseRect().Contains(Utility.Vector2ToPoint(new Vector2(toPaint.tileX, toPaint.tileY))))
{
if (!carpenterMenu.CanPaintHouse())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint");
}
else if (!carpenterMenu.HasPermissionsToPaint(null))
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint_Permission");
}
else
{
carpenterMenu.SetChildMenu(new BuildingPaintMenu("House", () => (farm_location.paintedHouseTexture != null) ? farm_location.paintedHouseTexture : Farm.houseTextures, farm_location.houseSource.Value, farm_location.housePaintColor.Value));
}
}*/
return response;
}
public static string? Move(Building? buildingToMove, Vector2 position)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::829)
if (buildingToMove != null)
{
string? name = buildingToMove.nameOfIndoorsWithoutUnique;
name = (name == "null") ? buildingToMove.buildingType.Value : name;
if ((int)buildingToMove.daysOfConstructionLeft.Value > 0)
{
buildingToMove = null;
return "Building under construction, cannot move";
}
if (CarpenterMenuPatch.carpenterMenu != null && !CarpenterMenuPatch.carpenterMenu.hasPermissionsToMove(buildingToMove))
{
buildingToMove = null;
return "You don't have permission to move this building";
}
Game1.playSound("axchop");
if (((Farm)Game1.getLocationFromName("Farm")).buildStructure(buildingToMove, position, Game1.player))
{
if (buildingToMove is ShippingBin)
{
((ShippingBin)buildingToMove).initLid();
}
if (buildingToMove is GreenhouseBuilding)
{
Game1.getFarm().greenhouseMoved.Value = true;
}
buildingToMove.performActionOnBuildingPlacement();
buildingToMove = null;
Game1.playSound("axchop");
DelayedAction.playSoundAfterDelay("dirtyHit", 50);
DelayedAction.playSoundAfterDelay("dirtyHit", 150);
response = $"{buildingToMove} moved to {position.X}x {position.Y}y";
}
else
{
Game1.playSound("cancel");
response = $"Cannot move building to {position.X}x {position.Y}y";
}
}
return response;
}
public static void PurchaseAnimal(Building? selection)
{
if (selection == null)
return;
if (PurchaseAnimalsMenuPatch.purchaseAnimalsMenu == null)
return;
int x = (selection.tileX.Value * Game1.tileSize) - Game1.viewport.X;
int y = (selection.tileY.Value * Game1.tileSize) - Game1.viewport.Y;
if (PurchaseAnimalsMenuPatch.animalBeingPurchased != null && !selection.buildingType.Value.Contains(PurchaseAnimalsMenuPatch.animalBeingPurchased.buildingTypeILiveIn.Value))
{
string warn = Game1.content.LoadString("Strings\\StringsFromCSFiles:PurchaseAnimalsMenu.cs.11326", PurchaseAnimalsMenuPatch.animalBeingPurchased.displayType);
MainClass.ScreenReader.Say(warn, true);
return;
}
if (((AnimalHouse)selection.indoors.Value).isFull())
{
string warn = Game1.content.LoadString("Strings\\StringsFromCSFiles:PurchaseAnimalsMenu.cs.11321");
MainClass.ScreenReader.Say(warn, true);
return;
}
PurchaseAnimalsMenuPatch.purchaseAnimalsMenu.receiveLeftClick(x, y);
}
public static void MoveAnimal(Building? selection)
{
if (selection == null)
return;
if (AnimalQueryMenuPatch.animalQueryMenu == null)
return;
if (AnimalQueryMenuPatch.animalBeingMoved == null)
return;
// The following code is taken from the game's source code [AnimalQueryMenu.cs::receiveLeftClick]
if (selection.buildingType.Value.Contains(AnimalQueryMenuPatch.animalBeingMoved.buildingTypeILiveIn.Value))
{
if (((AnimalHouse)selection.indoors.Value).isFull())
{
string warn = Game1.content.LoadString("Strings\\UI:AnimalQuery_Moving_BuildingFull");
MainClass.ScreenReader.Say(warn, true);
return;
}
if (selection.Equals(AnimalQueryMenuPatch.animalBeingMoved.home))
{
string warn = Game1.content.LoadString("Strings\\UI:AnimalQuery_Moving_AlreadyHome");
MainClass.ScreenReader.Say(warn, true);
return;
}
((AnimalHouse)AnimalQueryMenuPatch.animalBeingMoved.home.indoors.Value).animalsThatLiveHere.Remove(AnimalQueryMenuPatch.animalBeingMoved.myID.Value);
if (((AnimalHouse)AnimalQueryMenuPatch.animalBeingMoved.home.indoors.Value).animals.ContainsKey(AnimalQueryMenuPatch.animalBeingMoved.myID.Value))
{
((AnimalHouse)selection.indoors.Value).animals.Add(AnimalQueryMenuPatch.animalBeingMoved.myID.Value, AnimalQueryMenuPatch.animalBeingMoved);
((AnimalHouse)AnimalQueryMenuPatch.animalBeingMoved.home.indoors.Value).animals.Remove(AnimalQueryMenuPatch.animalBeingMoved.myID.Value);
}
AnimalQueryMenuPatch.animalBeingMoved.home = selection;
AnimalQueryMenuPatch.animalBeingMoved.homeLocation.Value = new Vector2((int)selection.tileX.Value, (int)selection.tileY.Value);
((AnimalHouse)selection.indoors.Value).animalsThatLiveHere.Add(AnimalQueryMenuPatch.animalBeingMoved.myID.Value);
AnimalQueryMenuPatch.animalBeingMoved.makeSound();
Game1.globalFadeToBlack(AnimalQueryMenuPatch.animalQueryMenu.finishedPlacingAnimal);
}
else
{
string warn = Game1.content.LoadString("Strings\\UI:AnimalQuery_Moving_CantLiveThere");
MainClass.ScreenReader.Say(warn, true);
}
return;
}
}
}

View File

@ -237,17 +237,17 @@ namespace stardew_access
harmony.Patch(
original: AccessTools.Method(typeof(CarpenterMenu), nameof(CarpenterMenu.draw), new Type[] { typeof(SpriteBatch) }),
prefix: new HarmonyMethod(typeof(BuildingNAnimalMenuPatches), nameof(BuildingNAnimalMenuPatches.CarpenterMenuPatch))
prefix: new HarmonyMethod(typeof(CarpenterMenuPatch), nameof(CarpenterMenuPatch.DrawPatch))
);
harmony.Patch(
original: AccessTools.Method(typeof(PurchaseAnimalsMenu), nameof(PurchaseAnimalsMenu.draw), new Type[] { typeof(SpriteBatch) }),
prefix: new HarmonyMethod(typeof(BuildingNAnimalMenuPatches), nameof(BuildingNAnimalMenuPatches.PurchaseAnimalsMenuPatch))
prefix: new HarmonyMethod(typeof(PurchaseAnimalsMenuPatch), nameof(PurchaseAnimalsMenuPatch.DrawPatch))
);
harmony.Patch(
original: AccessTools.Method(typeof(AnimalQueryMenu), nameof(AnimalQueryMenu.draw), new Type[] { typeof(SpriteBatch) }),
postfix: new HarmonyMethod(typeof(BuildingNAnimalMenuPatches), nameof(BuildingNAnimalMenuPatches.AnimalQueryMenuPatch))
postfix: new HarmonyMethod(typeof(AnimalQueryMenuPatch), nameof(AnimalQueryMenuPatch.DrawPatch))
);
#endregion

View File

@ -128,14 +128,14 @@ namespace stardew_access
HarmonyPatches.Initialize(harmony);
//Initialize marked locations
for (int i = 0; i < BuildingNAnimalMenuPatches.marked.Length; i++)
for (int i = 0; i < BuildingOperations.marked.Length; i++)
{
BuildingNAnimalMenuPatches.marked[i] = Vector2.Zero;
BuildingOperations.marked[i] = Vector2.Zero;
}
for (int i = 0; i < BuildingNAnimalMenuPatches.availableBuildings.Length; i++)
for (int i = 0; i < BuildingOperations.availableBuildings.Length; i++)
{
BuildingNAnimalMenuPatches.availableBuildings[i] = null;
BuildingOperations.availableBuildings[i] = null;
}
#endregion

View File

@ -0,0 +1,78 @@
using StardewValley;
using StardewValley.Menus;
namespace stardew_access.Patches
{
internal class AnimalQueryMenuPatch
{
internal static bool isNarratingAnimalInfo = false;
internal static string animalQueryMenuQuery = "";
internal static AnimalQueryMenu? animalQueryMenu;
internal static FarmAnimal? animalBeingMoved = null;
internal static bool isOnFarm = false;
internal static void DrawPatch(AnimalQueryMenu __instance, bool ___confirmingSell, FarmAnimal ___animal, TextBox ___textBox, string ___parentName, bool ___movingAnimal)
{
try
{
if (TextBoxPatch.isAnyTextBoxActive) return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For narrating animal details
string toSpeak = " ", details = " ";
isOnFarm = ___movingAnimal;
animalQueryMenu = __instance;
animalBeingMoved = ___animal;
if (isPrimaryInfoKeyPressed & !isNarratingAnimalInfo)
{
string name = ___animal.displayName;
string type = ___animal.displayType;
int age = (___animal.GetDaysOwned() + 1) / 28 + 1;
string ageText = (age <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", age);
string parent = "";
if ((int)___animal.age.Value < (byte)___animal.ageWhenMature.Value)
{
ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby");
}
if (___parentName != null)
{
parent = Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", ___parentName);
}
details = $"Name: {name} Type: {type} \n\t Age: {ageText} {parent}";
animalQueryMenuQuery = "";
isNarratingAnimalInfo = true;
Task.Delay(200).ContinueWith(_ => { isNarratingAnimalInfo = false; });
}
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
toSpeak = "OK button";
else if (__instance.sellButton != null && __instance.sellButton.containsPoint(x, y))
toSpeak = $"Sell for {___animal.getSellPrice()}g button";
else if (___confirmingSell && __instance.yesButton != null && __instance.yesButton.containsPoint(x, y))
toSpeak = "Confirm selling animal";
else if (___confirmingSell && __instance.noButton != null && __instance.noButton.containsPoint(x, y))
toSpeak = "Cancel selling animal";
else if (__instance.moveHomeButton != null && __instance.moveHomeButton.containsPoint(x, y))
toSpeak = "Change home building button";
else if (__instance.allowReproductionButton != null && __instance.allowReproductionButton.containsPoint(x, y))
toSpeak = ((___animal.allowReproduction.Value) ? "Enabled" : "Disabled") + " allow reproduction button";
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
toSpeak = "Animal name text box";
if (animalQueryMenuQuery != toSpeak)
{
animalQueryMenuQuery = toSpeak;
MainClass.ScreenReader.Say($"{details} {toSpeak}", true);
}
}
catch (System.Exception e)
{
MainClass.ErrorLog($"An error occured in AnimalQueryMenuPatch()->DrawPatch():\n{e.Message}\n{e.StackTrace}");
}
}
}
}

View File

@ -1,705 +0,0 @@
using Microsoft.Xna.Framework;
using StardewValley;
using StardewValley.Buildings;
using StardewValley.Locations;
using StardewValley.Menus;
using StardewValley.Objects;
namespace stardew_access.Patches
{
internal class BuildingNAnimalMenuPatches
{
internal static Vector2[] marked = new Vector2[10];
internal static Building?[] availableBuildings = new Building[100];
internal static CarpenterMenu? carpenterMenu = null;
internal static bool isNarratingAnimalInfo = false;
internal static string animalQueryMenuQuery = " ";
internal static string carpenterMenuQuery = "", purchaseAnimalMenuQuery = "";
internal static bool isSayingBlueprintInfo = false;
internal static string prevBlueprintInfo = "";
internal static bool isOnFarm = false, isUpgrading = false, isDemolishing = false, isPainting = false, isConstructing = false, isMoving = false, isMagicalConstruction = false;
internal static bool firstTimeInNamingMenu = true;
internal static PurchaseAnimalsMenu? purchaseAnimalsMenu;
internal static AnimalQueryMenu? animalQueryMenu;
private static FarmAnimal? animalBeingPurchasedOrMoved = null;
internal static void AnimalQueryMenuPatch(AnimalQueryMenu __instance, bool ___confirmingSell, FarmAnimal ___animal, TextBox ___textBox, string ___parentName, bool ___movingAnimal)
{
try
{
if (TextBoxPatch.isAnyTextBoxActive) return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For narrating animal details
string toSpeak = " ", details = " ";
isOnFarm = ___movingAnimal;
animalQueryMenu = __instance;
animalBeingPurchasedOrMoved = ___animal;
if (isPrimaryInfoKeyPressed & !isNarratingAnimalInfo)
{
string name = ___animal.displayName;
string type = ___animal.displayType;
int age = (___animal.GetDaysOwned() + 1) / 28 + 1;
string ageText = (age <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", age);
string parent = "";
if ((int)___animal.age.Value < (byte)___animal.ageWhenMature.Value)
{
ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby");
}
if (___parentName != null)
{
parent = Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", ___parentName);
}
details = $"Name: {name} Type: {type} \n\t Age: {ageText} {parent}";
animalQueryMenuQuery = " ";
isNarratingAnimalInfo = true;
Task.Delay(200).ContinueWith(_ => { isNarratingAnimalInfo = false; });
}
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
toSpeak = "OK button";
else if (__instance.sellButton != null && __instance.sellButton.containsPoint(x, y))
toSpeak = $"Sell for {___animal.getSellPrice()}g button";
else if (___confirmingSell && __instance.yesButton != null && __instance.yesButton.containsPoint(x, y))
toSpeak = "Confirm selling animal";
else if (___confirmingSell && __instance.noButton != null && __instance.noButton.containsPoint(x, y))
toSpeak = "Cancel selling animal";
else if (__instance.moveHomeButton != null && __instance.moveHomeButton.containsPoint(x, y))
toSpeak = "Change home building button";
else if (__instance.allowReproductionButton != null && __instance.allowReproductionButton.containsPoint(x, y))
toSpeak = ((___animal.allowReproduction.Value) ? "Enabled" : "Disabled") + " allow reproduction button";
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
toSpeak = "Animal name text box";
if (animalQueryMenuQuery != toSpeak)
{
animalQueryMenuQuery = toSpeak;
MainClass.ScreenReader.Say($"{details} {toSpeak}", true);
}
}
catch (System.Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
internal static void PurchaseAnimalsMenuPatch(PurchaseAnimalsMenu __instance, bool ___onFarm, bool ___namingAnimal, TextBox ___textBox, FarmAnimal ___animalBeingPurchased)
{
try
{
if (TextBoxPatch.isAnyTextBoxActive) return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
purchaseAnimalsMenu = __instance;
isOnFarm = ___onFarm;
animalBeingPurchasedOrMoved = ___animalBeingPurchased;
if (___onFarm && ___namingAnimal)
{
string toSpeak = "";
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
{
toSpeak = "Cancel Button";
}
else if (__instance.doneNamingButton != null && __instance.doneNamingButton.containsPoint(x, y))
{
toSpeak = "OK Button";
}
else if (__instance.randomButton != null && __instance.randomButton.containsPoint(x, y))
{
toSpeak = "Random Name Button";
}
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
{
toSpeak = "Name Text Box";
// string? value = ___textBox.Text;
// if (value != "" && value != null && value != "null")
// toSpeak = $"{toSpeak}, Value: {value}";
}
if (purchaseAnimalMenuQuery != toSpeak)
{
purchaseAnimalMenuQuery = toSpeak;
if (firstTimeInNamingMenu)
{
toSpeak = $"Enter the name of animal in the name text box. {toSpeak}";
firstTimeInNamingMenu = false;
}
MainClass.ScreenReader.Say(toSpeak, true);
}
}
else if (___onFarm && !___namingAnimal)
{
firstTimeInNamingMenu = true;
}
else if (!___onFarm && !___namingAnimal)
{
firstTimeInNamingMenu = true;
if (__instance.hovered != null)
{
string toSpeak = "";
if (((StardewValley.Object)__instance.hovered.item).Type != null)
{
toSpeak = ((StardewValley.Object)__instance.hovered.item).Type;
}
else
{
string displayName = PurchaseAnimalsMenu.getAnimalTitle(__instance.hovered.hoverText);
int price = __instance.hovered.item.salePrice();
string description = PurchaseAnimalsMenu.getAnimalDescription(__instance.hovered.hoverText);
toSpeak = $"{displayName}, Price: {price}g, Description: {description}";
}
if (purchaseAnimalMenuQuery != toSpeak)
{
purchaseAnimalMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
}
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
internal static void CarpenterMenuPatch(
CarpenterMenu __instance, bool ___onFarm, List<Item> ___ingredients, int ___price,
List<BluePrint> ___blueprints, int ___currentBlueprintIndex, bool ___upgrading, bool ___demolishing, bool ___moving,
bool ___painting, bool ___magicalConstruction)
{
try
{
isOnFarm = ___onFarm;
carpenterMenu = __instance;
isMagicalConstruction = ___magicalConstruction;
if (!___onFarm)
{
isUpgrading = false;
isDemolishing = false;
isPainting = false;
isMoving = false;
isConstructing = false;
#region The blueprint menu
BluePrint currentBluprint = __instance.CurrentBlueprint;
if (currentBluprint == null)
return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed();
string ingredients = "";
string name = currentBluprint.displayName;
string upgradeName = currentBluprint.nameOfBuildingToUpgrade;
string description = currentBluprint.description;
string price = $"{___price}g";
string blueprintInfo;
int width = currentBluprint.tilesWidth;
int height = currentBluprint.tilesHeight;
#region Get ingredients
for (int i = 0; i < ___ingredients.Count; i++)
{
string itemName = ___ingredients[i].DisplayName;
int itemStack = ___ingredients[i].Stack;
string itemQuality = "";
int qualityValue = ((StardewValley.Object)___ingredients[i]).Quality;
if (qualityValue == 1)
{
itemQuality = "Silver quality";
}
else if (qualityValue == 2 || qualityValue == 3)
{
itemQuality = "Gold quality";
}
else if (qualityValue >= 4)
{
itemQuality = "Iridium quality";
}
ingredients = $"{ingredients}, {itemStack} {itemName} {itemQuality}";
}
#endregion
blueprintInfo = $"{name}, Price: {price}, Ingredients: {ingredients}, Dimensions: {width} width and {height} height, Description: {description}";
if (isPrimaryInfoKeyPressed && !isSayingBlueprintInfo)
{
SayBlueprintInfo(blueprintInfo);
}
else if (prevBlueprintInfo != blueprintInfo)
{
prevBlueprintInfo = blueprintInfo;
SayBlueprintInfo(blueprintInfo);
}
else
{
if (__instance.backButton != null && __instance.backButton.containsPoint(x, y))
{
string toSpeak = "Previous Blueprint";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.forwardButton != null && __instance.forwardButton.containsPoint(x, y))
{
string toSpeak = "Next Blueprint";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.demolishButton != null && __instance.demolishButton.containsPoint(x, y))
{
string toSpeak = $"Demolish Building" + (__instance.CanDemolishThis(___blueprints[___currentBlueprintIndex]) ? "" : ", cannot demolish building");
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
{
string toSpeak = "Construct Building" + (___blueprints[___currentBlueprintIndex].doesFarmerHaveEnoughResourcesToBuild() ? "" : ", cannot cunstrut building, not enough resources to build.");
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.moveButton != null && __instance.moveButton.containsPoint(x, y))
{
string toSpeak = "Move Building";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.paintButton != null && __instance.paintButton.containsPoint(x, y))
{
string toSpeak = "Paint Building";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.cancelButton != null && __instance.cancelButton.containsPoint(x, y))
{
string toSpeak = "Cancel Button";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
}
#endregion
}
else
{
if (___demolishing)
isDemolishing = true;
else if (___upgrading)
isUpgrading = true;
else if (___painting)
isPainting = true;
else if (___moving)
isMoving = true;
else
isConstructing = true;
}
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
private static async void SayBlueprintInfo(string info)
{
isSayingBlueprintInfo = true;
MainClass.ScreenReader.Say(info, true);
await Task.Delay(300);
isSayingBlueprintInfo = false;
}
public static string? Demolish(Building? toDemolish)
{
if (toDemolish == null)
return null;
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::654)
Farm farm = (Farm)Game1.getLocationFromName("Farm");
Action buildingLockFailed = delegate
{
if (isDemolishing)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_LockFailed");
}
};
Action continueDemolish = delegate
{
if (isDemolishing && toDemolish != null && farm.buildings.Contains(toDemolish))
{
if ((int)toDemolish.daysOfConstructionLeft.Value > 0 || (int)toDemolish.daysUntilUpgrade.Value > 0)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_DuringConstruction");
}
else if (toDemolish.indoors.Value != null && toDemolish.indoors.Value is AnimalHouse && ((AnimalHouse)toDemolish.indoors.Value).animalsThatLiveHere.Count > 0)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_AnimalsHere");
}
else if (toDemolish.indoors.Value != null && toDemolish.indoors.Value.farmers.Any())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_PlayerHere");
}
else
{
if (toDemolish.indoors.Value != null && toDemolish.indoors.Value is Cabin)
{
foreach (Farmer current in Game1.getAllFarmers())
{
if (current.currentLocation != null && current.currentLocation.Name == ((Cabin)toDemolish.indoors.Value).GetCellarName())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_PlayerHere");
return;
}
}
}
if (toDemolish.indoors.Value is Cabin && ((Cabin)toDemolish.indoors.Value).farmhand.Value.isActive())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_FarmhandOnline");
}
else
{
toDemolish.BeforeDemolish();
Chest? chest = null;
if (toDemolish.indoors.Value is Cabin)
{
List<Item> list = ((Cabin)toDemolish.indoors.Value).demolish();
if (list.Count > 0)
{
chest = new Chest(playerChest: true);
chest.fixLidFrame();
chest.items.Set(list);
}
}
if (farm.destroyStructure(toDemolish))
{
_ = (int)toDemolish.tileY.Value;
_ = (int)toDemolish.tilesHigh.Value;
Game1.flashAlpha = 1f;
toDemolish.showDestroyedAnimation(Game1.getFarm());
Game1.playSound("explosion");
Utility.spreadAnimalsAround(toDemolish, farm);
if (carpenterMenu != null)
DelayedAction.functionAfterDelay(carpenterMenu.returnToCarpentryMenu, 1500);
// freeze = true;
if (chest != null)
{
farm.objects[new Vector2((int)toDemolish.tileX.Value + (int)toDemolish.tilesWide.Value / 2, (int)toDemolish.tileY.Value + (int)toDemolish.tilesHigh.Value / 2)] = chest;
}
}
}
}
}
};
if (toDemolish != null)
{
if (toDemolish.indoors.Value != null && toDemolish.indoors.Value is Cabin && !Game1.IsMasterGame)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantDemolish_LockFailed");
toDemolish = null;
return response;
}
if (carpenterMenu != null && !carpenterMenu.CanDemolishThis(toDemolish))
{
toDemolish = null;
return response;
}
if (carpenterMenu != null && !Game1.IsMasterGame && !carpenterMenu.hasPermissionsToDemolish(toDemolish))
{
toDemolish = null;
return response;
}
}
if (toDemolish != null && toDemolish.indoors.Value is Cabin)
{
Cabin cabin = (Cabin)toDemolish.indoors.Value;
if (cabin.farmhand.Value != null && (bool)cabin.farmhand.Value.isCustomized.Value)
{
Game1.currentLocation.createQuestionDialogue(Game1.content.LoadString("Strings\\UI:Carpenter_DemolishCabinConfirm", cabin.farmhand.Value.Name), Game1.currentLocation.createYesNoResponses(), delegate (Farmer f, string answer)
{
if (answer == "Yes")
{
Game1.activeClickableMenu = carpenterMenu;
Game1.player.team.demolishLock.RequestLock(continueDemolish, buildingLockFailed);
}
else
{
if (carpenterMenu != null)
DelayedAction.functionAfterDelay(carpenterMenu.returnToCarpentryMenu, 1000);
}
});
return response;
}
}
if (toDemolish != null)
{
Game1.player.team.demolishLock.RequestLock(continueDemolish, buildingLockFailed);
}
return response;
}
public static string? Contstruct(Vector2 position)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::874)
Game1.player.team.buildLock.RequestLock(delegate
{
if (isOnFarm && Game1.locationRequest == null)
{
if (tryToBuild(position))
{
if (carpenterMenu != null)
{
carpenterMenu.CurrentBlueprint.consumeResources();
DelayedAction.functionAfterDelay(carpenterMenu.returnToCarpentryMenuAfterSuccessfulBuild, 2000);
}
// freeze = true;
}
else
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantBuild");
}
}
Game1.player.team.buildLock.ReleaseLock();
});
return response;
}
public static bool tryToBuild(Vector2 position)
{
if (carpenterMenu == null)
return false;
return ((Farm)Game1.getLocationFromName("Farm")).buildStructure(carpenterMenu.CurrentBlueprint, position, Game1.player, isMagicalConstruction);
}
public static string? Upgrade(Building? toUpgrade)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::775)
if (carpenterMenu != null && toUpgrade != null && carpenterMenu.CurrentBlueprint.name != null && toUpgrade.buildingType.Equals(carpenterMenu.CurrentBlueprint.nameOfBuildingToUpgrade))
{
carpenterMenu.CurrentBlueprint.consumeResources();
toUpgrade.daysUntilUpgrade.Value = 2;
toUpgrade.showUpgradeAnimation(Game1.getFarm());
Game1.playSound("axe");
DelayedAction.functionAfterDelay(carpenterMenu.returnToCarpentryMenuAfterSuccessfulBuild, 1500);
// freeze = true;
// Game1.multiplayer.globalChatInfoMessage("BuildingBuild", Game1.player.Name, Utility.AOrAn(carpenterMenu.CurrentBlueprint.displayName), carpenterMenu.CurrentBlueprint.displayName, Game1.player.farmName.Value);
}
else if (toUpgrade != null)
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CantUpgrade_BuildingType");
}
return response;
}
public static string? Paint(Building? toPaint)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::793)
Farm farm_location = Game1.getFarm();
if (toPaint != null)
{
if (!toPaint.CanBePainted())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint");
return response;
}
if (carpenterMenu != null && !carpenterMenu.HasPermissionsToPaint(toPaint))
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint_Permission");
return response;
}
toPaint.color.Value = Color.White;
if (carpenterMenu != null)
carpenterMenu.SetChildMenu(new BuildingPaintMenu(toPaint));
}
/* TODO Add painting of farm house
else if (farm_location.GetHouseRect().Contains(Utility.Vector2ToPoint(new Vector2(toPaint.tileX, toPaint.tileY))))
{
if (!carpenterMenu.CanPaintHouse())
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint");
}
else if (!carpenterMenu.HasPermissionsToPaint(null))
{
response = Game1.content.LoadString("Strings\\UI:Carpenter_CannotPaint_Permission");
}
else
{
carpenterMenu.SetChildMenu(new BuildingPaintMenu("House", () => (farm_location.paintedHouseTexture != null) ? farm_location.paintedHouseTexture : Farm.houseTextures, farm_location.houseSource.Value, farm_location.housePaintColor.Value));
}
}*/
return response;
}
public static string? Move(Building? buildingToMove, Vector2 position)
{
string? response = null;
// This code is taken from the game's code (CarpenterMenu.cs::829)
if (buildingToMove != null)
{
string? name = buildingToMove.nameOfIndoorsWithoutUnique;
name = (name == "null") ? buildingToMove.buildingType.Value : name;
if ((int)buildingToMove.daysOfConstructionLeft.Value > 0)
{
buildingToMove = null;
return "Building under construction, cannot move";
}
if (carpenterMenu != null && !carpenterMenu.hasPermissionsToMove(buildingToMove))
{
buildingToMove = null;
return "You don't have permission to move this building";
}
Game1.playSound("axchop");
if (((Farm)Game1.getLocationFromName("Farm")).buildStructure(buildingToMove, position, Game1.player))
{
if (buildingToMove is ShippingBin)
{
((ShippingBin)buildingToMove).initLid();
}
if (buildingToMove is GreenhouseBuilding)
{
Game1.getFarm().greenhouseMoved.Value = true;
}
buildingToMove.performActionOnBuildingPlacement();
buildingToMove = null;
Game1.playSound("axchop");
DelayedAction.playSoundAfterDelay("dirtyHit", 50);
DelayedAction.playSoundAfterDelay("dirtyHit", 150);
response = $"{buildingToMove} moved to {position.X}x {position.Y}y";
}
else
{
Game1.playSound("cancel");
response = $"Cannot move building to {position.X}x {position.Y}y";
}
}
return response;
}
public static void PurchaseAnimal(Building? selection)
{
if (selection == null)
return;
if (purchaseAnimalsMenu == null)
return;
int x = (selection.tileX.Value * Game1.tileSize) - Game1.viewport.X;
int y = (selection.tileY.Value * Game1.tileSize) - Game1.viewport.Y;
if (animalBeingPurchasedOrMoved != null && !selection.buildingType.Value.Contains(animalBeingPurchasedOrMoved.buildingTypeILiveIn.Value))
{
string warn = Game1.content.LoadString("Strings\\StringsFromCSFiles:PurchaseAnimalsMenu.cs.11326", animalBeingPurchasedOrMoved.displayType);
MainClass.ScreenReader.Say(warn, true);
return;
}
if (((AnimalHouse)selection.indoors.Value).isFull())
{
string warn = Game1.content.LoadString("Strings\\StringsFromCSFiles:PurchaseAnimalsMenu.cs.11321");
MainClass.ScreenReader.Say(warn, true);
return;
}
purchaseAnimalsMenu.receiveLeftClick(x, y);
}
public static void MoveAnimal(Building? selection)
{
if (selection == null)
return;
if (animalQueryMenu == null)
return;
if (animalBeingPurchasedOrMoved == null)
return;
// The following code is taken from the game's source code [AnimalQueryMenu.cs::receiveLeftClick]
if (selection.buildingType.Value.Contains(animalBeingPurchasedOrMoved.buildingTypeILiveIn.Value))
{
if (((AnimalHouse)selection.indoors.Value).isFull())
{
string warn = Game1.content.LoadString("Strings\\UI:AnimalQuery_Moving_BuildingFull");
MainClass.ScreenReader.Say(warn, true);
return;
}
if (selection.Equals(animalBeingPurchasedOrMoved.home))
{
string warn = Game1.content.LoadString("Strings\\UI:AnimalQuery_Moving_AlreadyHome");
MainClass.ScreenReader.Say(warn, true);
return;
}
((AnimalHouse)animalBeingPurchasedOrMoved.home.indoors.Value).animalsThatLiveHere.Remove(animalBeingPurchasedOrMoved.myID.Value);
if (((AnimalHouse)animalBeingPurchasedOrMoved.home.indoors.Value).animals.ContainsKey(animalBeingPurchasedOrMoved.myID.Value))
{
((AnimalHouse)selection.indoors.Value).animals.Add(animalBeingPurchasedOrMoved.myID.Value, animalBeingPurchasedOrMoved);
((AnimalHouse)animalBeingPurchasedOrMoved.home.indoors.Value).animals.Remove(animalBeingPurchasedOrMoved.myID.Value);
}
animalBeingPurchasedOrMoved.home = selection;
animalBeingPurchasedOrMoved.homeLocation.Value = new Vector2((int)selection.tileX.Value, (int)selection.tileY.Value);
((AnimalHouse)selection.indoors.Value).animalsThatLiveHere.Add(animalBeingPurchasedOrMoved.myID.Value);
animalBeingPurchasedOrMoved.makeSound();
Game1.globalFadeToBlack(animalQueryMenu.finishedPlacingAnimal);
}
else
{
string warn = Game1.content.LoadString("Strings\\UI:AnimalQuery_Moving_CantLiveThere");
MainClass.ScreenReader.Say(warn, true);
}
return;
}
}
}

View File

@ -0,0 +1,195 @@
using StardewValley;
using StardewValley.Menus;
namespace stardew_access.Patches
{
internal class CarpenterMenuPatch
{
internal static CarpenterMenu? carpenterMenu = null;
internal static string carpenterMenuQuery = "";
internal static bool isSayingBlueprintInfo = false;
internal static string prevBlueprintInfo = "";
internal static bool isOnFarm = false, isUpgrading = false, isDemolishing = false, isPainting = false, isConstructing = false, isMoving = false, isMagicalConstruction = false;
internal static void DrawPatch(
CarpenterMenu __instance, bool ___onFarm, List<Item> ___ingredients, int ___price,
List<BluePrint> ___blueprints, int ___currentBlueprintIndex, bool ___upgrading, bool ___demolishing, bool ___moving,
bool ___painting, bool ___magicalConstruction)
{
try
{
isOnFarm = ___onFarm;
carpenterMenu = __instance;
isMagicalConstruction = ___magicalConstruction;
if (!___onFarm)
{
isUpgrading = false;
isDemolishing = false;
isPainting = false;
isMoving = false;
isConstructing = false;
#region The blueprint menu
BluePrint currentBluprint = __instance.CurrentBlueprint;
if (currentBluprint == null)
return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
bool isPrimaryInfoKeyPressed = MainClass.Config.PrimaryInfoKey.JustPressed();
string ingredients = "";
string name = currentBluprint.displayName;
string upgradeName = currentBluprint.nameOfBuildingToUpgrade;
string description = currentBluprint.description;
string price = $"{___price}g";
string blueprintInfo;
int width = currentBluprint.tilesWidth;
int height = currentBluprint.tilesHeight;
#region Get ingredients
for (int i = 0; i < ___ingredients.Count; i++)
{
string itemName = ___ingredients[i].DisplayName;
int itemStack = ___ingredients[i].Stack;
string itemQuality = "";
int qualityValue = ((StardewValley.Object)___ingredients[i]).Quality;
if (qualityValue == 1)
{
itemQuality = "Silver quality";
}
else if (qualityValue == 2 || qualityValue == 3)
{
itemQuality = "Gold quality";
}
else if (qualityValue >= 4)
{
itemQuality = "Iridium quality";
}
ingredients = $"{ingredients}, {itemStack} {itemName} {itemQuality}";
}
#endregion
blueprintInfo = $"{name}, Price: {price}, Ingredients: {ingredients}, Dimensions: {width} width and {height} height, Description: {description}";
if (isPrimaryInfoKeyPressed && !isSayingBlueprintInfo)
{
SayBlueprintInfo(blueprintInfo);
}
else if (prevBlueprintInfo != blueprintInfo)
{
prevBlueprintInfo = blueprintInfo;
SayBlueprintInfo(blueprintInfo);
}
else
{
if (__instance.backButton != null && __instance.backButton.containsPoint(x, y))
{
string toSpeak = "Previous Blueprint";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.forwardButton != null && __instance.forwardButton.containsPoint(x, y))
{
string toSpeak = "Next Blueprint";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.demolishButton != null && __instance.demolishButton.containsPoint(x, y))
{
string toSpeak = $"Demolish Building" + (__instance.CanDemolishThis(___blueprints[___currentBlueprintIndex]) ? "" : ", cannot demolish building");
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
{
string toSpeak = "Construct Building" + (___blueprints[___currentBlueprintIndex].doesFarmerHaveEnoughResourcesToBuild() ? "" : ", cannot cunstrut building, not enough resources to build.");
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.moveButton != null && __instance.moveButton.containsPoint(x, y))
{
string toSpeak = "Move Building";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.paintButton != null && __instance.paintButton.containsPoint(x, y))
{
string toSpeak = "Paint Building";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
if (__instance.cancelButton != null && __instance.cancelButton.containsPoint(x, y))
{
string toSpeak = "Cancel Button";
if (carpenterMenuQuery != toSpeak)
{
carpenterMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
}
#endregion
}
else
{
if (___demolishing)
isDemolishing = true;
else if (___upgrading)
isUpgrading = true;
else if (___painting)
isPainting = true;
else if (___moving)
isMoving = true;
else
isConstructing = true;
}
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
private static async void SayBlueprintInfo(string info)
{
isSayingBlueprintInfo = true;
MainClass.ScreenReader.Say(info, true);
await Task.Delay(300);
isSayingBlueprintInfo = false;
}
}
}

View File

@ -63,19 +63,24 @@ namespace stardew_access.Patches
}
else if (menu is CarpenterMenu)
{
BuildingNAnimalMenuPatches.carpenterMenuQuery = "";
BuildingNAnimalMenuPatches.isUpgrading = false;
BuildingNAnimalMenuPatches.isDemolishing = false;
BuildingNAnimalMenuPatches.isPainting = false;
BuildingNAnimalMenuPatches.isMoving = false;
BuildingNAnimalMenuPatches.isConstructing = false;
BuildingNAnimalMenuPatches.carpenterMenu = null;
CarpenterMenuPatch.carpenterMenuQuery = "";
CarpenterMenuPatch.isUpgrading = false;
CarpenterMenuPatch.isDemolishing = false;
CarpenterMenuPatch.isPainting = false;
CarpenterMenuPatch.isMoving = false;
CarpenterMenuPatch.isConstructing = false;
CarpenterMenuPatch.carpenterMenu = null;
}
else if (menu is PurchaseAnimalsMenu)
{
BuildingNAnimalMenuPatches.purchaseAnimalMenuQuery = "";
BuildingNAnimalMenuPatches.firstTimeInNamingMenu = true;
BuildingNAnimalMenuPatches.purchaseAnimalsMenu = null;
PurchaseAnimalsMenuPatch.purchaseAnimalMenuQuery = "";
PurchaseAnimalsMenuPatch.firstTimeInNamingMenu = true;
PurchaseAnimalsMenuPatch.purchaseAnimalsMenu = null;
}
else if (menu is AnimalQueryMenu)
{
AnimalQueryMenuPatch.animalQueryMenuQuery = "";
AnimalQueryMenuPatch.animalQueryMenu = null;
}
else if (menu is DialogueBox)
{

View File

@ -0,0 +1,101 @@
using StardewValley;
using StardewValley.Menus;
namespace stardew_access.Patches
{
internal class PurchaseAnimalsMenuPatch
{
internal static FarmAnimal? animalBeingPurchased = null;
internal static bool isOnFarm = false;
internal static string purchaseAnimalMenuQuery = "";
internal static PurchaseAnimalsMenu? purchaseAnimalsMenu;
internal static bool firstTimeInNamingMenu = true;
internal static void DrawPatch(PurchaseAnimalsMenu __instance, bool ___onFarm, bool ___namingAnimal, TextBox ___textBox, FarmAnimal ___animalBeingPurchased)
{
try
{
if (TextBoxPatch.isAnyTextBoxActive) return;
int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position
purchaseAnimalsMenu = __instance;
isOnFarm = ___onFarm;
animalBeingPurchased = ___animalBeingPurchased;
if (___onFarm && ___namingAnimal)
{
string toSpeak = "";
if (__instance.okButton != null && __instance.okButton.containsPoint(x, y))
{
toSpeak = "Cancel Button";
}
else if (__instance.doneNamingButton != null && __instance.doneNamingButton.containsPoint(x, y))
{
toSpeak = "OK Button";
}
else if (__instance.randomButton != null && __instance.randomButton.containsPoint(x, y))
{
toSpeak = "Random Name Button";
}
else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y))
{
toSpeak = "Name Text Box";
// string? value = ___textBox.Text;
// if (value != "" && value != null && value != "null")
// toSpeak = $"{toSpeak}, Value: {value}";
}
if (purchaseAnimalMenuQuery != toSpeak)
{
purchaseAnimalMenuQuery = toSpeak;
if (firstTimeInNamingMenu)
{
toSpeak = $"Enter the name of animal in the name text box. {toSpeak}";
firstTimeInNamingMenu = false;
}
MainClass.ScreenReader.Say(toSpeak, true);
}
}
else if (___onFarm && !___namingAnimal)
{
firstTimeInNamingMenu = true;
}
else if (!___onFarm && !___namingAnimal)
{
firstTimeInNamingMenu = true;
if (__instance.hovered != null)
{
string toSpeak = "";
if (((StardewValley.Object)__instance.hovered.item).Type != null)
{
toSpeak = ((StardewValley.Object)__instance.hovered.item).Type;
}
else
{
string displayName = PurchaseAnimalsMenu.getAnimalTitle(__instance.hovered.hoverText);
int price = __instance.hovered.item.salePrice();
string description = PurchaseAnimalsMenu.getAnimalDescription(__instance.hovered.hoverText);
toSpeak = $"{displayName}, Price: {price}g, Description: {description}";
}
if (purchaseAnimalMenuQuery != toSpeak)
{
purchaseAnimalMenuQuery = toSpeak;
MainClass.ScreenReader.Say(toSpeak, true);
}
return;
}
}
}
catch (Exception e)
{
MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}");
}
}
}
}