From 0657a3aa7f2ef2013ca16fa56a87c6c7ab91d82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?mc=E5=BC=80=E5=A7=8B=E4=B8=8B=E9=9B=AA?= <37864486+mcBegins2Snow@users.noreply.github.com> Date: Thu, 5 Aug 2021 14:09:35 +0800 Subject: [PATCH 01/29] Update zh.json Improve translation According to: https://zh.stardewvalleywiki.com/%E5%8F%8B%E8%B0%8A#.E7.A4.BC.E7.89.A9_2 --- JoysOfEfficiency/i18n/zh.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/JoysOfEfficiency/i18n/zh.json b/JoysOfEfficiency/i18n/zh.json index 30ae7af..84a4b86 100644 --- a/JoysOfEfficiency/i18n/zh.json +++ b/JoysOfEfficiency/i18n/zh.json @@ -8,14 +8,14 @@ "fishinfo.quality": "品质: ", "fishinfo.size": "尺寸: {0} 厘米", "fishinfo.species": "品种: {0}", - "fishinfo.treasure.appear": "宝箱出现了!", - "fishinfo.treasure.caught": "获得了宝箱!", - "fishinfo.treasure.incoming": "宝箱在 {0:f1} 秒后出现.", + "fishinfo.treasure.appear": "宝箱出现了!", + "fishinfo.treasure.caught": "获得了宝箱!", + "fishinfo.treasure.incoming": "宝箱在 {0:f1} 秒后出现。", "fishinfo.price": "出售价格:{0}G", "hud.paused": "游戏暂停", - "ladder": "梯子出现了!", + "ladder": "梯子出现了!", "location.awaiting": "单击某处以指定所需的位置。", @@ -109,26 +109,26 @@ "quality.iridium": "铱", "quality.normal": "一般", "quality.silver": "银", - "stones.many": "这个层有 {0} 块石头", - "stones.none": "这个层没剩下有石头", - "stones.one": "这个层石头只有一个", + "stones.many": "这层还有 {0} 块石头", + "stones.none": "这层没有石头", + "stones.one": "这层有一块石头", "tab.automation": "自动化", "tab.cheats": "作弊", "tab.controls": "控制", "tab.misc": "杂项", "tab.UIs": "用户界面", - "taste.dislike.female": "她讨厌这个礼物", - "taste.dislike.male": "他讨厌这个礼物", + "taste.dislike.female": "她不喜欢这个礼物", + "taste.dislike.male": "他不喜欢这个礼物", "taste.gavetoday.female": "今天你给过她礼物了", "taste.gavetoday.male": "今天你给过他礼物了", "taste.gavetwogifts.female": "这周你给过她两次礼物了", "taste.gavetwogifts.male": "这周你给过他两次礼物了", - "taste.hate.female": "她非常讨厌这个礼物", - "taste.hate.male": "他非常讨厌这个礼物", + "taste.hate.female": "她不喜欢这个礼物", + "taste.hate.male": "他不喜欢这个礼物", "taste.like.female": "她喜欢这个礼物", "taste.like.male": "他喜欢这个礼物", - "taste.love.female": "她非常喜欢这个礼物", - "taste.love.male": "他非常喜欢这个礼物", + "taste.love.female": "她最爱这个礼物", + "taste.love.male": "他最爱这个礼物", "taste.neutral.female": "她对这份礼物持中立态度", "taste.neutral.male": "他对这份礼物持中立态度" } From 1db87e25b5f04693ad5b326440dfccfdfb544359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?mc=E5=BC=80=E5=A7=8B=E4=B8=8B=E9=9B=AA?= <37864486+mcBegins2Snow@users.noreply.github.com> Date: Thu, 5 Aug 2021 14:10:58 +0800 Subject: [PATCH 02/29] Update zh.json --- JoysOfEfficiency/i18n/zh.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JoysOfEfficiency/i18n/zh.json b/JoysOfEfficiency/i18n/zh.json index 84a4b86..95b44a0 100644 --- a/JoysOfEfficiency/i18n/zh.json +++ b/JoysOfEfficiency/i18n/zh.json @@ -111,7 +111,7 @@ "quality.silver": "银", "stones.many": "这层还有 {0} 块石头", "stones.none": "这层没有石头", - "stones.one": "这层有一块石头", + "stones.one": "这层还有一块石头", "tab.automation": "自动化", "tab.cheats": "作弊", "tab.controls": "控制", From 4d726764cfc98e60ea21ea745dbc1f4d7199bc75 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Sat, 20 Jan 2024 18:12:06 -0500 Subject: [PATCH 03/29] [Hackswell] Updated build files to work with net5.0. Reduce warnings. Added Heavy Tapper to machine list. Added new option AutoDepositSeedMaker. --- .gitignore | 5 +- JoysOfEfficiency.sln | 8 +- JoysOfEfficiency/Automation/AutoFisher.cs | 4 +- .../Automation/CollectibleCollector.cs | 2 +- JoysOfEfficiency/Automation/FarmCleaner.cs | 16 +- .../Automation/FenceGateAutomation.cs | 16 +- .../Automation/HarvestAutomation.cs | 2 +- .../Automation/MachineOperator.cs | 25 ++- JoysOfEfficiency/Core/Config.cs | 1 + JoysOfEfficiency/Harmony/HarmonyPatcher.cs | 6 +- JoysOfEfficiency/Huds/MineIcons.cs | 6 +- JoysOfEfficiency/JoysOfEfficiency.csproj | 159 +++--------------- JoysOfEfficiency/Menus/JoeMenu.cs | 2 + JoysOfEfficiency/Utils/ConfigHolder.cs | 6 +- JoysOfEfficiency/WhatsNew.md | 10 +- .../{Arts => assets}/icon_ladder.png | Bin .../{Arts => assets}/icon_monster.png | Bin .../{Arts => assets}/icon_pickaxe.png | Bin JoysOfEfficiency/i18n/default.json | 1 + JoysOfEfficiency/i18n/es.json | 1 + JoysOfEfficiency/manifest.json | 6 +- JoysOfEfficiency/packages.config | 5 +- global.json | 7 + 23 files changed, 102 insertions(+), 186 deletions(-) rename JoysOfEfficiency/{Arts => assets}/icon_ladder.png (100%) rename JoysOfEfficiency/{Arts => assets}/icon_monster.png (100%) rename JoysOfEfficiency/{Arts => assets}/icon_pickaxe.png (100%) create mode 100644 global.json diff --git a/.gitignore b/.gitignore index d97ee0b..ff52632 100644 --- a/.gitignore +++ b/.gitignore @@ -353,4 +353,7 @@ MigrationBackup/ .ionide/ *.DotSettings -codepage.txt \ No newline at end of file +codepage.txt + +# IDEA / JetBrains Rider +.idea/ diff --git a/JoysOfEfficiency.sln b/JoysOfEfficiency.sln index 7dc0a2a..2cca74c 100644 --- a/JoysOfEfficiency.sln +++ b/JoysOfEfficiency.sln @@ -12,14 +12,10 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.ActiveCfg = Release|x86 - {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Build.0 = Release|x86 - {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|x86.ActiveCfg = Debug|x86 - {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|x86.Build.0 = Debug|x86 + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Build.0 = Release|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.ActiveCfg = Release|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.Build.0 = Release|Any CPU - {0302444C-4190-4C5D-A873-A1F80267961A}.Release|x86.ActiveCfg = Release|x86 - {0302444C-4190-4C5D-A873-A1F80267961A}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/JoysOfEfficiency/Automation/AutoFisher.cs b/JoysOfEfficiency/Automation/AutoFisher.cs index 95403f5..63437f5 100644 --- a/JoysOfEfficiency/Automation/AutoFisher.cs +++ b/JoysOfEfficiency/Automation/AutoFisher.cs @@ -155,7 +155,7 @@ public static void CollectFish(Farmer who, FishingRod rod) bool fromFishPond = rod.fromFishPond; who.completelyStopAnimatingOrDoingAction(); rod.doneFishing(who, !fromFishPond); - if (!Game1.isFestival() && !fromFishPond && (itemCategory == "Object" && Game1.player.team.specialOrders != null)) + if (!Game1.isFestival() && !fromFishPond && (itemCategory == "Object" && Game1.player.team.specialOrders.Count > 0)) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { @@ -185,7 +185,7 @@ public static void CollectFish(Farmer who, FishingRod rod) } Object @object = new Object(whichFish, initialStack, false, -1, fishQuality); - if (Game1.player.team.specialOrders != null) + if (Game1.player.team.specialOrders.Count > 0) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { diff --git a/JoysOfEfficiency/Automation/CollectibleCollector.cs b/JoysOfEfficiency/Automation/CollectibleCollector.cs index 70fc65f..e2cc943 100644 --- a/JoysOfEfficiency/Automation/CollectibleCollector.cs +++ b/JoysOfEfficiency/Automation/CollectibleCollector.cs @@ -98,7 +98,7 @@ private static void CollectObj(GameLocation loc, SVObject obj) private static bool IsGinger(Crop crop) { - return crop != null && crop.forageCrop && crop.whichForageCrop == Crop.forageCrop_ginger; + return crop != null && crop.forageCrop.Value && crop.whichForageCrop.Value == Crop.forageCrop_ginger; } private static void CollectGinger(GameLocation loc, Vector2 pos, HoeDirt dirt) diff --git a/JoysOfEfficiency/Automation/FarmCleaner.cs b/JoysOfEfficiency/Automation/FarmCleaner.cs index 158bba3..cfadf9a 100644 --- a/JoysOfEfficiency/Automation/FarmCleaner.cs +++ b/JoysOfEfficiency/Automation/FarmCleaner.cs @@ -72,7 +72,7 @@ private static bool ChopTwig(GameLocation farm, Object obj, Vector2 loc) player.Stamina -= stamina; - obj.fragility.Value = 2; + obj.Fragility = 2; farm.playSound("axchop"); farm.debris.Add(new Debris(new Object(388, 1), loc * 64f + new Vector2(32f, 32f))); Game1.createRadialDebris(farm, 12, (int)loc.X, (int)loc.Y, Game1.random.Next(4, 10), false); @@ -98,12 +98,12 @@ private static bool BreakRock(GameLocation location, Tool pickaxe, Object @objec int x = num1 * 64; int y = num2 * 64; location.playSound("hammer"); - if (@object.minutesUntilReady > 0) + if (@object.MinutesUntilReady > 0) { - int num3 = Math.Max(1, pickaxe.upgradeLevel + 1); - @object.minutesUntilReady.Value -= num3; + int num3 = Math.Max(1, pickaxe.UpgradeLevel + 1); + @object.MinutesUntilReady -= num3; @object.shakeTimer = 200; - if (@object.minutesUntilReady > 0) + if (@object.MinutesUntilReady > 0) { Game1.createRadialDebris(Game1.currentLocation, 14, num1, num2, Game1.random.Next(2, 5), false); return false; @@ -114,7 +114,7 @@ private static bool BreakRock(GameLocation location, Tool pickaxe, Object @objec { Multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(@object.ParentSheetIndex + 1, 300f, - 1, 2, new Vector2(x - x % 64, y - y % 64), true, @object.flipped) + 1, 2, new Vector2(x - x % 64, y - y % 64), true, @object.Flipped) { alphaFade = 0.01f }); @@ -131,8 +131,8 @@ private static bool BreakRock(GameLocation location, Tool pickaxe, Object @objec acceleration = new Vector2(0.0f, 1f / 500f), alphaFade = 0.015f }); - location.OnStoneDestroyed(@object.parentSheetIndex, num1, num2, Game1.player); - if (@object.minutesUntilReady > 0) + location.OnStoneDestroyed(@object.ParentSheetIndex, num1, num2, Game1.player); + if (@object.MinutesUntilReady > 0) return false; location.Objects.Remove(new Vector2(num1, num2)); location.playSound("stoneCrack"); diff --git a/JoysOfEfficiency/Automation/FenceGateAutomation.cs b/JoysOfEfficiency/Automation/FenceGateAutomation.cs index 920dc30..9bc17a5 100644 --- a/JoysOfEfficiency/Automation/FenceGateAutomation.cs +++ b/JoysOfEfficiency/Automation/FenceGateAutomation.cs @@ -18,7 +18,7 @@ internal class FenceGateAutomation public static void TryToggleGate(Farmer player) { GameLocation location = player.currentLocation; - foreach (Fence fence in Util.GetObjectsWithin(2, true).Where(x=>x.isGate)) + foreach (Fence fence in Util.GetObjectsWithin(2, true).Where(x=>x.isGate.Value)) { bool flag = false; List fencesToOperate = new List {fence}; @@ -113,12 +113,12 @@ private static Fence GetConnectedGate(GameLocation location, Vector2 fenceLoc, F if (type == FenceType.Horizontal) { if (location.Objects.TryGetValue(fenceLoc + new Vector2(-1, 0), out Object obj) && - obj is Fence fence && fence.isGate) + obj is Fence fence && fence.isGate.Value) { return fence; } if (location.Objects.TryGetValue(fenceLoc + new Vector2(1, 0), out obj) && - obj is Fence fence2 && fence2.isGate) + obj is Fence fence2 && fence2.isGate.Value) { return fence2; } @@ -126,12 +126,12 @@ private static Fence GetConnectedGate(GameLocation location, Vector2 fenceLoc, F else if (type == FenceType.Vertical) { if (location.Objects.TryGetValue(fenceLoc + new Vector2(0, -1), out Object obj2) && - obj2 is Fence fence3 && fence3.isGate) + obj2 is Fence fence3 && fence3.isGate.Value) { return fence3; } if (location.Objects.TryGetValue(fenceLoc + new Vector2(0, 1), out obj2) && - obj2 is Fence fence4 && fence4.isGate) + obj2 is Fence fence4 && fence4.isGate.Value) { return fence4; } @@ -142,7 +142,7 @@ private static Fence GetConnectedGate(GameLocation location, Vector2 fenceLoc, F private static bool IsSingleFence(GameLocation location, Fence fence) { - return GetSurroundingObjects(location, fence.TileLocation).Any(f => !f.isGate); + return GetSurroundingObjects(location, fence.TileLocation).Any(f => !f.isGate.Value); } private static bool IsGatesSerial(GameLocation location, Vector2 fenceLoc, int dX, int dY, out int gateCount) @@ -158,7 +158,7 @@ private static bool IsGatesSerial(GameLocation location, Vector2 fenceLoc, int d return false; } - if (!fence.isGate) + if (!fence.isGate.Value) { break; } @@ -174,7 +174,7 @@ private static bool IsGatesSerial(GameLocation location, Vector2 fenceLoc, int d return false; } - if (!fence.isGate) + if (!fence.isGate.Value) { break; } diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index 67dea73..59064a5 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -332,7 +332,7 @@ private static bool IsTeaBush(Bush bush) private static bool IsBerryBush(Bush bush) { - return bush.size.Value == Bush.mediumBush && !bush.townBush; + return bush.size.Value == Bush.mediumBush && !bush.townBush.Value; } private static bool IsBushFruited(Bush bush) diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/JoysOfEfficiency/Automation/MachineOperator.cs index 6c463de..c6057c6 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/JoysOfEfficiency/Automation/MachineOperator.cs @@ -48,10 +48,22 @@ public static void DepositIngredientsToMachines() flag = true; } } + else if (obj.Name == "Seed Maker") + { + if (InstanceHolder.Config.AutoDepositSeedMaker == false) + { + flag = false; + } + else + { + flag = true; + } + } else if (accepted) { flag = true; } + if (!flag) continue; @@ -87,12 +99,12 @@ private static bool CanFurnaceAcceptItem(Item item, Farmer player) return false; switch (item.ParentSheetIndex) { - case 378: - case 380: - case 384: - case 386: - case 80: - case 82: + case 378: // Copper Ore + case 380: // Iron Ore + case 384: // Gold Ore + case 386: // Iridium Ore + case 80: // Quartz + case 82: // Fire Quartz break; default: return false; @@ -133,6 +145,7 @@ private static bool IsObjectMachine(SVObject obj) case "Statue Of Endless Fortune": case "Statue Of Perfection": case "Tapper": + case "Heavy Tapper": return true; default: return false; } diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index c1602c1..7841a75 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -67,6 +67,7 @@ internal class Config public bool BalancedMode { get; set; } = true; public bool AutoDepositIngredient { get; set; } = false; + public bool AutoDepositSeedMaker { get; set; } = false; public bool AutoPullMachineResult { get; set; } = true; public int MachineRadius { get; set; } = 1; diff --git a/JoysOfEfficiency/Harmony/HarmonyPatcher.cs b/JoysOfEfficiency/Harmony/HarmonyPatcher.cs index c5e22f2..0e7d354 100644 --- a/JoysOfEfficiency/Harmony/HarmonyPatcher.cs +++ b/JoysOfEfficiency/Harmony/HarmonyPatcher.cs @@ -1,14 +1,14 @@ -using Harmony; +using HarmonyLib; namespace JoysOfEfficiency.Harmony { internal class HarmonyPatcher { - private static readonly HarmonyInstance Harmony = HarmonyInstance.Create("com.pome.joe"); + private static HarmonyLib.Harmony harmony = new HarmonyLib.Harmony("com.pome.joe"); public static void DoPatching() { - Harmony.PatchAll(); + harmony.PatchAll(); } } diff --git a/JoysOfEfficiency/Huds/MineIcons.cs b/JoysOfEfficiency/Huds/MineIcons.cs index eb02a8d..46b5162 100644 --- a/JoysOfEfficiency/Huds/MineIcons.cs +++ b/JoysOfEfficiency/Huds/MineIcons.cs @@ -19,9 +19,9 @@ public class MineIcons public static void Init(IModHelper helper) { - _iconPickaxe = helper.Content.Load("icon_pickaxe.png"); - _iconMonster = helper.Content.Load("icon_monster.png"); - _iconLadder = helper.Content.Load("icon_ladder.png"); + _iconPickaxe = helper.ModContent.Load("assets/icon_pickaxe.png"); + _iconMonster = helper.ModContent.Load("assets/icon_monster.png"); + _iconLadder = helper.ModContent.Load("assets/icon_ladder.png"); int x = 16 + OffsetX; _logger.Log($"x:{x}"); diff --git a/JoysOfEfficiency/JoysOfEfficiency.csproj b/JoysOfEfficiency/JoysOfEfficiency.csproj index e41b836..6cde001 100644 --- a/JoysOfEfficiency/JoysOfEfficiency.csproj +++ b/JoysOfEfficiency/JoysOfEfficiency.csproj @@ -1,19 +1,14 @@  - + - Debug - AnyCPU - {0302444C-4190-4C5D-A873-A1F80267961A} + net5.0 Library Properties JoysOfEfficiency JoysOfEfficiency - v4.5 512 - - - + 1.4.9 true @@ -22,123 +17,20 @@ bin\Debug\ DEBUG;TRACE prompt - 4 - 7.1 + 3 + true pdbonly true bin\Release\ TRACE prompt - 4 - true - 7.1 - - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - - - true - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset + 3 Always - - - ..\packages\Lib.Harmony.1.2.0.1\lib\net45\0Harmony.dll - - - - - - ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - - - - - - @@ -152,31 +44,24 @@ + + PreserveNewest + + + + + PreserveNewest + + + PreserveNewest + - - ResXFileCodeGenerator - Resources.Designer.cs - + - + + + - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + diff --git a/JoysOfEfficiency/Menus/JoeMenu.cs b/JoysOfEfficiency/Menus/JoeMenu.cs index e76876d..6b9b1eb 100644 --- a/JoysOfEfficiency/Menus/JoeMenu.cs +++ b/JoysOfEfficiency/Menus/JoeMenu.cs @@ -154,6 +154,7 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Auto Deposit/Pull Machines")); tab.AddOptionsElement(new ModifiedCheckBox("AutoDepositIngredient", 22, Config.AutoDepositIngredient, OnCheckboxValueChanged)); + tab.AddOptionsElement(new ModifiedCheckBox("AutoDepositSeedMaker", 42, Config.AutoDepositSeedMaker, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedCheckBox("AutoPullMachineResult", 23, Config.AutoPullMachineResult, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedSlider("MachineRadius", 10, Config.MachineRadius, 1, 3, OnSliderValueChanged, () => !(Config.AutoPullMachineResult || Config.AutoDepositIngredient) || Config.BalancedMode)); @@ -363,6 +364,7 @@ private void OnCheckboxValueChanged(int index, bool value) case 39: Config.CutWeeds = value; break; case 40: Config.BreakRocks = value; break; case 41: Config.ChopTwigs = value; break; + case 42: Config.AutoDepositSeedMaker = value; break; default: return; } InstanceHolder.WriteConfig(); diff --git a/JoysOfEfficiency/Utils/ConfigHolder.cs b/JoysOfEfficiency/Utils/ConfigHolder.cs index b5ef312..57027e0 100644 --- a/JoysOfEfficiency/Utils/ConfigHolder.cs +++ b/JoysOfEfficiency/Utils/ConfigHolder.cs @@ -1,5 +1,5 @@ using System.IO; -using Newtonsoft.Json; +using System.Text.Json; namespace JoysOfEfficiency.Utils { @@ -29,12 +29,12 @@ protected void Load() Logger.Log("Loaded "+ _configFileName); string jsonContent = File.ReadAllText(_configFileName); - Entry = JsonConvert.DeserializeObject(jsonContent); + Entry = JsonSerializer.Deserialize(jsonContent); } public void Save() { - string jsonContent = JsonConvert.SerializeObject(Entry, Formatting.Indented); + string jsonContent = JsonSerializer.Serialize(Entry); File.WriteAllText(_configFileName, jsonContent); Logger.Log("Saved " + Path.GetFullPath(_configFileName)); } diff --git a/JoysOfEfficiency/WhatsNew.md b/JoysOfEfficiency/WhatsNew.md index 02ced2b..e1aaa25 100644 --- a/JoysOfEfficiency/WhatsNew.md +++ b/JoysOfEfficiency/WhatsNew.md @@ -1,8 +1,16 @@ # Overview -This is a changelog from 1.0.22 +This is a changelog from 1.4.9 # Changelog +## 1.4.9 +- Updated build files to work with net5.0 +- Updated code to work with HarmonyLib +- Moved from Newtonsoft.Json to System.Text.Json +- Reduce number of warnings +- Added Heavy Tapper to machine list for auto-collection +- Added new option to NOT auto-add to Seed Makers + ## 1.0.22 - Moved Utilities to Util.cs - Added Balanced mode diff --git a/JoysOfEfficiency/Arts/icon_ladder.png b/JoysOfEfficiency/assets/icon_ladder.png similarity index 100% rename from JoysOfEfficiency/Arts/icon_ladder.png rename to JoysOfEfficiency/assets/icon_ladder.png diff --git a/JoysOfEfficiency/Arts/icon_monster.png b/JoysOfEfficiency/assets/icon_monster.png similarity index 100% rename from JoysOfEfficiency/Arts/icon_monster.png rename to JoysOfEfficiency/assets/icon_monster.png diff --git a/JoysOfEfficiency/Arts/icon_pickaxe.png b/JoysOfEfficiency/assets/icon_pickaxe.png similarity index 100% rename from JoysOfEfficiency/Arts/icon_pickaxe.png rename to JoysOfEfficiency/assets/icon_pickaxe.png diff --git a/JoysOfEfficiency/i18n/default.json b/JoysOfEfficiency/i18n/default.json index 7fc86cf..9187d76 100644 --- a/JoysOfEfficiency/i18n/default.json +++ b/JoysOfEfficiency/i18n/default.json @@ -26,6 +26,7 @@ "options.AutoCollectCollectibles": "Auto-collect collectibles nearby", "options.AutoCollectRadius": "How far tiles to auto-collect", "options.AutoDepositIngredient": "Deposit ingredient you held to machines", + "options.AutoDepositSeedMaker": " Deposit ingredient to Seed Makers", "options.AutoDestroyDeadCrops": "Auto-destroy dead crops nearby", "options.AutoDigArtifactSpot": "Auto-dig nearby artifact spots", "options.AutoDigRadius": "How far tiles to auto-dig", diff --git a/JoysOfEfficiency/i18n/es.json b/JoysOfEfficiency/i18n/es.json index 8f2846b..a841a7b 100644 --- a/JoysOfEfficiency/i18n/es.json +++ b/JoysOfEfficiency/i18n/es.json @@ -16,6 +16,7 @@ "options.AutoCollectCollectibles": "Colecciona objetos de colección en las cercanías", "options.AutoCollectRadius": "Azulejos para coleccionar", "options.AutoDepositIngredient": "Deposite el ingrediente que aferró a las máquinas", + "options.AutoDepositSeedMaker": "\tDeposite el ingrediente en los Seed Makers", "options.AutoDestroyDeadCrops": "Destruir las cosechas muertas cercanas", "options.AutoDigArtifactSpot": "Cavando un artefacto cercano", "options.AutoDigRadius": "Baldosas para excavación", diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 24cd6f6..39c18fa 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -2,9 +2,9 @@ "Author": "punyo", "Description": "Adds many useful functions to make gameplay more efficient", "EntryDll": "JoysOfEfficiency.dll", - "MinimumApiVersion": "3.0", + "MinimumApiVersion": "3.8", "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.4.1" -} \ No newline at end of file + "Version": "1.4.9" +} diff --git a/JoysOfEfficiency/packages.config b/JoysOfEfficiency/packages.config index c138194..ebb72ce 100644 --- a/JoysOfEfficiency/packages.config +++ b/JoysOfEfficiency/packages.config @@ -1,6 +1,5 @@  - - - + + \ No newline at end of file diff --git a/global.json b/global.json new file mode 100644 index 0000000..2c43f91 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "5.0.0", + "rollForward": "latestMajor", + "allowPrerelease": false + } +} \ No newline at end of file From 34617da9eb7eeacb004c11b9f4e41b85322c2ec4 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Fri, 16 Feb 2024 14:14:37 -0500 Subject: [PATCH 04/29] [RCB] Added coffee maker and worm bin to machine list. --- JoysOfEfficiency/Automation/MachineOperator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/JoysOfEfficiency/Automation/MachineOperator.cs index c6057c6..2059f9b 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/JoysOfEfficiency/Automation/MachineOperator.cs @@ -146,6 +146,8 @@ private static bool IsObjectMachine(SVObject obj) case "Statue Of Perfection": case "Tapper": case "Heavy Tapper": + case "Coffee Maker": + case "Worm Bin": return true; default: return false; } From 645114c2daf22d0484535a8d1f7b544838717903 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Sat, 23 Mar 2024 22:16:41 -0400 Subject: [PATCH 05/29] [Hackswell] Preliminary 1.6 compatability. See testplan.txt for what should be working, what doesn't work, and what hasn't even been tested yet. --- JoysOfEfficiency.sln | 5 +- .../Automation/AnimalAutomation.cs | 94 ++++++------------ JoysOfEfficiency/Automation/AutoFisher.cs | 70 ++++++------- .../Automation/CollectibleCollector.cs | 10 +- JoysOfEfficiency/Automation/FarmCleaner.cs | 10 +- .../Automation/FenceGateAutomation.cs | 4 +- .../Automation/FlowerColorUnifier.cs | 24 ++--- .../Automation/HarvestAutomation.cs | 68 +++++++------ .../Automation/InventoryAutomation.cs | 13 +-- .../Automation/MachineOperator.cs | 74 +++++--------- JoysOfEfficiency/Automation/MailAutomation.cs | 13 +-- .../Automation/TrashCanScavenger.cs | 99 ++----------------- .../Automation/WateringCanRefiller.cs | 2 +- JoysOfEfficiency/Core/Config.cs | 39 +++++++- JoysOfEfficiency/Core/InstanceHolder.cs | 9 +- .../EventHandler/ArtifactSpotDigger.cs | 5 +- JoysOfEfficiency/EventHandler/UpdateEvents.cs | 7 +- JoysOfEfficiency/Huds/FishInformationHud.cs | 17 ++-- .../Huds/FishingProbabilitiesBox.cs | 16 +-- .../Huds/GiftInformationTooltip.cs | 6 +- JoysOfEfficiency/JoysOfEfficiency.csproj | 11 +-- JoysOfEfficiency/Menus/RegisterFlowerMenu.cs | 2 +- JoysOfEfficiency/Utils/Util.cs | 42 +++----- JoysOfEfficiency/manifest.json | 4 +- JoysOfEfficiency/packages.config | 6 +- global.json | 2 +- testplan.txt | 65 ++++++++++++ 27 files changed, 320 insertions(+), 397 deletions(-) create mode 100644 testplan.txt diff --git a/JoysOfEfficiency.sln b/JoysOfEfficiency.sln index 2cca74c..a17ea7d 100644 --- a/JoysOfEfficiency.sln +++ b/JoysOfEfficiency.sln @@ -12,10 +12,11 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Build.0 = Release|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.ActiveCfg = Release|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.Build.0 = Release|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/JoysOfEfficiency/Automation/AnimalAutomation.cs b/JoysOfEfficiency/Automation/AnimalAutomation.cs index 2073940..994097b 100644 --- a/JoysOfEfficiency/Automation/AnimalAutomation.cs +++ b/JoysOfEfficiency/Automation/AnimalAutomation.cs @@ -1,10 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using JoysOfEfficiency.Core; using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; -using Netcode; -using StardewModdingAPI; using StardewValley; using StardewValley.Buildings; using StardewValley.Characters; @@ -14,7 +13,6 @@ namespace JoysOfEfficiency.Automation { internal class AnimalAutomation { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; private static Config Config => InstanceHolder.Config; private static readonly Logger Logger = new Logger("AnimalAutomation"); @@ -26,8 +24,8 @@ public static void LetAnimalsInHome() { FarmAnimal animal = kv.Value; Logger.Log( - $"Warped {animal.displayName}({animal.shortDisplayType()}) to {animal.displayHouse}@[{animal.homeLocation.X}, {animal.homeLocation.Y}]"); - animal.warpHome(farm, animal); + $"Warped {animal.displayName}({animal.shortDisplayType()}) to {animal.displayHouse}@[{animal.home.animalDoor.X}, {animal.home.animalDoor.Y}]"); + animal.warpHome(); } } @@ -49,34 +47,18 @@ public static void AutoOpenAnimalDoor() Farm farm = Game1.getFarm(); foreach (Building building in farm.buildings) { - switch (building) + switch (building.buildingType.Value) { - case Coop coop: + case "Coop": + case "Barn": { - if (coop.indoors.Value is AnimalHouse house) + if (building.indoors.Value is AnimalHouse house) { - if (house.animals.Any() && !coop.animalDoorOpen.Value) + if (house.animals.Any() && !building.animalDoorOpen.Value) { - Logger.Log($"Opening coop door @[{coop.animalDoor.X},{coop.animalDoor.Y}]"); - coop.animalDoorOpen.Value = true; - Reflection.GetField(coop, "animalDoorMotion").SetValue(new NetInt(-2)); + building.ToggleAnimalDoor(Game1.player); } } - - break; - } - case Barn barn: - { - if (barn.indoors.Value is AnimalHouse house) - { - if (house.animals.Any() && !barn.animalDoorOpen.Value) - { - Logger.Log($"Opening barn door @[{barn.animalDoor.X},{barn.animalDoor.Y}]"); - barn.animalDoorOpen.Value = true; - Reflection.GetField(barn, "animalDoorMotion").SetValue(new NetInt(-3)); - } - } - break; } } @@ -88,32 +70,18 @@ public static void AutoCloseAnimalDoor() Farm farm = Game1.getFarm(); foreach (Building building in farm.buildings) { - switch (building) + switch (building.buildingType.Value) { - case Coop coop: + case "Coop": + case "Barn": { - if (coop.indoors.Value is AnimalHouse house) + if (building.indoors.Value is AnimalHouse house) { - if (house.animals.Any() && coop.animalDoorOpen.Value) + if (house.animals.Any() && building.animalDoorOpen.Value) { - coop.animalDoorOpen.Value = false; - Reflection.GetField(coop, "animalDoorMotion").SetValue(new NetInt(2)); + building.ToggleAnimalDoor(Game1.player); } } - - break; - } - case Barn barn: - { - if (barn.indoors.Value is AnimalHouse house) - { - if (house.animals.Any() && barn.animalDoorOpen.Value) - { - barn.animalDoorOpen.Value = false; - Reflection.GetField(barn, "animalDoorMotion").SetValue(new NetInt(2)); - } - } - break; } } @@ -132,8 +100,9 @@ public static void PetNearbyPets() bool wasPet = WasPetToday(pet); if (!wasPet) { - Logger.Log($"Petted {(pet is Dog ? "Dog" : "Cat")}'{pet.Name}' @{pet.getTileLocationPoint()}"); + Logger.Log($"Petted {(pet.petType.Value == "Dog" ? "Dog" : "Cat")}'{pet.Name}' @{pet.position}"); pet.checkAction(player, location); // Pet pet... lol + } } } @@ -153,7 +122,7 @@ public static void PetNearbyAnimals() { continue; } - Logger.Log($"Petted {animal.displayType}'{animal.Name}' @{animal.getTileLocationPoint()}"); + Logger.Log($"Petted {animal.displayType}'{animal.Name}' @{animal.position}"); animal.pet(Game1.player); } } @@ -165,7 +134,7 @@ public static void ShearingAndMilking(Farmer player) foreach (FarmAnimal animal in Util.GetAnimalsList(player)) { string lowerType = animal.type.Value.ToLower(); - if (animal.currentProduce.Value < 0 || animal.age.Value < animal.ageWhenMature.Value || + if (animal.currentProduce.Value is null || animal.isBaby() || player.CurrentTool == null || !animal.GetBoundingBox().Intersects(bb)) { continue; @@ -177,20 +146,21 @@ public static void ShearingAndMilking(Farmer player) continue; if (!player.addItemToInventoryBool( - new Object(Vector2.Zero, animal.currentProduce.Value, null, false, true, false, false) - { - Quality = animal.produceQuality.Value - })) + new StardewValley.Object(animal.currentProduce.Value, + 1, + false, + -1, + animal.produceQuality.Value))) { continue; } switch (player.CurrentTool) { - case Shears _: + case Shears: Shears.playSnip(player); break; - case MilkPail _: + case MilkPail: player.currentLocation.localSound("Milking"); DelayedAction.playSoundAfterDelay("fishingRodBend", 300); DelayedAction.playSoundAfterDelay("fishingRodBend", 1200); @@ -200,12 +170,8 @@ public static void ShearingAndMilking(Farmer player) animal.doEmote(20); Game1.playSound("coin"); - animal.currentProduce.Value = -1; - if (animal.showDifferentTextureWhenReadyForHarvest.Value) - { - animal.Sprite.LoadTexture("Animals\\Sheared" + animal.type.Value); - } - + animal.currentProduce.Value = null; + animal.ReloadTextureIfNeeded(); player.gainExperience(0, 5); } } @@ -216,4 +182,4 @@ private static bool WasPetToday(Pet pet) pet.lastPetDay[Game1.player.UniqueMultiplayerID] == Game1.Date.TotalDays; } } -} \ No newline at end of file +} diff --git a/JoysOfEfficiency/Automation/AutoFisher.cs b/JoysOfEfficiency/Automation/AutoFisher.cs index 63437f5..336f0b2 100644 --- a/JoysOfEfficiency/Automation/AutoFisher.cs +++ b/JoysOfEfficiency/Automation/AutoFisher.cs @@ -1,11 +1,13 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using JoysOfEfficiency.Core; using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; -using StardewModdingAPI; using StardewValley; +using StardewValley.GameData.WorldMaps; using StardewValley.Menus; using StardewValley.Objects; +using StardewValley.SpecialOrders; using StardewValley.Tools; namespace JoysOfEfficiency.Automation @@ -22,8 +24,6 @@ internal class AutoFisher private static int AutoFishingCounter { get; set; } private static int AfkCooltimeCounter { get; set; } - private static IReflectionHelper Reflection => InstanceHolder.Reflection; - public static void AfkFishing() { Farmer player = Game1.player; @@ -74,9 +74,9 @@ public static void AutoReelRod() { return; } - int whichFish = Reflection.GetField(rod, "whichFish").GetValue(); + String whichFish = rod.whichFish.QualifiedItemId; - if (!rod.isNibbling || !rod.isFishing || whichFish != -1 || rod.isReeling || rod.hit || + if (!rod.isNibbling || !rod.isFishing || whichFish != null || rod.isReeling || rod.hit || rod.isTimingCast || rod.pullingOutOfWater || rod.fishCaught || rod.castedButBobberStillInAir) { return; @@ -87,12 +87,10 @@ public static void AutoReelRod() public static void CollectFish(Farmer who, FishingRod rod) { - IReflectedField recastTimerMs = Reflection.GetField(rod, "recastTimerMs"); - - int whichFish = Reflection.GetField(rod, "whichFish").GetValue(); - int fishQuality = Reflection.GetField(rod, "fishQuality").GetValue(); - - string itemCategory = Reflection.GetField(rod, "itemCategory").GetValue(); + int recastTimerMs = rod.recastTimerMs; + String whichFish = rod.whichFish.QualifiedItemId; + int fishQuality = rod.fishQuality; + String itemCategory = rod.getCategoryName(); if (!Game1.isFestival()) { @@ -105,7 +103,7 @@ public static void CollectFish(Farmer who, FishingRod rod) who.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", new Rectangle(653, 858, 1, 1), 9999f, 1, 1, who.Position + new Vector2(Game1.random.Next(-3, 2) * 4, -32f), false, false, - (float) (who.getStandingY() / 10000.0 + 1.0 / 500.0), 0.04f, Color.LightBlue, 5f, 0.0f, + (float) (who.Tile.Y / 10000.0 + 1.0 / 500.0), 0.04f, Color.LightBlue, 5f, 0.0f, 0.0f, 0.0f) { acceleration = new Vector2(0.0f, 0.25f) @@ -120,28 +118,28 @@ public static void CollectFish(Farmer who, FishingRod rod) who.currentLocation.localSound("coin"); if (!rod.treasureCaught) { - recastTimerMs.SetValue(200); - Object @object = null; + rod.recastTimerMs = 200; + StardewValley.Object @object = null; switch (itemCategory) { case "Object": { - @object = new Object(whichFish, 1, false, -1, fishQuality); - if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM) + @object = new StardewValley.Object(whichFish, 1, false, -1, fishQuality); + if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM_QID) { @object.questItem.Value = true; } - if (whichFish == 79 || whichFish == 842) + if (whichFish == "79" || whichFish == "842") { @object = who.currentLocation.tryToCreateUnseenSecretNote(who); if (@object == null) return; } - if (rod.caughtDoubleFish) + if (rod.numberOfFishCaught > 1) { - @object.Stack = 2; + @object.Stack = rod.numberOfFishCaught; } break; @@ -179,12 +177,12 @@ public static void CollectFish(Farmer who, FishingRod rod) rod.showingTreasure = true; who.UsingTool = true; int initialStack = 1; - if (rod.caughtDoubleFish) + if (rod.numberOfFishCaught > 1) { - initialStack = 2; + initialStack = rod.numberOfFishCaught; } - Object @object = new Object(whichFish, initialStack, false, -1, fishQuality); + StardewValley.Object @object = new StardewValley.Object(whichFish, initialStack, false, -1, fishQuality); if (Game1.player.team.specialOrders.Count > 0) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) @@ -193,7 +191,7 @@ public static void CollectFish(Farmer who, FishingRod rod) } } bool inventoryBool = who.addItemToInventoryBool(@object); - rod.animations.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", new Rectangle(64, 1920, 32, 32), 500f, 1, 0, who.Position + new Vector2(-32f, -160f), false, false, (float)(who.getStandingY() / 10000.0 + 1.0 / 1000.0), 0.0f, Color.White, 4f, 0.0f, 0.0f, 0.0f) + rod.animations.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", new Rectangle(64, 1920, 32, 32), 500f, 1, 0, who.Position + new Vector2(-32f, -160f), false, false, (float)(who.Tile.Y / 10000.0 + 1.0 / 1000.0), 0.0f, Color.White, 4f, 0.0f, 0.0f, 0.0f) { motion = new Vector2(0.0f, -0.128f), timeBasedMotion = true, @@ -213,19 +211,15 @@ public static void AutoFishing(BobberBar bar) return; } - - IReflectedField bobberSpeed = Reflection.GetField(bar, "bobberBarSpeed"); - - float barPos = Reflection.GetField(bar, "bobberBarPos").GetValue(); - int barHeight = Reflection.GetField(bar, "bobberBarHeight").GetValue(); - float fishPos = Reflection.GetField(bar, "bobberPosition").GetValue(); - float treasurePos = Reflection.GetField(bar, "treasurePosition").GetValue(); - float distanceFromCatching = Reflection.GetField(bar, "distanceFromCatching").GetValue(); - bool treasureCaught = Reflection.GetField(bar, "treasureCaught").GetValue(); - bool treasure = Reflection.GetField(bar, "treasure").GetValue(); - float treasureAppearTimer = Reflection.GetField(bar, "treasureAppearTimer").GetValue(); - float bobberBarSpeed = bobberSpeed.GetValue(); - + float barPos = bar.bobberBarPos; + int barHeight = bar.bobberBarHeight; + float fishPos = bar.bobberPosition; + float treasurePos = bar.treasurePosition; + float distanceFromCatching = bar.distanceFromCatching; + bool treasureCaught = bar.treasureCaught; + bool treasure = bar.treasure; + float treasureAppearTimer = bar.treasureAppearTimer; + float bobberBarSpeed = bar.bobberBarSpeed; float top = barPos; if (treasure && treasureAppearTimer <= 0 && !treasureCaught) @@ -258,7 +252,7 @@ public static void AutoFishing(BobberBar bar) bobberBarSpeed = strength; } - bobberSpeed.SetValue(bobberBarSpeed); + bar.bobberBarSpeed = bobberBarSpeed; } public static void ToggleAfkFishing() diff --git a/JoysOfEfficiency/Automation/CollectibleCollector.cs b/JoysOfEfficiency/Automation/CollectibleCollector.cs index e2cc943..ed2b8c1 100644 --- a/JoysOfEfficiency/Automation/CollectibleCollector.cs +++ b/JoysOfEfficiency/Automation/CollectibleCollector.cs @@ -40,12 +40,12 @@ private static void CollectObj(GameLocation loc, SVObject obj) int quality = obj.Quality; Random random = new Random((int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed + (int)vector.X + (int)vector.Y * 777); - if (who.professions.Contains(16) && obj.isForage(loc)) + if (who.professions.Contains(16) && obj.isForage()) { obj.Quality = 4; } - else if (obj.isForage(loc)) + else if (obj.isForage()) { if (random.NextDouble() < who.ForagingLevel / 30f) { @@ -73,7 +73,7 @@ private static void CollectObj(GameLocation loc, SVObject obj) if (!loc.isFarmBuildingInterior()) { - if (obj.isForage(loc)) + if (obj.isForage()) { who.gainExperience(2, 7); } @@ -98,7 +98,7 @@ private static void CollectObj(GameLocation loc, SVObject obj) private static bool IsGinger(Crop crop) { - return crop != null && crop.forageCrop.Value && crop.whichForageCrop.Value == Crop.forageCrop_ginger; + return crop != null && crop.forageCrop.Value && crop.whichForageCrop.Value == Crop.forageCrop_ginger.ToString(); } private static void CollectGinger(GameLocation loc, Vector2 pos, HoeDirt dirt) @@ -113,7 +113,7 @@ private static void CollectGinger(GameLocation loc, Vector2 pos, HoeDirt dirt) if (dirt.crop.hitWithHoe((int)pos.X, (int)pos.Y, loc,dirt)) { who.Stamina -= stamina; - dirt.destroyCrop(pos, true, loc); + dirt.destroyCrop(true); } } } diff --git a/JoysOfEfficiency/Automation/FarmCleaner.cs b/JoysOfEfficiency/Automation/FarmCleaner.cs index cfadf9a..31a9a3f 100644 --- a/JoysOfEfficiency/Automation/FarmCleaner.cs +++ b/JoysOfEfficiency/Automation/FarmCleaner.cs @@ -3,7 +3,6 @@ using JoysOfEfficiency.Core; using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; -using StardewModdingAPI; using StardewValley; using StardewValley.Locations; using StardewValley.Tools; @@ -15,7 +14,6 @@ internal class FarmCleaner { private static Multiplayer Multiplayer => InstanceHolder.Multiplayer; private static Config Config => InstanceHolder.Config; - private static IReflectionHelper Reflection => InstanceHolder.Reflection; private static readonly Logger Logger = new Logger("FarmCleaner"); @@ -57,7 +55,7 @@ public static void OnEighthUpdate() private static void CutWeeds(GameLocation farm, Object obj, Vector2 loc) { - Reflection.GetMethod(obj, "cutWeed").Invoke(Game1.player, farm); + obj.cutWeed(Game1.player); farm.removeObject(loc, false); } @@ -74,7 +72,7 @@ private static bool ChopTwig(GameLocation farm, Object obj, Vector2 loc) obj.Fragility = 2; farm.playSound("axchop"); - farm.debris.Add(new Debris(new Object(388, 1), loc * 64f + new Vector2(32f, 32f))); + farm.debris.Add(new Debris(new Object("388", 1), loc * 64f + new Vector2(32f, 32f))); Game1.createRadialDebris(farm, 12, (int)loc.X, (int)loc.Y, Game1.random.Next(4, 10), false); Multiplayer.broadcastSprites(farm, new TemporaryAnimatedSprite(12, new Vector2(loc.X * 64f, loc.Y * 64f), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); @@ -110,7 +108,7 @@ private static bool BreakRock(GameLocation location, Tool pickaxe, Object @objec } } - if (@object.ParentSheetIndex < 200 && !Game1.objectInformation.ContainsKey(@object.ParentSheetIndex + 1)) + if (@object.ParentSheetIndex < 200 && !Game1.objectData.ContainsKey(""+(@object.ParentSheetIndex + 1))) { Multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(@object.ParentSheetIndex + 1, 300f, @@ -131,7 +129,7 @@ private static bool BreakRock(GameLocation location, Tool pickaxe, Object @objec acceleration = new Vector2(0.0f, 1f / 500f), alphaFade = 0.015f }); - location.OnStoneDestroyed(@object.ParentSheetIndex, num1, num2, Game1.player); + location.OnStoneDestroyed(""+@object.ParentSheetIndex, num1, num2, Game1.player); if (@object.MinutesUntilReady > 0) return false; location.Objects.Remove(new Vector2(num1, num2)); diff --git a/JoysOfEfficiency/Automation/FenceGateAutomation.cs b/JoysOfEfficiency/Automation/FenceGateAutomation.cs index 9bc17a5..7ee88bb 100644 --- a/JoysOfEfficiency/Automation/FenceGateAutomation.cs +++ b/JoysOfEfficiency/Automation/FenceGateAutomation.cs @@ -57,7 +57,7 @@ private static bool IsPlayerFaceOrBack(FenceType type, Farmer farmer) private static bool IsPlayerInClose(Fence fence, Farmer player) { Vector2 oVec = fence.TileLocation; - Vector2 pVec = player.getTileLocation(); + Vector2 pVec = player.Tile; return pVec == oVec || pVec == oVec + new Vector2(1, 0) || pVec == oVec + new Vector2(-1, 0) || pVec == oVec + new Vector2(0, 1) || pVec == oVec + new Vector2(0, -1); @@ -72,7 +72,7 @@ private static bool IsPlayerInClose(List fences, FenceType type, Farmer p foreach (Fence fence in fences.Where(f => f != null)) { Vector2 oVec = fence.TileLocation; - Vector2 pVec = player.getTileLocation(); + Vector2 pVec = player.Tile; if (oVec == pVec) { return true; diff --git a/JoysOfEfficiency/Automation/FlowerColorUnifier.cs b/JoysOfEfficiency/Automation/FlowerColorUnifier.cs index 42bb047..46206ce 100644 --- a/JoysOfEfficiency/Automation/FlowerColorUnifier.cs +++ b/JoysOfEfficiency/Automation/FlowerColorUnifier.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using JoysOfEfficiency.Core; using JoysOfEfficiency.Menus; @@ -10,7 +11,7 @@ namespace JoysOfEfficiency.Automation { - using SVObject = Object; + using SVObject = StardewValley.Object; internal class FlowerIndex { @@ -39,7 +40,8 @@ public static void UnifyFlowerColors() continue; } Color oldColor = crop.tintColor.Value; - switch (crop.indexOfHarvest.Value) + int harvestIndex = Int32.Parse(crop.indexOfHarvest.Value); + switch (harvestIndex) { case FlowerIndex.Poppy: //Poppy @@ -62,7 +64,7 @@ public static void UnifyFlowerColors() crop.tintColor.Value = Config.FairyRoseColor; break; default: - Color? color = GetCustomizedFlowerColor(crop.indexOfHarvest.Value); + Color? color = GetCustomizedFlowerColor(harvestIndex); if (color != null) { crop.tintColor.Value = color.Value; @@ -135,32 +137,32 @@ public static void ToggleFlowerColorUnification() return; } - int index = crop.indexOfHarvest.Value; + int harvestIndex = Int32.Parse(crop.indexOfHarvest.Value); - if (IsVanillaFlower(index)) + if (IsVanillaFlower(harvestIndex)) { Util.ShowHudMessage(Translation.Get("flower.vanilla")); return; } - if (GetCustomizedFlowerColor(index) != null) + if (GetCustomizedFlowerColor(harvestIndex) != null) { // Unregister flower - Config.CustomizedFlowerColors.Remove(crop.indexOfHarvest.Value); + Config.CustomizedFlowerColors.Remove(harvestIndex); InstanceHolder.WriteConfig(); - Util.ShowHudMessage(string.Format(Translation.Get("flower.unregister"), Util.GetItemName(index))); + Util.ShowHudMessage(string.Format(Translation.Get("flower.unregister"), harvestIndex)); return; } // Show flower registration menu Game1.playSound("bigSelect"); - Game1.activeClickableMenu = new RegisterFlowerMenu(800, 640, crop.tintColor.Value, index, RegisterFlowerColor); + Game1.activeClickableMenu = new RegisterFlowerMenu(800, 640, crop.tintColor.Value, harvestIndex, RegisterFlowerColor); } private static void RegisterFlowerColor(int whichFlower, Color color) { Config.CustomizedFlowerColors.Add(whichFlower, color); - Util.ShowHudMessage(string.Format(Translation.Get("flower.register"), Util.GetItemName(whichFlower))); + Util.ShowHudMessage(string.Format(Translation.Get("flower.register"), whichFlower)); } } } \ No newline at end of file diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index 59064a5..5b624f0 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -4,7 +4,6 @@ using JoysOfEfficiency.Core; using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; -using StardewModdingAPI; using StardewValley; using StardewValley.Objects; using StardewValley.TerrainFeatures; @@ -15,7 +14,6 @@ namespace JoysOfEfficiency.Automation { internal class HarvestAutomation { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; private static Config Config => InstanceHolder.Config; private static readonly Logger Logger = new Logger("HarvestAutomation"); @@ -69,9 +67,9 @@ public static void HarvestNearbyCrops(Farmer player) continue; } - if (dirt.crop.regrowAfterHarvest.Value == -1 || dirt.crop.forageCrop.Value) + if (dirt.crop.RegrowsAfterHarvest() == false || dirt.crop.forageCrop.Value) { - dirt.destroyCrop(loc, true, location); + dirt.destroyCrop(true); } } foreach (IndoorPot pot in Util.GetObjectsWithin(radius)) @@ -87,9 +85,9 @@ public static void HarvestNearbyCrops(Farmer player) continue; } - if (dirt.crop.regrowAfterHarvest.Value == -1 || dirt.crop.forageCrop.Value) + if (dirt.crop.RegrowsAfterHarvest() == false || dirt.crop.forageCrop.Value) { - dirt.destroyCrop(pot.TileLocation, true, location); + dirt.destroyCrop(true); } } } @@ -155,7 +153,7 @@ public static void ToggleBlacklistUnderCursor() } else { - string name = dirt.crop.forageCrop.Value ? Util.GetItemName(dirt.crop.whichForageCrop.Value) : Util.GetItemName(dirt.crop.indexOfHarvest.Value); + string name = dirt.crop.whichForageCrop.Value; if (name == "") { return; @@ -178,7 +176,7 @@ public static void DestroyNearDeadCrops(Farmer player) HoeDirt dirt = kv.Value; if (dirt.crop != null && dirt.crop.dead.Value) { - dirt.destroyCrop(loc, true, location); + dirt.destroyCrop(true); } } @@ -188,7 +186,7 @@ public static void DestroyNearDeadCrops(Farmer player) HoeDirt dirt = pot.hoeDirt.Value; if (dirt?.crop != null && dirt.crop.dead.Value) { - dirt.destroyCrop(loc, true, location); + dirt.destroyCrop(true); } } } @@ -198,17 +196,17 @@ public static void ShakeNearbyFruitedBush() int radius = InstanceHolder.Config.AutoShakeRadius; foreach (Bush bush in Game1.currentLocation.largeTerrainFeatures.OfType()) { - Vector2 loc = bush.tilePosition.Value; - Vector2 diff = loc - Game1.player.getTileLocation(); + Vector2 loc = bush.Tile; + Vector2 diff = loc - Game1.player.Tile; if (Math.Abs(diff.X) > radius || Math.Abs(diff.Y) > radius) continue; if (IsBushFruited(bush)) - bush.performUseAction(loc, Game1.currentLocation); + bush.performUseAction(loc); } } - public static void ShakeNearbyFruitedTree() + public static void ShakeNearbyFruitedTree() // RCB TODO... Broken for coconut trees [fine with bananas] { foreach (KeyValuePair kv in Util.GetFeaturesWithin(InstanceHolder.Config.AutoShakeRadius)) { @@ -225,44 +223,44 @@ public static void ShakeNearbyFruitedTree() } int num2; - switch (tree.treeType.Value) + switch (tree.treeType.Value) // treeType.Value is now a string! -RCB { - case 3: - num2 = 311; + case "3": + num2 = 311; // Pine Cone break; - case 1: - num2 = 309; + case "1": + num2 = 309; // Acorn break; - case 2: - num2 = 310; + case "2": + num2 = 310; // Maple Seed break; - case 6: - case 9: - num2 = 88; + case "6": + case "9": + num2 = 88; // Coconut break; default: num2 = -1; break; } - if (Game1.currentSeason.Equals("fall") && tree.treeType.Value == 2 && + if (Game1.currentSeason.Equals("fall") && tree.treeType.Value == "2" && Game1.dayOfMonth >= 14) { - num2 = 408; + num2 = 408; // Hazelnut } if (num2 != -1) - { - Reflection.GetMethod(tree, "shake").Invoke(loc, false, Game1.currentLocation); + { + tree.shake(loc, false); Logger.Log($@"Shook fruited tree @{loc}"); } } break; case FruitTree fruitTree: - if (fruitTree.growthStage.Value >= 4 && fruitTree.fruitsOnTree.Value > 0 && !fruitTree.stump.Value) + if (fruitTree.growthStage.Value >= 4 && fruitTree.fruit.Count > 0 && !fruitTree.stump.Value) { - fruitTree.shake(loc, false, Game1.currentLocation); + fruitTree.shake(loc, false); Logger.Log($@"Shook fruited tree @{loc}"); } break; @@ -279,20 +277,20 @@ public static void ShakeNearbyFruitedTree() private static bool IsBlackListed(Crop crop) { - int index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; - return InstanceHolder.Config.HarvestException.Contains(index); + String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; + return InstanceHolder.Config.HarvestException.Contains(Int32.Parse(index)); } private static bool ToggleBlackList(Crop crop) { - int index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; + String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; if (IsBlackListed(crop)) { - InstanceHolder.Config.HarvestException.Remove(index); + InstanceHolder.Config.HarvestException.Remove(Int32.Parse(index)); } else { - InstanceHolder.Config.HarvestException.Add(index); + InstanceHolder.Config.HarvestException.Add(Int32.Parse(index)); } InstanceHolder.WriteConfig(); @@ -339,7 +337,7 @@ private static bool IsBushFruited(Bush bush) { if (IsBerryBush(bush) || IsTeaBush(bush)) { - return bush.tileSheetOffset.Value == 1 && bush.inBloom(Game1.currentSeason, Game1.dayOfMonth); + return bush.tileSheetOffset.Value == 1 && bush.inBloom(); } return false; diff --git a/JoysOfEfficiency/Automation/InventoryAutomation.cs b/JoysOfEfficiency/Automation/InventoryAutomation.cs index f24702c..6c55091 100644 --- a/JoysOfEfficiency/Automation/InventoryAutomation.cs +++ b/JoysOfEfficiency/Automation/InventoryAutomation.cs @@ -1,7 +1,5 @@ -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Huds; +using JoysOfEfficiency.Huds; using JoysOfEfficiency.Utils; -using StardewModdingAPI; using StardewValley; using StardewValley.Menus; @@ -9,8 +7,6 @@ namespace JoysOfEfficiency.Automation { internal class InventoryAutomation { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; - private static readonly Logger Logger = new Logger("InventoryAutomation"); public static void LootAllAcceptableItems(ItemGrabMenu menu, bool skipCheck = false) @@ -81,7 +77,7 @@ public static void TryCloseItemGrabMenu(ItemGrabMenu menu) return; } - if (menu.context is Event && GetEssential(menu)) + if (menu.context is Event && menu.essential) { // You should not emergency close in events (it may stop the dialogue). return; @@ -96,10 +92,5 @@ public static void TryCloseItemGrabMenu(ItemGrabMenu menu) menu.exitThisMenu(); } - - private static bool GetEssential(ItemGrabMenu menu) - { - return Reflection.GetField(menu, "essential").GetValue(); - } } } diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/JoysOfEfficiency/Automation/MachineOperator.cs index 2059f9b..b155d03 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/JoysOfEfficiency/Automation/MachineOperator.cs @@ -12,10 +12,12 @@ namespace JoysOfEfficiency.Automation { internal class MachineOperator { + private static readonly Logger Logger = new Logger("MachineOperator"); + public static void DepositIngredientsToMachines() { Farmer player = Game1.player; - if (player.CurrentItem == null || !(Game1.player.CurrentItem is SVObject item)) + if (player.CurrentItem == null || !(player.CurrentItem is SVObject item)) { return; } @@ -31,8 +33,8 @@ public static void DepositIngredientsToMachines() return; } - bool flag = false; bool accepted = obj.Name == "Furnace" ? CanFurnaceAcceptItem(item, player) : Utility.isThereAnObjectHereWhichAcceptsThisItem(currentLocation, item, (int)loc.X * tileSize, (int)loc.Y * tileSize); + Logger.Log($"Trying to deposit ({accepted}) {item.Name} into machine: {obj.Name}"); if (obj is Cask) { if (ModEntry.IsCoGOn || ModEntry.IsCaOn) @@ -40,37 +42,36 @@ public static void DepositIngredientsToMachines() if (obj.performObjectDropInAction(item, true, player)) { obj.heldObject.Value = null; - flag = true; + accepted = true; } } - else if (currentLocation is Cellar && accepted) + else if (currentLocation is not Cellar && accepted) { - flag = true; + accepted = false; } } - else if (obj.Name == "Seed Maker") + else if (obj.Name == "Crab Pot") { - if (InstanceHolder.Config.AutoDepositSeedMaker == false) - { - flag = false; - } - else + if (item.Name == "Bait" || item.Name == "Magic Bait") { - flag = true; + accepted = true; + Logger.Log($"\tCrab Pot and {item.Name} are now ACCEPTED."); } } - else if (accepted) + else if (obj.Name == "Seed Maker") { - flag = true; + accepted = InstanceHolder.Config.AutoDepositSeedMaker == false ? false : true; } - if (!flag) + if (!accepted) continue; + Logger.Log($"Trying to drop {item.Name} into {obj}."); + // performObjectDropInAction but only if it's currently empty obj.performObjectDropInAction(item, false, player); if (!(obj.Name == "Furnace" || obj.Name == "Charcoal Kiln") || item.Stack == 0) { - player.reduceActiveItemByOne(); +// player.reduceActiveItemByOne(); } return; @@ -93,7 +94,7 @@ public static void PullMachineResult() private static bool CanFurnaceAcceptItem(Item item, Farmer player) { - if (player.getTallyOfObject(382, false) <= 0) + if (player.Items.ContainsId(Object.coalQID, 1)) return false; if (item.Stack < 5 && item.ParentSheetIndex != 80 && item.ParentSheetIndex != 82 && item.ParentSheetIndex != 330) return false; @@ -112,45 +113,14 @@ private static bool CanFurnaceAcceptItem(Item item, Farmer player) return true; } - - - private static bool IsObjectMachine(SVObject obj) { - if (obj is CrabPot) - return true; - - if (!obj.bigCraftable.Value) - return false; - - switch (obj.Name) + Logger.Log($"IsObjectMachine: Name: {obj.Name}"); + if (InstanceHolder.Config.MachineTypes.Contains(obj.Name)) { - case "Incubator": - case "Slime Incubator": - case "Keg": - case "Preserves Jar": - case "Cheese Press": - case "Mayonnaise Machine": - case "Loom": - case "Oil Maker": - case "Seed Maker": - case "Crystalarium": - case "Recycling Machine": - case "Furnace": - case "Charcoal Kiln": - case "Slime Egg-Press": - case "Cask": - case "Bee House": - case "Mushroom Box": - case "Statue Of Endless Fortune": - case "Statue Of Perfection": - case "Tapper": - case "Heavy Tapper": - case "Coffee Maker": - case "Worm Bin": - return true; - default: return false; + return true; } + return false; } } } diff --git a/JoysOfEfficiency/Automation/MailAutomation.cs b/JoysOfEfficiency/Automation/MailAutomation.cs index b0ba891..fed0ac2 100644 --- a/JoysOfEfficiency/Automation/MailAutomation.cs +++ b/JoysOfEfficiency/Automation/MailAutomation.cs @@ -1,7 +1,6 @@ -using System.Linq; -using JoysOfEfficiency.Core; +using System; +using System.Linq; using JoysOfEfficiency.Utils; -using StardewModdingAPI; using StardewValley; using StardewValley.Menus; using StardewValley.Quests; @@ -10,13 +9,11 @@ namespace JoysOfEfficiency.Automation { internal class MailAutomation { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; - private static readonly Logger Logger = new Logger("MailAutomation"); public static void CollectMailAttachmentsAndQuests(LetterViewerMenu menu) { - int questId = menu.questID; + String questId = menu.questID; if (menu.itemsLeftToGrab()) { @@ -43,7 +40,7 @@ public static void CollectMailAttachmentsAndQuests(LetterViewerMenu menu) } } - if (questId == -1) + if (questId == null) { return; } @@ -51,7 +48,7 @@ public static void CollectMailAttachmentsAndQuests(LetterViewerMenu menu) Logger.Log($"You started Quest: '{Quest.getQuestFromId(questId).questTitle}'."); Game1.player.addQuest(questId); Game1.playSound("newArtifact"); - menu.questID = -1; + menu.questID = null; } private static bool CanPlayerAcceptsItemPartially(Item item) diff --git a/JoysOfEfficiency/Automation/TrashCanScavenger.cs b/JoysOfEfficiency/Automation/TrashCanScavenger.cs index 57c1441..416f8a8 100644 --- a/JoysOfEfficiency/Automation/TrashCanScavenger.cs +++ b/JoysOfEfficiency/Automation/TrashCanScavenger.cs @@ -1,23 +1,16 @@ -using System; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; -using Netcode; -using StardewModdingAPI; +using JoysOfEfficiency.Core; +using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Locations; using xTile.Layers; -using Object = StardewValley.Object; namespace JoysOfEfficiency.Automation { internal class TrashCanScavenger { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; - private static readonly Logger Logger = new Logger("TrashCanScavenger"); - public static void ScavengeTrashCan() { - if (!(Game1.currentLocation is Town)) + if (!(Game1.currentLocation is Town town)) { return; } @@ -25,7 +18,9 @@ public static void ScavengeTrashCan() Farmer player = Game1.player; int radius = InstanceHolder.Config.BalancedMode ? 1 : InstanceHolder.Config.ScavengingRadius; Layer layer = Game1.currentLocation.Map.GetLayer("Buildings"); - int ox = player.getTileX(), oy = player.getTileY(); + Point currPos = player.TilePoint; + int ox = currPos.X; + int oy = currPos.Y; for (int dy = -radius; dy <= radius; dy++) { for (int dx = -radius; dx <= radius; dx++) @@ -34,87 +29,9 @@ public static void ScavengeTrashCan() if (layer.Tiles[x, y]?.TileIndex == 78) { - CollectTrashCan(x, y); - } - } - } - } - private static void CollectTrashCan(int x, int y) - { - if (!(Game1.currentLocation is Town town)) - { - return; - } - - NetArray garbageChecked = - Reflection.GetField>(town, "garbageChecked").GetValue(); - - string text = Game1.currentLocation.doesTileHaveProperty(x, y, "Action", "Buildings"); - int num = text != null ? Convert.ToInt32(text.Split(' ')[1]) : -1; - if (num >= 0 && num < garbageChecked.Length && !garbageChecked[num]) - { - garbageChecked[num] = true; - Game1.currentLocation.playSound("trashcan"); - Random random = new Random((int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed + 777 + num); - if (random.NextDouble() < 0.2 + Game1.player.DailyLuck) - { - int parentSheetIndex = 168; - switch (random.Next(10)) - { - case 0: - parentSheetIndex = 168; - break; - case 1: - parentSheetIndex = 167; - break; - case 2: - parentSheetIndex = 170; - break; - case 3: - parentSheetIndex = 171; - break; - case 4: - parentSheetIndex = 172; - break; - case 5: - parentSheetIndex = 216; - break; - case 6: - parentSheetIndex = Utility.getRandomItemFromSeason(Game1.currentSeason, x * 653 + y * 777, false); - break; - case 7: - parentSheetIndex = 403; - break; - case 8: - parentSheetIndex = 309 + random.Next(3); - break; - case 9: - parentSheetIndex = 153; - break; + string whichGarbage = Game1.currentLocation.doesTileHaveProperty(x, y, "Action", "Buildings"); + town.CheckGarbage(whichGarbage, new Vector2(x, y), Game1.player, true, true); } - switch (num) - { - case 3 when random.NextDouble() < 0.2 + Game1.player.DailyLuck: - parentSheetIndex = 535; - if (random.NextDouble() < 0.05) - { - parentSheetIndex = 749; - } - - break; - case 4 when random.NextDouble() < 0.2 + Game1.player.DailyLuck: - parentSheetIndex = 378 + random.Next(3) * 2; - break; - case 5 when random.NextDouble() < 0.2 + Game1.player.DailyLuck && Game1.dishOfTheDay != null: - parentSheetIndex = Game1.dishOfTheDay.ParentSheetIndex != 217 ? Game1.dishOfTheDay.ParentSheetIndex : 216; - break; - case 6 when random.NextDouble() < 0.2 + Game1.player.DailyLuck: - parentSheetIndex = 223; - break; - } - - Logger.Log($"You picked up trash @ [{x},{y}]"); - Game1.player.addItemByMenuIfNecessary(new Object(parentSheetIndex, 1)); } } } diff --git a/JoysOfEfficiency/Automation/WateringCanRefiller.cs b/JoysOfEfficiency/Automation/WateringCanRefiller.cs index cc9d5e4..73bea74 100644 --- a/JoysOfEfficiency/Automation/WateringCanRefiller.cs +++ b/JoysOfEfficiency/Automation/WateringCanRefiller.cs @@ -12,7 +12,7 @@ public static void RefillWateringCan() { WateringCan can = Util.FindToolFromInventory(Config.FindCanFromInventory); if (can == null || can.WaterLeft >= Util.GetMaxCan(can) || - !Util.IsThereAnyWaterNear(Game1.player.currentLocation, Game1.player.getTileLocation())) + !Util.IsThereAnyWaterNear(Game1.player.currentLocation, Game1.player.Tile)) { return; } diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index 7841a75..f1e841b 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using StardewModdingAPI; @@ -71,6 +72,42 @@ internal class Config public bool AutoPullMachineResult { get; set; } = true; public int MachineRadius { get; set; } = 1; + public List MachineTypes { get; set; } = new List() + { + "Bee House", + "Cask", + "Charcoal Kiln", + "Cheese Press", + "Coffee Maker", + "Crab Pot", + "Crystalarium", + "Furnace", + "Heavy Tapper", + "Incubator", + "Keg", + "Loom", + "Mayonnaise Machine", + "Mushroom Box", + "Oil Maker", + "Preserves Jar", + "Recycling Machine", + "Seed Maker", + "Sewing Machine", + "Slime Egg-Press", + "Slime Incubator", + "Statue Of Endless Fortune", + "Statue Of Perfection", + "Tapper", + "Worm Bin", + "Deluxe Worm Bin", + "Dehydrator", + "Mushroom Log", + "Bait Maker", + "Heavy Furnace", + "Fish Smoker", + "Anvil" + }; + //Fishing Probabilities public bool FishingProbabilitiesInfo { get; set; } = false; public Point ProbBoxCoordinates { get; set; } = new Point(100, 400); diff --git a/JoysOfEfficiency/Core/InstanceHolder.cs b/JoysOfEfficiency/Core/InstanceHolder.cs index 8931bb2..9ca77f5 100644 --- a/JoysOfEfficiency/Core/InstanceHolder.cs +++ b/JoysOfEfficiency/Core/InstanceHolder.cs @@ -14,15 +14,14 @@ internal class InstanceHolder public static Config Config { get; private set; } private static IModHelper Helper => ModInstance.Helper; public static ITranslationHelper Translation => Helper.Translation; - public static IReflectionHelper Reflection => Helper.Reflection; - public static Multiplayer Multiplayer => Reflection.GetField(typeof(Game1), "multiplayer").GetValue(); + public static Multiplayer Multiplayer => Game1.Multiplayer; - public static InputState Input => Reflection.GetField(typeof(Game1), "input").GetValue(); + public static InputState Input => Game1.input; public static CustomAnimalConfigHolder CustomAnimalTool; /// - /// Sets mod's entry point and configuration instance. + /// Sets mod's entry point and configuration instance. /// /// the mod instance /// the configuration instance @@ -32,7 +31,7 @@ public static void Init(ModEntry modInstance) Config = LoadConfig(); CustomAnimalTool = new CustomAnimalConfigHolder(modInstance.GetFilePath("customAnimalTools.json")); } - + /// /// Writes settings to '(ModFolder)/config.json'. /// diff --git a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs index 505215a..4e67f21 100644 --- a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs +++ b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs @@ -27,8 +27,9 @@ public static void DigNearbyArtifactSpots() { for (int j = -radius; j <= radius; j++) { - int x = player.getTileX() + i; - int y = player.getTileY() + j; + Point currPos = player.TilePoint; + int x = currPos.X + i; + int y = currPos.Y + j; Vector2 loc = new Vector2(x, y); if (!location.Objects.ContainsKey(loc) || location.Objects[loc].ParentSheetIndex != 590 || location.isTileHoeDirt(loc)) diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/JoysOfEfficiency/EventHandler/UpdateEvents.cs index 903c2f2..bfa42b2 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/JoysOfEfficiency/EventHandler/UpdateEvents.cs @@ -39,7 +39,7 @@ public void OnEveryUpdate() { return; } - + IdlePause.OnTickUpdate(); Farmer player = Game1.player; @@ -51,7 +51,6 @@ public void OnEveryUpdate() if (player.CurrentTool is FishingRod rod) { FishingProbabilitiesBox.UpdateProbabilities(rod); - AutoFisher.AfkFishing(); } @@ -85,8 +84,7 @@ private void OnGameEighthUpdate() } if (Game1.currentLocation is MineShaft shaft) { - bool isFallingDownShaft = InstanceHolder.Reflection.GetField(shaft, "isFallingDownShaft").GetValue(); - if (isFallingDownShaft) + if (shaft.isFallingDownShaft) { return; } @@ -105,6 +103,7 @@ private void OnGameEighthUpdate() { return; } + FarmCleaner.OnEighthUpdate(); if (Conf.AutoEat) { diff --git a/JoysOfEfficiency/Huds/FishInformationHud.cs b/JoysOfEfficiency/Huds/FishInformationHud.cs index 63a224d..d3af04b 100644 --- a/JoysOfEfficiency/Huds/FishInformationHud.cs +++ b/JoysOfEfficiency/Huds/FishInformationHud.cs @@ -12,25 +12,22 @@ namespace JoysOfEfficiency.Huds { internal class FishInformationHud { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; private static ITranslationHelper Translation => InstanceHolder.Translation; public static void DrawFishingInfoBox(SpriteBatch batch, BobberBar bar, SpriteFont font) { int width = 0, height = 120; - float scale = 1.0f; + String whichFish = bar.whichFish; + int fishSize = bar.fishSize; + int fishQuality = bar.fishQuality; + bool treasure = bar.treasure; + bool treasureCaught = bar.treasureCaught; + float treasureAppearTimer = bar.treasureAppearTimer; - int whichFish = Reflection.GetField(bar, "whichFish").GetValue(); - int fishSize = Reflection.GetField(bar, "fishSize").GetValue(); - int fishQuality = Reflection.GetField(bar, "fishQuality").GetValue(); - bool treasure = Reflection.GetField(bar, "treasure").GetValue(); - bool treasureCaught = Reflection.GetField(bar, "treasureCaught").GetValue(); - float treasureAppearTimer = Reflection.GetField(bar, "treasureAppearTimer").GetValue() / 1000; - - bool perfect = Reflection.GetField(bar, "perfect").GetValue(); + bool perfect = bar.perfect; if (perfect) { if(fishQuality >= 2) diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index c87dfd7..7581be0 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -7,6 +7,7 @@ using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; using StardewValley; +using StardewValley.GameData.Locations; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Tools; @@ -18,8 +19,6 @@ namespace JoysOfEfficiency.Huds { public class FishingProbabilitiesBox { - private static IReflectionHelper Reflection => InstanceHolder.Reflection; - private static readonly Logger Logger = new Logger("FishingProbabilitiesInfo"); private static Dictionary _fishingDictionary; @@ -39,7 +38,7 @@ public static void UpdateProbabilities(FishingRod rod) Rectangle rectangle = new Rectangle(location.fishSplashPoint.X * 64, location.fishSplashPoint.Y * 64, 64, 64); Rectangle value = new Rectangle((int)rod.bobber.X - 80, (int)rod.bobber.Y - 80, 64, 64); bool flag = rectangle.Intersects(value); - int clearWaterDistance = Reflection.GetField(rod, "clearWaterDistance").GetValue(); + int clearWaterDistance = rod.clearWaterDistance; _fishingDictionary = GetFishes(location, rod.attachments[0]?.ParentSheetIndex ?? -1, clearWaterDistance + (flag ? 1 : 0), Game1.player, InstanceHolder.Config.MorePreciseProbabilities ? InstanceHolder.Config.TrialOfExamine : 1); } @@ -101,7 +100,9 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, str Dictionary dictionary = Game1.content.Load>("Data\\Locations"); string key = locationName ?? Game1.currentLocation.Name; - if (key.Equals("WitchSwamp") && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") && !Game1.player.hasItemInInventory(308, 1)) + if (key.Equals("WitchSwamp") + && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") + && !Game1.player.Items.ContainsId("(O)308", 1)) { return new Dictionary { @@ -132,7 +133,10 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, str string[] array3 = dictionary3[Convert.ToInt32(t)].Split('/'); string[] array4 = array3[5].Split(' '); int num2 = Convert.ToInt32(dictionary2[t]); - if (num2 == -1 || Game1.currentLocation.getFishingLocation(who.getTileLocation()) == num2) + String fishAreaId = ""; + FishAreaData fishAreaData; + Game1.currentLocation.TryGetFishAreaForTile(who.Tile, out fishAreaId, out fishAreaData); + if (num2 == -1 || Int32.Parse(fishAreaId) == num2) { int num3 = 0; while (num3 < array4.Length) @@ -367,7 +371,7 @@ private static void DrawProbBox(Dictionary probabilities) foreach (KeyValuePair kv in probabilities) { string text = $"{kv.Value * 100:f1}%"; - Object fish = new Object(kv.Key, 1); + Object fish = new Object(""+kv.Key, 1); fish.drawInMenu(b, new Vector2(x + 8, y), 1.0f); Utility.drawTextWithShadow(b, text, font, new Vector2(x + 32 + square, y + 16), Color.Black); diff --git a/JoysOfEfficiency/Huds/GiftInformationTooltip.cs b/JoysOfEfficiency/Huds/GiftInformationTooltip.cs index 6361e9b..7d883b6 100644 --- a/JoysOfEfficiency/Huds/GiftInformationTooltip.cs +++ b/JoysOfEfficiency/Huds/GiftInformationTooltip.cs @@ -29,7 +29,7 @@ public static void UpdateTooltip() return; } - List npcList = player.currentLocation.characters.Where(a => a != null && a.isVillager()).ToList(); + List npcList = player.currentLocation.characters.Where(a => a != null && a.IsVillager).ToList(); foreach (NPC npc in npcList) { Rectangle npcRect = new Rectangle( @@ -62,7 +62,7 @@ public static void UpdateTooltip() key.Append("gavetoday."); _unableToGift = true; } - else if (npc.canReceiveThisItemAsGift(player.CurrentItem)) + else if (npc.tryToReceiveActiveObject(player, probe: true)) { switch (npc.getGiftTasteForThisItem(player.CurrentItem)) { @@ -90,7 +90,7 @@ public static void UpdateTooltip() } switch (npc.Gender) { - case NPC.female: + case Gender.Female: key.Append("female"); break; default: diff --git a/JoysOfEfficiency/JoysOfEfficiency.csproj b/JoysOfEfficiency/JoysOfEfficiency.csproj index 6cde001..671c1ef 100644 --- a/JoysOfEfficiency/JoysOfEfficiency.csproj +++ b/JoysOfEfficiency/JoysOfEfficiency.csproj @@ -2,13 +2,13 @@ - net5.0 + net6.0 Library Properties JoysOfEfficiency JoysOfEfficiency 512 - 1.4.9 + 1.5.0 true @@ -56,12 +56,9 @@ PreserveNewest - - - - + - + diff --git a/JoysOfEfficiency/Menus/RegisterFlowerMenu.cs b/JoysOfEfficiency/Menus/RegisterFlowerMenu.cs index ac94e7c..a5a169b 100644 --- a/JoysOfEfficiency/Menus/RegisterFlowerMenu.cs +++ b/JoysOfEfficiency/Menus/RegisterFlowerMenu.cs @@ -41,7 +41,7 @@ public RegisterFlowerMenu(int width, int height, Color initialColor, int item, A _elements.Add(new EmptyLabel()); if (item != -1) { - string s = string.Format(InstanceHolder.Translation.Get("options.flower"), Util.GetItemName(item)); + string s = string.Format(InstanceHolder.Translation.Get("options.flower"), item.ToString()); _elements.Add(new LabelComponent(s)); _itemIndex = item; } diff --git a/JoysOfEfficiency/Utils/Util.cs b/JoysOfEfficiency/Utils/Util.cs index 347f5b3..2fe2408 100644 --- a/JoysOfEfficiency/Utils/Util.cs +++ b/JoysOfEfficiency/Utils/Util.cs @@ -6,7 +6,6 @@ using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; using StardewValley; -using StardewValley.Locations; using StardewValley.Menus; using StardewValley.TerrainFeatures; using StardewValley.Tools; @@ -22,8 +21,6 @@ internal class Util { private static ITranslationHelper Translation => InstanceHolder.Translation; private static Config Config => InstanceHolder.Config; - - private static int _lastItemIndex; public static bool IsAndroid() @@ -31,11 +28,6 @@ public static bool IsAndroid() return Constants.TargetPlatform == GamePlatform.Android; } - public static string GetItemName(int parentSheetIndex) - { - return new SVObject(parentSheetIndex, 1).DisplayName; - } - public static T FindToolFromInventory(bool fromEntireInventory) where T : Tool { Player player = Game1.player; @@ -61,7 +53,7 @@ public static float Cap(float f, float min, float max) return f < min ? min : (f > max ? max : f); } - + public static void ShowHudMessage(string message, int duration = 3500) { @@ -159,7 +151,10 @@ public static bool IsThereAnyWaterNear(GameLocation location, Vector2 tileLocati { Vector2 toCheck = tileLocation + new Vector2(i, j); int x = (int)toCheck.X, y = (int)toCheck.Y; - if (location.doesTileHaveProperty(x, y, "Water", "Back") != null || location.doesTileHaveProperty(x, y, "WaterSource", "Back") != null || location is BuildableGameLocation loc2 && loc2.buildings.Where(b => b.occupiesTile(toCheck)).Any(building => building.buildingType.Value == "Well")) + if (location.doesTileHaveProperty(x, y, "Water", "Back") != null + || location.doesTileHaveProperty(x, y, "WaterSource", "Back") != null + || location.IsBuildableLocation() + && location.buildings.Where(b => b.occupiesTile(toCheck)).Any(building => building.buildingType.Value == "Well")) { return true; } @@ -189,7 +184,7 @@ public static List GetObjectsWithin(int radius, bool ignoreBalancedMode = } GameLocation location = player.currentLocation; - Vector2 ov = player.getTileLocation(); + Vector2 ov = player.Tile; List list = new List(); for (int dx = -radius; dx <= radius; dx++) { @@ -289,28 +284,29 @@ public static int GetMaxCan(WateringCan can) { if (can == null) return -1; + int waterCanSize; switch (can.UpgradeLevel) { case 0: - can.waterCanMax = 40; + waterCanSize = 40; break; case 1: - can.waterCanMax = 55; + waterCanSize = 55; break; case 2: - can.waterCanMax = 70; + waterCanSize = 70; break; case 3: - can.waterCanMax = 85; + waterCanSize= 85; break; case 4: - can.waterCanMax = 100; + waterCanSize = 100; break; default: return -1; } - return can.waterCanMax; + return waterCanSize; } @@ -336,14 +332,13 @@ public static Dictionary GetFeaturesWithin(int radius) where T : radius = 1; } GameLocation location = player.currentLocation; - Vector2 ov = player.getTileLocation(); Dictionary list = new Dictionary(); for (int dx = -radius; dx <= radius; dx++) { for (int dy = -radius; dy <= radius; dy++) { - Vector2 loc = ov + new Vector2(dx, dy); + Vector2 loc = player.Tile + new Vector2(dx, dy); if (location.terrainFeatures.ContainsKey(loc) && location.terrainFeatures[loc] is T t) { list.Add(loc, t); @@ -358,12 +353,6 @@ public static Vector2 GetLocationOf(GameLocation location, SVObject obj) return location.Objects.Pairs.Any(kv => kv.Value == obj) ? location.Objects.Pairs.First(kv => kv.Value == obj).Key : new Vector2(-1, -1); } - - - - - - private static void DrawItemPickupHud(Item item) { @@ -393,7 +382,8 @@ private static void DrawItemPickupHud(Item item) } } - addHUDMessage(new HUDMessage(text, Math.Max(1, item.Stack), true, color, item)); +// addHUDMessage(new HUDMessage(text, Math.Max(1, item.Stack), true, color, item)); + addHUDMessage(new HUDMessage(text, 3.0f, true)); } public static int GetTruePrice(Item item) diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 39c18fa..3f6c620 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -2,9 +2,9 @@ "Author": "punyo", "Description": "Adds many useful functions to make gameplay more efficient", "EntryDll": "JoysOfEfficiency.dll", - "MinimumApiVersion": "3.8", + "MinimumApiVersion": "3.9", "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.4.9" + "Version": "1.5.0-unofficial.1-Hackswell" } diff --git a/JoysOfEfficiency/packages.config b/JoysOfEfficiency/packages.config index ebb72ce..fb99453 100644 --- a/JoysOfEfficiency/packages.config +++ b/JoysOfEfficiency/packages.config @@ -1,5 +1,5 @@  - - - \ No newline at end of file + + + diff --git a/global.json b/global.json index 2c43f91..87aef9f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "5.0.0", + "version": "6.0.0", "rollForward": "latestMajor", "allowPrerelease": false } diff --git a/testplan.txt b/testplan.txt new file mode 100644 index 0000000..0da8268 --- /dev/null +++ b/testplan.txt @@ -0,0 +1,65 @@ + ++[Fence Gate Automation] + ++[Farm Cleaner] -- Should probably default to OFF, especially early game. ++[Watering Can Refiller] ++[Harvest Automation] + +Autofill watering can + +Water nearby crops + +Harvest nearby crops + +Does NOT harvest crops on exclusion list + +Destroy dead crops + +Shake trees / fruit trees + +O[MachineOperator] + Auto pull + Auto push [Crab pot? Cask?] + -- TODO: Furnace neither pushes nor pulls + ++[Animal Automation] + +Pet nearby animals + +Pet nearby pets + +Auto shear/milk + ++[Gift Information Tooltip] + ++Balanced Mode [every 1s for balanced, super fast otherwise] + ++[Mine HUD] + +[Food Automation] -- UNTESTED + Auto eat + +[Shipping Estimator] -- Is this even needed in 1.6 any more? + +[FPS Counter] -- UNTESTED + +[Trash can Scavenger] -- UNTESTED +O[Collectible Collector] + XSeed Spots -- TODO + +Artifact auto digger + +Collect nearby collectibles + +[Inventory Automation] + Treasure Auto-grab + +[Fishing] -- UNTESTED + Fishing Probabilities Box + Fish Info HUD + Autofisher - AFK + Auto Reel Rod + +[Flower Color Unifier] -- UNTESTED + Unify Flower Colors + +[Mail Automation] -- UNTESTED + +[Idle Pause] -- UNTESTED + + + + + + + + From defaa1a18b11dda19b35828f0b4e5e9c49f8b624 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:46:15 -0400 Subject: [PATCH 06/29] [Hackswell] ArtifactSpotDigger also digs SeedSpots. --- .../Automation/MachineOperator.cs | 10 +++++---- .../EventHandler/ArtifactSpotDigger.cs | 17 +++++++++------ JoysOfEfficiency/Utils/Logger.cs | 6 +++++- JoysOfEfficiency/Utils/Util.cs | 1 - testplan.txt | 21 +++++++------------ 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/JoysOfEfficiency/Automation/MachineOperator.cs index b155d03..53b080b 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/JoysOfEfficiency/Automation/MachineOperator.cs @@ -30,11 +30,12 @@ public static void DepositIngredientsToMachines() if (obj.Name == "Keg" && item.ParentSheetIndex == 433 && item.Stack < 5) { // You don't have enough beans. + Logger.Info($"Trying to deposit {item.Name} into KEG: {obj.Name}. Not enough beans!"); return; } bool accepted = obj.Name == "Furnace" ? CanFurnaceAcceptItem(item, player) : Utility.isThereAnObjectHereWhichAcceptsThisItem(currentLocation, item, (int)loc.X * tileSize, (int)loc.Y * tileSize); - Logger.Log($"Trying to deposit ({accepted}) {item.Name} into machine: {obj.Name}"); + Logger.Info($"Trying to deposit ({accepted}) {item.Name} into machine: {obj.Name}"); if (obj is Cask) { if (ModEntry.IsCoGOn || ModEntry.IsCaOn) @@ -55,7 +56,7 @@ public static void DepositIngredientsToMachines() if (item.Name == "Bait" || item.Name == "Magic Bait") { accepted = true; - Logger.Log($"\tCrab Pot and {item.Name} are now ACCEPTED."); + Logger.Info($"\tCrab Pot and {item.Name} are now ACCEPTED."); } } else if (obj.Name == "Seed Maker") @@ -66,13 +67,14 @@ public static void DepositIngredientsToMachines() if (!accepted) continue; - Logger.Log($"Trying to drop {item.Name} into {obj}."); + Logger.Info($"Trying to drop {item.Name} into {obj}."); // performObjectDropInAction but only if it's currently empty obj.performObjectDropInAction(item, false, player); if (!(obj.Name == "Furnace" || obj.Name == "Charcoal Kiln") || item.Stack == 0) { -// player.reduceActiveItemByOne(); + player.reduceActiveItemByOne(); } + Logger.Info($"DONE dropping {item.Name} into {obj}."); return; } diff --git a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs index 4e67f21..de1480d 100644 --- a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs +++ b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs @@ -10,6 +10,7 @@ namespace JoysOfEfficiency.EventHandler internal class ArtifactSpotDigger { private static Config Config => InstanceHolder.Config; + private static readonly Logger Logger = new Logger("ArtifactSpotDigger"); public static void DigNearbyArtifactSpots() { @@ -31,15 +32,19 @@ public static void DigNearbyArtifactSpots() int x = currPos.X + i; int y = currPos.Y + j; Vector2 loc = new Vector2(x, y); - if (!location.Objects.ContainsKey(loc) || location.Objects[loc].ParentSheetIndex != 590 || - location.isTileHoeDirt(loc)) + if (!location.Objects.ContainsKey(loc) || location.isTileHoeDirt(loc)) { continue; } - location.digUpArtifactSpot(x, y, player); - location.Objects.Remove(loc); - location.terrainFeatures.Add(loc, new HoeDirt()); - flag = true; + + if (location.Objects[loc].name == "Artifact Spot" || location.Objects[loc].name == "Seed Spot") + { + Logger.Info($"** {location.Objects[loc].name} ** at [{loc.X},{loc.Y}]"); + location.digUpArtifactSpot(x, y, player); + location.Objects.Remove(loc); + location.terrainFeatures.Add(loc, new HoeDirt()); + flag = true; + } } } diff --git a/JoysOfEfficiency/Utils/Logger.cs b/JoysOfEfficiency/Utils/Logger.cs index 9f9538f..7db76cc 100644 --- a/JoysOfEfficiency/Utils/Logger.cs +++ b/JoysOfEfficiency/Utils/Logger.cs @@ -7,7 +7,6 @@ public class Logger public static IMonitor Monitor { get; private set; - } public static void Init(IMonitor monitor) @@ -26,6 +25,11 @@ public void Log(string text, LogLevel level = LogLevel.Trace) Monitor.Log($"[{Name}]{text}", level); } + public void Info(string text, LogLevel level = LogLevel.Info) + { + Monitor.Log($"[{Name}]{text}", level); + } + public void Error(string text) { Log(text, LogLevel.Error); diff --git a/JoysOfEfficiency/Utils/Util.cs b/JoysOfEfficiency/Utils/Util.cs index 2fe2408..246e291 100644 --- a/JoysOfEfficiency/Utils/Util.cs +++ b/JoysOfEfficiency/Utils/Util.cs @@ -382,7 +382,6 @@ private static void DrawItemPickupHud(Item item) } } -// addHUDMessage(new HUDMessage(text, Math.Max(1, item.Stack), true, color, item)); addHUDMessage(new HUDMessage(text, 3.0f, true)); } diff --git a/testplan.txt b/testplan.txt index 0da8268..3760e77 100644 --- a/testplan.txt +++ b/testplan.txt @@ -34,12 +34,13 @@ O[MachineOperator] [FPS Counter] -- UNTESTED -[Trash can Scavenger] -- UNTESTED -O[Collectible Collector] - XSeed Spots -- TODO ++[Trash can Scavenger] + ++[Collectible Collector] + +Seed Spots auto digger +Artifact auto digger +Collect nearby collectibles - + [Inventory Automation] Treasure Auto-grab @@ -48,18 +49,10 @@ O[Collectible Collector] Fish Info HUD Autofisher - AFK Auto Reel Rod - + [Flower Color Unifier] -- UNTESTED Unify Flower Colors - + [Mail Automation] -- UNTESTED [Idle Pause] -- UNTESTED - - - - - - - - From 485778a0295d189bf183ca1bbcf3fb764e5e6a45 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Mon, 25 Mar 2024 09:49:43 -0400 Subject: [PATCH 07/29] [Hackswell] Furnaces working again. --- .../Automation/MachineOperator.cs | 31 ++++++++++++------ testplan.txt | 32 +++++++++++-------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/JoysOfEfficiency/Automation/MachineOperator.cs index 53b080b..a627d6e 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/JoysOfEfficiency/Automation/MachineOperator.cs @@ -96,19 +96,30 @@ public static void PullMachineResult() private static bool CanFurnaceAcceptItem(Item item, Farmer player) { - if (player.Items.ContainsId(Object.coalQID, 1)) - return false; - if (item.Stack < 5 && item.ParentSheetIndex != 80 && item.ParentSheetIndex != 82 && item.ParentSheetIndex != 330) + Logger.Info($"{player.Items.ContainsId(Object.coalQID)} ** {item.Stack} ** {item.ParentSheetIndex}"); + + // Minimum of one coal in inventory + if (! player.Items.ContainsId(Object.coalQID, 1)) return false; - switch (item.ParentSheetIndex) + + switch (item.Name) { - case 378: // Copper Ore - case 380: // Iron Ore - case 384: // Gold Ore - case 386: // Iridium Ore - case 80: // Quartz - case 82: // Fire Quartz + // One item per coal... + case "Clay": + case "Quartz": + case "Fire Quartz": break; + + // Five items per coal... + case "Copper Ore": + case "Iron Ore": + case "Gold Ore": + case "Iridium Ore": + case "Radioactive Ore": + if (item.Stack < 5) + return false; + break; + default: return false; } diff --git a/testplan.txt b/testplan.txt index 3760e77..d4248e2 100644 --- a/testplan.txt +++ b/testplan.txt @@ -1,7 +1,13 @@ +*** KNOWN BROKEN *** +-------------------- + + +*** APPARENTLY WORKING *** +-------------------------- +[Fence Gate Automation] -+[Farm Cleaner] -- Should probably default to OFF, especially early game. ++[Farm Cleaner] +[Watering Can Refiller] +[Harvest Automation] +Autofill watering can @@ -11,10 +17,9 @@ +Destroy dead crops +Shake trees / fruit trees -O[MachineOperator] - Auto pull - Auto push [Crab pot? Cask?] - -- TODO: Furnace neither pushes nor pulls ++[MachineOperator] + +Auto pull + +Auto push +[Animal Automation] +Pet nearby animals @@ -27,13 +32,6 @@ O[MachineOperator] +[Mine HUD] -[Food Automation] -- UNTESTED - Auto eat - -[Shipping Estimator] -- Is this even needed in 1.6 any more? - -[FPS Counter] -- UNTESTED - +[Trash can Scavenger] +[Collectible Collector] @@ -41,9 +39,17 @@ O[MachineOperator] +Artifact auto digger +Collect nearby collectibles -[Inventory Automation] ++[Shipping Estimator] + + +*** UNTESTED *** +---------------- +[Inventory Automation] -- UNTESTED Treasure Auto-grab +[Food Automation] -- UNTESTED + Auto eat + [Fishing] -- UNTESTED Fishing Probabilities Box Fish Info HUD From 26401a0eadc5e4f8751994291c996b39596ebd20 Mon Sep 17 00:00:00 2001 From: Tonho da lua Date: Mon, 25 Mar 2024 16:14:03 -0300 Subject: [PATCH 08/29] no reflections commit --- JoysOfEfficiency.sln | 14 +++-- JoysOfEfficiency/Automation/AutoFisher.cs | 72 ++++++++++++++--------- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/JoysOfEfficiency.sln b/JoysOfEfficiency.sln index a17ea7d..95b4f6e 100644 --- a/JoysOfEfficiency.sln +++ b/JoysOfEfficiency.sln @@ -1,8 +1,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29424.173 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34714.143 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JoysOfEfficiency", "JoysOfEfficiency\JoysOfEfficiency.csproj", "{0302444C-4190-4C5D-A873-A1F80267961A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JoysOfEfficiency", "JoysOfEfficiency\JoysOfEfficiency.csproj", "{0302444C-4190-4C5D-A873-A1F80267961A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -12,11 +12,15 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.Build.0 = Release|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Build.0 = Debug|Any CPU {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|x86.ActiveCfg = Debug|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Debug|x86.Build.0 = Debug|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Release|Any CPU.Build.0 = Release|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Release|x86.ActiveCfg = Release|Any CPU + {0302444C-4190-4C5D-A873-A1F80267961A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/JoysOfEfficiency/Automation/AutoFisher.cs b/JoysOfEfficiency/Automation/AutoFisher.cs index 336f0b2..29884e5 100644 --- a/JoysOfEfficiency/Automation/AutoFisher.cs +++ b/JoysOfEfficiency/Automation/AutoFisher.cs @@ -74,9 +74,11 @@ public static void AutoReelRod() { return; } - String whichFish = rod.whichFish.QualifiedItemId; - if (!rod.isNibbling || !rod.isFishing || whichFish != null || rod.isReeling || rod.hit || + // if instance here gives error so i instance in the if. + // String whichFish = rod.whichFish.QualifiedItemId; + + if (!rod.isNibbling || !rod.isFishing || rod.whichFish != null || rod.isReeling || rod.hit || rod.isTimingCast || rod.pullingOutOfWater || rod.fishCaught || rod.castedButBobberStillInAir) { return; @@ -90,7 +92,7 @@ public static void CollectFish(Farmer who, FishingRod rod) int recastTimerMs = rod.recastTimerMs; String whichFish = rod.whichFish.QualifiedItemId; int fishQuality = rod.fishQuality; - String itemCategory = rod.getCategoryName(); + int itemCategory = rod.whichFish.GetParsedData().Category; if (!Game1.isFestival()) { @@ -118,42 +120,57 @@ public static void CollectFish(Farmer who, FishingRod rod) who.currentLocation.localSound("coin"); if (!rod.treasureCaught) { - rod.recastTimerMs = 200; StardewValley.Object @object = null; switch (itemCategory) { - case "Object": - { - @object = new StardewValley.Object(whichFish, 1, false, -1, fishQuality); - if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM_QID) + case -24: { - @object.questItem.Value = true; + @object = new Furniture(whichFish, Vector2.Zero); + break; } - if (whichFish == "79" || whichFish == "842") + + case -4: { - @object = who.currentLocation.tryToCreateUnseenSecretNote(who); - if (@object == null) - return; + @object = new StardewValley.Object(whichFish, 1, false, -1, fishQuality); + if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM_QID) + { + @object.questItem.Value = true; + } + if (whichFish == "79" || whichFish == "842") + { + @object = who.currentLocation.tryToCreateUnseenSecretNote(who); + if (@object == null) return; + } + if (rod.numberOfFishCaught > 1) + { + @object.Stack = 2; + } + break; } - - if (rod.numberOfFishCaught > 1) + default: { - @object.Stack = rod.numberOfFishCaught; + @object = new StardewValley.Object(whichFish, 1, false, -1); + if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM_QID) + { + @object.questItem.Value = true; + } + if (whichFish == "79" || whichFish == "842") + { + @object = who.currentLocation.tryToCreateUnseenSecretNote(who); + if (@object == null) return; + } + if (rod.numberOfFishCaught > 1) + { + @object.Stack = 2; + } + break; } - - break; - } - case "Furniture": - { - @object = new Furniture(whichFish, Vector2.Zero); - break; - } } bool fromFishPond = rod.fromFishPond; who.completelyStopAnimatingOrDoingAction(); rod.doneFishing(who, !fromFishPond); - if (!Game1.isFestival() && !fromFishPond && (itemCategory == "Object" && Game1.player.team.specialOrders.Count > 0)) + if (!Game1.isFestival() && !fromFishPond && (itemCategory == -4 && Game1.player.team.specialOrders.Count > 0)) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { @@ -166,10 +183,7 @@ public static void CollectFish(Farmer who, FishingRod rod) return; } - Game1.activeClickableMenu = new ItemGrabMenu(new List - { - @object - }, rod).setEssential(true); + Game1.activeClickableMenu = new ItemGrabMenu(new List { @object }, rod).setEssential(true); } else { From 1861eeb9f0520abf3859ddde18789b6b6bbfa3dc Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Tue, 26 Mar 2024 21:23:11 -0400 Subject: [PATCH 09/29] [Hackswell] FishingProbabilityBox should be working much better now. Still not fully tested though. --- JoysOfEfficiency/Automation/AutoFisher.cs | 111 +++--- JoysOfEfficiency/Core/Config.cs | 2 +- .../Huds/FishingProbabilitiesBox.cs | 346 +++++++++++------- JoysOfEfficiency/manifest.json | 4 +- testplan.txt | 20 +- 5 files changed, 266 insertions(+), 217 deletions(-) diff --git a/JoysOfEfficiency/Automation/AutoFisher.cs b/JoysOfEfficiency/Automation/AutoFisher.cs index 29884e5..2e46b54 100644 --- a/JoysOfEfficiency/Automation/AutoFisher.cs +++ b/JoysOfEfficiency/Automation/AutoFisher.cs @@ -4,11 +4,12 @@ using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; -using StardewValley.GameData.WorldMaps; +using StardewValley.ItemTypeDefinitions; using StardewValley.Menus; using StardewValley.Objects; using StardewValley.SpecialOrders; using StardewValley.Tools; +using Object = StardewValley.Object; namespace JoysOfEfficiency.Automation { @@ -16,10 +17,13 @@ internal class AutoFisher { private static Config Config => InstanceHolder.Config; - private static readonly Logger Logger = new Logger("AFKFisher"); + private static readonly Logger Logger = new Logger("AutoFisher"); public static bool AfkMode { get; private set; } + public static int fishQuality { get; set; } + public static bool treasure { get; set; } + private static bool CatchingTreasure { get; set; } private static int AutoFishingCounter { get; set; } private static int AfkCooltimeCounter { get; set; } @@ -75,9 +79,6 @@ public static void AutoReelRod() return; } - // if instance here gives error so i instance in the if. - // String whichFish = rod.whichFish.QualifiedItemId; - if (!rod.isNibbling || !rod.isFishing || rod.whichFish != null || rod.isReeling || rod.hit || rod.isTimingCast || rod.pullingOutOfWater || rod.fishCaught || rod.castedButBobberStillInAir) { @@ -87,12 +88,13 @@ public static void AutoReelRod() rod.DoFunction(player.currentLocation, 1, 1, 1, player); } - public static void CollectFish(Farmer who, FishingRod rod) + private static void CollectFish(Farmer who, FishingRod rod) { - int recastTimerMs = rod.recastTimerMs; - String whichFish = rod.whichFish.QualifiedItemId; - int fishQuality = rod.fishQuality; - int itemCategory = rod.whichFish.GetParsedData().Category; + ItemMetadata whichFish = rod.whichFish; + String whichFishName = rod.whichFish.QualifiedItemId; + fishQuality = rod.fishQuality; + string fishID = whichFish.GetParsedData().ItemId; + int itemCategory = whichFish.GetParsedData().Category; if (!Game1.isFestival()) { @@ -100,18 +102,6 @@ public static void CollectFish(Farmer who, FishingRod rod) who.FarmerSprite.setCurrentFrame(84); } - if (Game1.random.NextDouble() < 0.025) - { - who.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", - new Rectangle(653, 858, 1, 1), 9999f, 1, 1, - who.Position + new Vector2(Game1.random.Next(-3, 2) * 4, -32f), false, false, - (float) (who.Tile.Y / 10000.0 + 1.0 / 500.0), 0.04f, Color.LightBlue, 5f, 0.0f, - 0.0f, 0.0f) - { - acceleration = new Vector2(0.0f, 0.25f) - }); - } - if (!who.IsLocalPlayer) { return; @@ -120,57 +110,47 @@ public static void CollectFish(Farmer who, FishingRod rod) who.currentLocation.localSound("coin"); if (!rod.treasureCaught) { - StardewValley.Object @object = null; + Object @object = null; switch (itemCategory) { - case -24: + case Object.furnitureCategory: + { + @object = new Furniture(fishID, Vector2.Zero); + break; + } + case Object.FishCategory: + { + @object = new StardewValley.Object(fishID, 1, false, -1, fishQuality); + if (fishID == GameLocation.CAROLINES_NECKLACE_ITEM_QID) { - @object = new Furniture(whichFish, Vector2.Zero); + @object.questItem.Value = true; break; } - - case -4: + if (fishID == "79" || fishID == "842") // Secret Note (79) or Journal Scrap (842) { - @object = new StardewValley.Object(whichFish, 1, false, -1, fishQuality); - if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM_QID) - { - @object.questItem.Value = true; - } - if (whichFish == "79" || whichFish == "842") - { - @object = who.currentLocation.tryToCreateUnseenSecretNote(who); - if (@object == null) return; - } - if (rod.numberOfFishCaught > 1) - { - @object.Stack = 2; - } - break; + @object = who.currentLocation.tryToCreateUnseenSecretNote(who); + if (@object == null) return; } - default: + + if (rod.numberOfFishCaught > 1) { - @object = new StardewValley.Object(whichFish, 1, false, -1); - if (whichFish == GameLocation.CAROLINES_NECKLACE_ITEM_QID) - { - @object.questItem.Value = true; - } - if (whichFish == "79" || whichFish == "842") - { - @object = who.currentLocation.tryToCreateUnseenSecretNote(who); - if (@object == null) return; - } - if (rod.numberOfFishCaught > 1) - { - @object.Stack = 2; - } - break; + @object.Stack = rod.numberOfFishCaught; } + + break; + } + default: + { + Logger.Log($"How did we get here?!?! Unhandled case in CollectFish! ItemCategory: {itemCategory}"); + break; + } } + bool fromFishPond = rod.fromFishPond; who.completelyStopAnimatingOrDoingAction(); rod.doneFishing(who, !fromFishPond); - if (!Game1.isFestival() && !fromFishPond && (itemCategory == -4 && Game1.player.team.specialOrders.Count > 0)) + if (!Game1.isFestival() && !fromFishPond && (itemCategory == Object.FishCategory && Game1.player.team.specialOrders.Count > 0)) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { @@ -196,7 +176,7 @@ public static void CollectFish(Farmer who, FishingRod rod) initialStack = rod.numberOfFishCaught; } - StardewValley.Object @object = new StardewValley.Object(whichFish, initialStack, false, -1, fishQuality); + Object @object = new Object(fishID, initialStack, false, -1, fishQuality); if (Game1.player.team.specialOrders.Count > 0) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) @@ -205,15 +185,7 @@ public static void CollectFish(Farmer who, FishingRod rod) } } bool inventoryBool = who.addItemToInventoryBool(@object); - rod.animations.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", new Rectangle(64, 1920, 32, 32), 500f, 1, 0, who.Position + new Vector2(-32f, -160f), false, false, (float)(who.Tile.Y / 10000.0 + 1.0 / 1000.0), 0.0f, Color.White, 4f, 0.0f, 0.0f, 0.0f) - { - motion = new Vector2(0.0f, -0.128f), - timeBasedMotion = true, - endFunction = rod.openChestEndFunction, - extraInfoForEndBehavior = inventoryBool ? 0 : 1, - alpha = 0.0f, - alphaFade = -1f / 500f - }); + rod.openChestEndFunction(inventoryBool ? 0 : 1); } } @@ -231,7 +203,6 @@ public static void AutoFishing(BobberBar bar) float treasurePos = bar.treasurePosition; float distanceFromCatching = bar.distanceFromCatching; bool treasureCaught = bar.treasureCaught; - bool treasure = bar.treasure; float treasureAppearTimer = bar.treasureAppearTimer; float bobberBarSpeed = bar.bobberBarSpeed; float top = barPos; diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index f1e841b..02ef0ef 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -110,7 +110,7 @@ internal class Config //Fishing Probabilities public bool FishingProbabilitiesInfo { get; set; } = false; - public Point ProbBoxCoordinates { get; set; } = new Point(100, 400); + public Point ProbBoxCoordinates { get; set; } = new Point(40, 500); public bool MorePreciseProbabilities { get; set; } = true; public int TrialOfExamine { get; set; } = 10; diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index 7581be0..4844edf 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -1,17 +1,20 @@ using System; using System.Collections.Generic; +using System.Text.Json; using System.Linq; +using System.Text.RegularExpressions; using JoysOfEfficiency.Core; using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using StardewModdingAPI; using StardewValley; +using StardewValley.GameData.LocationContexts; using StardewValley.GameData.Locations; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Tools; using xTile.Dimensions; +using Game1 = StardewValley.Game1; using Object = StardewValley.Object; using Rectangle = Microsoft.Xna.Framework.Rectangle; @@ -21,7 +24,7 @@ public class FishingProbabilitiesBox { private static readonly Logger Logger = new Logger("FishingProbabilitiesInfo"); - private static Dictionary _fishingDictionary; + private static Dictionary _fishingDictionary; private static bool _isFirstTimeOfFishing = true; @@ -59,9 +62,9 @@ public static void PrintFishingInfo() DrawProbBox(_fishingDictionary); } - private static Dictionary GetFishes(GameLocation location, int bait, int waterDepth, Farmer who, int trial = 1) + private static Dictionary GetFishes(GameLocation location, int bait, int waterDepth, Farmer who, int trial = 1) { - List> dictList = new List>(); + List> dictList = new List>(); for (int i = 0; i < trial; i++) { switch (location) @@ -70,6 +73,7 @@ private static Dictionary GetFishes(GameLocation location, int bait dictList.Add(GetFishesFarm(waterDepth, who)); break; case MineShaft shaft: +// dictList.Add(GetFishes(waterDepth, who)); dictList.Add(GetFishesMine(shaft, bait, waterDepth, who)); break; case Submarine _: @@ -81,135 +85,183 @@ private static Dictionary GetFishes(GameLocation location, int bait } } - Dictionary dict = ShuffleAndAverageFishingDictionary(dictList); + Dictionary dict = ShuffleAndAverageFishingDictionary(dictList); - Dictionary dict2 = + Dictionary dict2 = dict.OrderByDescending(x => x.Value) .Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value); double sum = dict2.Sum(kv => kv.Value); if (1 - sum >= 0.0001) { - dict2.Add(168, 1 - sum); + dict2.Add("168", 1 - sum); } return dict2; } - private static Dictionary GetFishes(int waterDepth, Farmer who, string locationName = null) + private static Dictionary GetFishes(int waterDepth, Farmer who, string locationName = null) { - Dictionary dict = new Dictionary(); + Dictionary dictFish = new Dictionary(); + GameLocation currLocation = Game1.currentLocation; + Season season = Game1.GetSeasonForLocation(currLocation); - Dictionary dictionary = Game1.content.Load>("Data\\Locations"); - string key = locationName ?? Game1.currentLocation.Name; - if (key.Equals("WitchSwamp") + LocationData thisLocData = Game1.currentLocation.GetData(); + String jThisLocData = JsonSerializer.Serialize(thisLocData, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"This LocationData: {jThisLocData}"); + + Dictionary allFishData = DataLoader.Fish(Game1.content); + + string locName = locationName ?? currLocation.Name; + Logger.Info($"GetFishes: Loc: {locName} ** Season: {season}"); + + if (locName.Equals("WitchSwamp") && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") - && !Game1.player.Items.ContainsId("(O)308", 1)) + && !Game1.player.Items.ContainsId("Void Mayonnaise", 1)) { - return new Dictionary + return new Dictionary { - {308,0.25} + { "308", 0.25 } // If the Henchman is gone, and the user has no void mayo, 25% chance to fish it up }; } - try + String JSONFishes = JsonSerializer.Serialize(allFishData, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"All Fishes: {JSONFishes}"); + Dictionary dictionary = DataLoader.Locations(Game1.content); + String jDict = JsonSerializer.Serialize(dictionary, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"All Location Data: {jDict}"); + + IEnumerable possibleFish = dictionary["Default"].Fish; + if (thisLocData != null && thisLocData.Fish?.Count > 0) + { + possibleFish = possibleFish.Concat(thisLocData.Fish); + } + + + if (!(who.CurrentTool is FishingRod rod)) + { + return dictFish; + } + + Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} [bobber] {rod.bobber.X},{rod.bobber.Y} ** {currLocation.locationContextId} ** "); + LocationContextData bubba = currLocation.GetLocationContext(); + String jsonBubba = JsonSerializer.Serialize(bubba, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"GameLocationContext: {jsonBubba}"); + + currLocation.TryGetFishAreaForTile(who.Tile, out var fishAreaID, out var fishAreaData); + Logger.Info($"FishAreaID: {fishAreaID}"); + String jsonFishAreaData = JsonSerializer.Serialize(fishAreaData, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"FishAreaData: {jsonFishAreaData}"); + + possibleFish = from p in possibleFish + orderby p.Precedence, Game1.random.Next() + where (p.FishAreaId == fishAreaID || p.FishAreaId == null) && (p.Season == season || p.Season == null) + select p; + + String JSON = JsonSerializer.Serialize(possibleFish, new JsonSerializerOptions{WriteIndented = true}); + Logger.Info($"Possibru Fishu:\n{JSON}"); + + // Reference: https://stardewvalleywiki.com/Modding:Fish_data#Fish_data_and_spawn_criteria + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // "143": "Catfish/ 75/mixed/ 12/72/600 2400/spring fall winter/ rainy/689 .4 680 .1/4/.40/.1/0/true", + // "800": "Blobfish/ 75/floater/8/25/600 2600/spring summer fall winter/both/685 .35/ 3/.40/.1/0/false" + // "701": "Tilapia/ 50/mixed/ 11/30/600 1400/summer fall/ both/683 .35/ 3/.4/.2/0/false", + // "838": "Blue Discus/ 60/dart/ 2/ 9/600 2600/spring summer fall winter/both/685 .35/ 1/.25/.1/0/false", + // "162": "Lava Eel/ 90/mixed/ 32/32/600 2600/spring summer fall winter/both/684 .1/ 2/.05/.1/7/false", + + /* 0 Name + 5 startTime endTime + 6 season1 season2 ... + 7 rainy|sunny|both + 9 maxDepth + 10 spawnMultiplier + 11 depthMultiplier + 12 fishingLevel */ + + double chance = 0.0d; + foreach (SpawnFishData f in possibleFish) { - if (dictionary.ContainsKey(key)) + String id = f.Id; + Logger.Info($"Testing Fish ID: {id}"); + id = Regex.Replace(id, "\\(O\\)", ""); + Logger.Info($"Testing Fish ID: {id}"); + + // Any list item like "(O)167|(O)168|(O)169|(O)170|(O)171|(O)172" is a list of garbage. Skip it. + if (id.Contains('|')) + { + continue; + } + + // If it's not found in the allFishData, assign the chance from possibleFish instead + if (!allFishData.ContainsKey(id)) + { + Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); + dictFish.Add(id, f.Chance); + continue; + } + + Logger.Info($"Parsing through allFishData for {f.Id} now..."); + String[] fishData = allFishData[id].Split('/'); + String jFishData = JsonSerializer.Serialize(fishData, new JsonSerializerOptions{WriteIndented = true}); + Logger.Info($"\tID: {id} *** {jFishData}"); + + // If the time isn't in the fish's catch times, go on to next fish. + String[] catchTimes = fishData[5].Split(' '); + if (Game1.timeOfDay < Convert.ToInt32(catchTimes[0]) || + Game1.timeOfDay >= Convert.ToInt32(catchTimes[1])) + { + continue; + } + + // Make sure weather matches the fish pool. [Hackswell: pun intended] + if (! fishData[7].Equals("both")) { - string[] array = dictionary[key].Split('/')[4 + Utility.getSeasonNumber(Game1.currentSeason)].Split(' '); - Dictionary dictionary2 = new Dictionary(); - if (array.Length > 1) + if (fishData[7].Equals("rainy") && !Game1.isRaining) { - for (int i = 0; i < array.Length; i += 2) - { - dictionary2[array[i]] = array[i + 1]; - } + continue; } - - string[] array2 = dictionary2.Keys.ToArray(); - Dictionary dictionary3 = Game1.content.Load>("Data\\Fish"); - //Utility.Shuffle(random, array2); - foreach (string t in array2) + else if (fishData[7].Equals("sunny") && Game1.isRaining) { - bool flag2 = true; - string[] array3 = dictionary3[Convert.ToInt32(t)].Split('/'); - string[] array4 = array3[5].Split(' '); - int num2 = Convert.ToInt32(dictionary2[t]); - String fishAreaId = ""; - FishAreaData fishAreaData; - Game1.currentLocation.TryGetFishAreaForTile(who.Tile, out fishAreaId, out fishAreaData); - if (num2 == -1 || Int32.Parse(fishAreaId) == num2) - { - int num3 = 0; - while (num3 < array4.Length) - { - if (Game1.timeOfDay < Convert.ToInt32(array4[num3]) || - Game1.timeOfDay >= Convert.ToInt32(array4[num3 + 1])) - { - num3 += 2; - continue; - } - - flag2 = false; - break; - } - } - - if (!array3[7].Equals("both")) - { - if (array3[7].Equals("rainy") && !Game1.isRaining) - { - flag2 = true; - } - else if (array3[7].Equals("sunny") && Game1.isRaining) - { - flag2 = true; - } - } - - if (who.FishingLevel < Convert.ToInt32(array3[12])) - { - flag2 = true; - } - - if (flag2) - continue; - - double num4 = Convert.ToDouble(array3[10]); - double num5 = Convert.ToDouble(array3[11]) * num4; - num4 -= Math.Max(0, Convert.ToInt32(array3[9]) - waterDepth) * num5; - num4 += who.FishingLevel / 50f; - num4 = Math.Min(num4, 0.89999997615814209); - int num = Convert.ToInt32(t); - - dict.Add(num, num4); + continue; } } + + if (who.FishingLevel < Convert.ToInt32(fishData[12])) + { + continue; + } + + int maxDepth = Convert.ToInt32(fishData[9]); + double spawnMultiplier = Convert.ToDouble(fishData[10]); + double depthMultiplier = Convert.ToDouble(fishData[11]) * spawnMultiplier; + spawnMultiplier -= Math.Max(0, maxDepth - waterDepth) * depthMultiplier; + spawnMultiplier += who.FishingLevel / 50f; + chance = Math.Min(spawnMultiplier, 0.89999997615814209); + + Logger.Info($"dictFish: Adding {id} :: {chance}"); + dictFish.Add(id, chance); } - catch (KeyNotFoundException knf) - { - Logger.Log("KeyNotFoundException occured."); - Logger.Log(knf.ToString()); - } + String jDictFish = JsonSerializer.Serialize(dictFish, new JsonSerializerOptions{WriteIndented = true}); + Logger.Info($"Possible Fish:\n{jDictFish}"); - return dict; + return dictFish; } - private static Dictionary GetFishesSubmarine() + private static Dictionary GetFishesSubmarine() { - return new Dictionary + return new Dictionary { - { 800, 0.1 }, - { 799, 0.18 }, - { 798, 0.28 }, - { 154, 0.1 }, - { 155, 0.08 }, - { 149, 0.05 }, - { 797, 0.01 } + { "800", 0.1 }, + { "799", 0.18 }, + { "798", 0.28 }, + { "154", 0.1 }, + { "155", 0.08 }, + { "149", 0.05 }, + { "797", 0.01 } }; } - private static Dictionary GetFishesMine(MineShaft shaft, int bait, int waterDepth, Farmer who) + private static Dictionary GetFishesMine(MineShaft shaft, int bait, int waterDepth, Farmer who) { - Dictionary dict = new Dictionary(); + Dictionary dict = new Dictionary(); double num2 = 1.0; num2 += 0.4 * who.FishingLevel; num2 += waterDepth * 0.1; @@ -221,17 +273,17 @@ private static Dictionary GetFishesMine(MineShaft shaft, int bait, case 10: num2 += bait == 689 ? 3 : 0; p = 0.02 + 0.01 * num2; - dict.Add(158, p); + dict.Add("158", p); // Stonefish break; case 40: num2 += bait == 682 ? 3 : 0; p = 0.015 + 0.009 * num2; - dict.Add(161, p); + dict.Add("161", p); // Ice Pip break; case 80: num2 += bait == 684 ? 3 : 0; p = 0.01 + 0.008 * num2; - dict.Add(162, p); + dict.Add("162", p); // Lava Eel break; default: return dict; @@ -249,7 +301,7 @@ private static Dictionary GetFishesMine(MineShaft shaft, int bait, return dict; } - private static Dictionary GetFishesFarm(int waterDepth, Farmer who) + private static Dictionary GetFishesFarm(int waterDepth, Farmer who) { switch (Game1.whichFarm) { @@ -261,7 +313,7 @@ private static Dictionary GetFishesFarm(int waterDepth, Farmer who) { double p = 0.05 + Game1.player.DailyLuck; return ConcatDictionary( - new Dictionary { { 734, p } }, + new Dictionary { { "734", p } }, MagnifyProbabilities( GetFishes(waterDepth, who, "Forest"), (1 - p) * 0.45) @@ -278,11 +330,11 @@ private static Dictionary GetFishesFarm(int waterDepth, Farmer who) } } - private static Dictionary GetFinalProbabilities(Dictionary dict) + private static Dictionary GetFinalProbabilities(Dictionary dict) { - Dictionary result = new Dictionary(); + Dictionary result = new Dictionary(); double ratio = 1.0; - foreach (KeyValuePair kv in dict) + foreach (KeyValuePair kv in dict) { result.Add(kv.Key, kv.Value * ratio); ratio *= (1 - kv.Value); @@ -291,41 +343,48 @@ private static Dictionary GetFinalProbabilities(Dictionary= 167 && index <= 172) - { - return true; - } - switch (index) + try { - case 152: - case 153: - case 157: return true; + int index = int.Parse(item); + if (index is >= 167 and <= 172) + { + return true; + } + switch (index) + { + case 152: + case 153: + case 157: + return true; + } } + catch { } + return false; } - private static Dictionary ShuffleAndAverageFishingDictionary(IEnumerable> list) + private static Dictionary ShuffleAndAverageFishingDictionary(IEnumerable> list) { - List> dicts = list.Select(dict => GetFinalProbabilities(ShuffleDictionary(dict))).ToList(); + List> dicts = list.Select(dict => GetFinalProbabilities(ShuffleDictionary(dict))).ToList(); return AverageDictionary(dicts); } - private static Dictionary ShuffleDictionary(Dictionary dict) + private static Dictionary ShuffleDictionary(Dictionary dict) { - KeyValuePair[] pairs = dict.ToArray(); + KeyValuePair[] pairs = dict.ToArray(); Utility.Shuffle(Game1.random, pairs); return pairs.ToDictionary(x => x.Key, x => x.Value); } - private static Dictionary AverageDictionary(List> list) + private static Dictionary AverageDictionary(List> list) { - Dictionary sum = new Dictionary(); - foreach (Dictionary elem in list) + Dictionary sum = new Dictionary(); + foreach (Dictionary elem in list) { - foreach (KeyValuePair pair in elem) + foreach (KeyValuePair pair in elem) { if (sum.ContainsKey(pair.Key)) { @@ -341,7 +400,7 @@ private static Dictionary AverageDictionary(List MagnifyProbabilities(Dictionary dict, double ratio) + private static Dictionary MagnifyProbabilities(Dictionary dict, double ratio) { return dict.ToDictionary(kv => kv.Key, kv => kv.Value * ratio); } @@ -358,22 +417,37 @@ private static Dictionary ConcatDictionary(IDictionary a return dict; } - private static void DrawProbBox(Dictionary probabilities) + private static void DrawProbBox(Dictionary probabilities) { + Rectangle window = Game1.game1.Window.ClientBounds; SpriteBatch b = Game1.spriteBatch; Size size = GetProbBoxSize(probabilities); - IClickableMenu.drawTextureBox(Game1.spriteBatch, InstanceHolder.Config.ProbBoxCoordinates.X, InstanceHolder.Config.ProbBoxCoordinates.Y, size.Width, size.Height, Color.White); + + int yOffset = InstanceHolder.Config.ProbBoxCoordinates.Y; + if (size.Height > window.Height - yOffset) + { + yOffset = window.Height - size.Height; + if (yOffset < 0) + yOffset = 0; + } + + IClickableMenu.drawTextureBox(Game1.spriteBatch, + InstanceHolder.Config.ProbBoxCoordinates.X, + yOffset, + size.Width, size.Height, Color.White); const int square = (int)(Game1.tileSize / 1.5); int x = InstanceHolder.Config.ProbBoxCoordinates.X + 8; - int y = InstanceHolder.Config.ProbBoxCoordinates.Y + 16; - SpriteFont font = Game1.dialogueFont; + int y = yOffset + 16; + SpriteFont font = Game1.smallFont; { - foreach (KeyValuePair kv in probabilities) + foreach (KeyValuePair kv in probabilities) { - string text = $"{kv.Value * 100:f1}%"; - Object fish = new Object(""+kv.Key, 1); + if (kv.Key.Contains("SECRET_NOTE")) + continue; - fish.drawInMenu(b, new Vector2(x + 8, y), 1.0f); + string text = $"{kv.Value * 100:f1}%"; + Object fish = new Object(kv.Key, 1); + fish.drawInMenu(b, new Vector2(x + 8, y), 0.70f); Utility.drawTextWithShadow(b, text, font, new Vector2(x + 32 + square, y + 16), Color.Black); y += square + 16; @@ -381,14 +455,16 @@ private static void DrawProbBox(Dictionary probabilities) } } - private static Size GetProbBoxSize(Dictionary probabilities) + private static Size GetProbBoxSize(Dictionary probabilities) { int width = 16, height = 48; int square = (int)(Game1.tileSize / 1.5); - SpriteFont font = Game1.dialogueFont; + SpriteFont font = Game1.smallFont; { - foreach (KeyValuePair kv in probabilities) + foreach (KeyValuePair kv in probabilities) { + if (kv.Key.Contains("SECRET_NOTE")) + continue; string text = $"{kv.Value * 100:f1}%"; Vector2 textSize = font.MeasureString(text); int w = square + (int)textSize.X + 64; diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 3f6c620..62b4ce3 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -2,9 +2,9 @@ "Author": "punyo", "Description": "Adds many useful functions to make gameplay more efficient", "EntryDll": "JoysOfEfficiency.dll", - "MinimumApiVersion": "3.9", + "MinimumApiVersion": "4.0", "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.5.0-unofficial.1-Hackswell" + "Version": "1.5.0-unofficial.3-Hackswell" } diff --git a/testplan.txt b/testplan.txt index d4248e2..64953c5 100644 --- a/testplan.txt +++ b/testplan.txt @@ -41,24 +41,26 @@ +[Shipping Estimator] +O[Fishing] + OFishing Probabilities Box [O Farm, +Mines, O Submarine, O Witch's Swamp, +EverywhereElse] + +Fish Info HUD + Autofisher + Auto-reeling + AFK + Treasure *** UNTESTED *** ---------------- -[Inventory Automation] -- UNTESTED - Treasure Auto-grab + +[Idle Pause] -- UNTESTED [Food Automation] -- UNTESTED Auto eat -[Fishing] -- UNTESTED - Fishing Probabilities Box - Fish Info HUD - Autofisher - AFK - Auto Reel Rod +[Inventory Automation] -- UNTESTED + Treasure Auto-grab [Flower Color Unifier] -- UNTESTED Unify Flower Colors [Mail Automation] -- UNTESTED - -[Idle Pause] -- UNTESTED From bd9c2cc1394c81de50243f225004175bb0c63d9d Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Sat, 6 Apr 2024 22:47:57 -0700 Subject: [PATCH 10/29] Fixed fishing probabilities to account for duplicate entries, non-catchable fish, furniture and non-standard IDs --- .../Huds/FishingProbabilitiesBox.cs | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index 4844edf..6729816 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -106,12 +106,12 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, LocationData thisLocData = Game1.currentLocation.GetData(); String jThisLocData = JsonSerializer.Serialize(thisLocData, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"This LocationData: {jThisLocData}"); + //Logger.Info($"This LocationData: {jThisLocData}"); Dictionary allFishData = DataLoader.Fish(Game1.content); string locName = locationName ?? currLocation.Name; - Logger.Info($"GetFishes: Loc: {locName} ** Season: {season}"); + //Logger.Info($"GetFishes: Loc: {locName} ** Season: {season}"); if (locName.Equals("WitchSwamp") && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") @@ -124,10 +124,10 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, } String JSONFishes = JsonSerializer.Serialize(allFishData, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"All Fishes: {JSONFishes}"); + //Logger.Info($"All Fishes: {JSONFishes}"); Dictionary dictionary = DataLoader.Locations(Game1.content); String jDict = JsonSerializer.Serialize(dictionary, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"All Location Data: {jDict}"); + //Logger.Info($"All Location Data: {jDict}"); IEnumerable possibleFish = dictionary["Default"].Fish; if (thisLocData != null && thisLocData.Fish?.Count > 0) @@ -141,15 +141,15 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, return dictFish; } - Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} [bobber] {rod.bobber.X},{rod.bobber.Y} ** {currLocation.locationContextId} ** "); + //Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} [bobber] {rod.bobber.X},{rod.bobber.Y} ** {currLocation.locationContextId} ** "); LocationContextData bubba = currLocation.GetLocationContext(); String jsonBubba = JsonSerializer.Serialize(bubba, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"GameLocationContext: {jsonBubba}"); + //Logger.Info($"GameLocationContext: {jsonBubba}"); currLocation.TryGetFishAreaForTile(who.Tile, out var fishAreaID, out var fishAreaData); - Logger.Info($"FishAreaID: {fishAreaID}"); + //Logger.Info($"FishAreaID: {fishAreaID}"); String jsonFishAreaData = JsonSerializer.Serialize(fishAreaData, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"FishAreaData: {jsonFishAreaData}"); + //Logger.Info($"FishAreaData: {jsonFishAreaData}"); possibleFish = from p in possibleFish orderby p.Precedence, Game1.random.Next() @@ -157,7 +157,7 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, select p; String JSON = JsonSerializer.Serialize(possibleFish, new JsonSerializerOptions{WriteIndented = true}); - Logger.Info($"Possibru Fishu:\n{JSON}"); + //Logger.Info($"Possibru Fishu:\n{JSON}"); // Reference: https://stardewvalleywiki.com/Modding:Fish_data#Fish_data_and_spawn_criteria // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 @@ -179,13 +179,21 @@ 12 fishingLevel */ double chance = 0.0d; foreach (SpawnFishData f in possibleFish) { - String id = f.Id; - Logger.Info($"Testing Fish ID: {id}"); + // Use ItemId unless its null. Account for mods with non-standard IDs for vanilla records + String id = f.ItemId; + if (id == null) { id = f.Id; } id = Regex.Replace(id, "\\(O\\)", ""); - Logger.Info($"Testing Fish ID: {id}"); + //Logger.Info($"Testing Fish ID: {id}"); - // Any list item like "(O)167|(O)168|(O)169|(O)170|(O)171|(O)172" is a list of garbage. Skip it. + // Any list item like "(O)167|(O)168|(O)169|(O)170|(O)171|(O)172" is a list of garbage. Handle it. if (id.Contains('|')) + { + dictFish["168"] = f.Chance; + continue; + } + + // Furniture, wrong conditions or the item doesnt exist. Skip it + if (id.Contains("(F)") || !GameStateQuery.CheckConditions(f.Condition) || !ItemRegistry.Exists(id)) { continue; } @@ -193,15 +201,15 @@ 12 fishingLevel */ // If it's not found in the allFishData, assign the chance from possibleFish instead if (!allFishData.ContainsKey(id)) { - Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); - dictFish.Add(id, f.Chance); + //Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); + dictFish[id] = f.Chance; continue; } - Logger.Info($"Parsing through allFishData for {f.Id} now..."); + //Logger.Info($"Parsing through allFishData for {f.Id} now..."); String[] fishData = allFishData[id].Split('/'); String jFishData = JsonSerializer.Serialize(fishData, new JsonSerializerOptions{WriteIndented = true}); - Logger.Info($"\tID: {id} *** {jFishData}"); + //Logger.Info($"\tID: {id} *** {jFishData}"); // If the time isn't in the fish's catch times, go on to next fish. String[] catchTimes = fishData[5].Split(' '); @@ -236,11 +244,11 @@ 12 fishingLevel */ spawnMultiplier += who.FishingLevel / 50f; chance = Math.Min(spawnMultiplier, 0.89999997615814209); - Logger.Info($"dictFish: Adding {id} :: {chance}"); - dictFish.Add(id, chance); + //Logger.Info($"dictFish: Adding {id} :: {chance}"); + dictFish[id] = chance; } String jDictFish = JsonSerializer.Serialize(dictFish, new JsonSerializerOptions{WriteIndented = true}); - Logger.Info($"Possible Fish:\n{jDictFish}"); + //Logger.Info($"Possible Fish:\n{jDictFish}"); return dictFish; } From 756f61f8e744c7dd88221fb3bb932baf8c028bfa Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:22:04 -0700 Subject: [PATCH 11/29] Updated probability code, accounted for Magic Bait, expanded probability window and bait/bobber display --- JoysOfEfficiency/Core/Config.cs | 4 + .../EventHandler/GraphicsEvents.cs | 2 +- .../Huds/FishingProbabilitiesBox.cs | 405 +++++++++++------- JoysOfEfficiency/Menus/JoeMenu.cs | 13 + JoysOfEfficiency/i18n/de.json | 4 + JoysOfEfficiency/i18n/default.json | 9 +- JoysOfEfficiency/i18n/es.json | 4 + JoysOfEfficiency/i18n/ja.json | 4 + JoysOfEfficiency/i18n/ko.json | 8 +- JoysOfEfficiency/i18n/pt.json | 4 + JoysOfEfficiency/i18n/ru.json | 16 +- JoysOfEfficiency/i18n/zh.json | 14 +- 12 files changed, 327 insertions(+), 160 deletions(-) diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index 02ef0ef..fbcc3e4 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -38,6 +38,9 @@ internal class Config public SButton ToggleAfkFishing { get; set; } = SButton.End; public bool FishingInfo { get; set; } = true; + public bool FishingTackleInfo { get; set; } = false; + public bool TackleBoxAttach { get; set; } = false; + public Point TackleBoxCoordinates { get; set; } = new Point(40, 500); public bool AutoGate { get; set; } = true; @@ -110,6 +113,7 @@ internal class Config //Fishing Probabilities public bool FishingProbabilitiesInfo { get; set; } = false; + public int ProbBoxMaxFish { get; set; } = 10; public Point ProbBoxCoordinates { get; set; } = new Point(40, 500); public bool MorePreciseProbabilities { get; set; } = true; public int TrialOfExamine { get; set; } = 10; diff --git a/JoysOfEfficiency/EventHandler/GraphicsEvents.cs b/JoysOfEfficiency/EventHandler/GraphicsEvents.cs index 0548098..886b812 100644 --- a/JoysOfEfficiency/EventHandler/GraphicsEvents.cs +++ b/JoysOfEfficiency/EventHandler/GraphicsEvents.cs @@ -24,7 +24,7 @@ public void OnRenderHud(object sender, RenderingHudEventArgs args) { GiftInformationTooltip.DrawTooltip(); } - if (Conf.FishingProbabilitiesInfo && Game1.player.CurrentTool is FishingRod rod && rod.isFishing) + if (Game1.player.CurrentTool is FishingRod rod && rod.isFishing) { FishingProbabilitiesBox.PrintFishingInfo(); } diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index 6729816..a8766fa 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -17,6 +17,11 @@ using Game1 = StardewValley.Game1; using Object = StardewValley.Object; using Rectangle = Microsoft.Xna.Framework.Rectangle; +using System.Net.Mail; +using static System.Net.Mime.MediaTypeNames; +using System.Xml; +using StardewValley.Buildings; +using Microsoft.VisualBasic; namespace JoysOfEfficiency.Huds { @@ -25,6 +30,7 @@ public class FishingProbabilitiesBox private static readonly Logger Logger = new Logger("FishingProbabilitiesInfo"); private static Dictionary _fishingDictionary; + private static Dictionary _attachmentDictionary; private static bool _isFirstTimeOfFishing = true; @@ -34,35 +40,65 @@ public static void UpdateProbabilities(FishingRod rod) { if (_isFirstTimeOfFishing) { - + // Only run the probablies once when line is cast _isFirstTimeOfFishing = false; - GameLocation location = Game1.currentLocation; + // Get water depth + GameLocation location = Game1.currentLocation; Rectangle rectangle = new Rectangle(location.fishSplashPoint.X * 64, location.fishSplashPoint.Y * 64, 64, 64); Rectangle value = new Rectangle((int)rod.bobber.X - 80, (int)rod.bobber.Y - 80, 64, 64); bool flag = rectangle.Intersects(value); int clearWaterDistance = rod.clearWaterDistance; - _fishingDictionary = GetFishes(location, rod.attachments[0]?.ParentSheetIndex ?? -1, clearWaterDistance + (flag ? 1 : 0), Game1.player, InstanceHolder.Config.MorePreciseProbabilities ? InstanceHolder.Config.TrialOfExamine : 1); + // Populate dictionaries + _fishingDictionary = GetFishes(location, rod.HasMagicBait() ,rod.attachments[0]?.ParentSheetIndex ?? -1, clearWaterDistance + (flag ? 1 : 0), Game1.player, InstanceHolder.Config.MorePreciseProbabilities ? InstanceHolder.Config.TrialOfExamine : 1); + _attachmentDictionary = GetAttachments(rod); } } else { _isFirstTimeOfFishing = true; _fishingDictionary = null; + _attachmentDictionary = null; } } public static void PrintFishingInfo() { - if (_fishingDictionary == null) + int x_pos_add = 0; + if (InstanceHolder.Config.FishingProbabilitiesInfo && _fishingDictionary != null) + x_pos_add = DrawProbBox(_fishingDictionary); + + if (InstanceHolder.Config.FishingTackleInfo && _attachmentDictionary != null && _attachmentDictionary.Count > 0) + DrawTackleBox(_attachmentDictionary, x_pos_add); + + } + + private static Dictionary GetAttachments(FishingRod rod) + { + Dictionary dictList = new Dictionary(); + + // If no attachments, return null set + if (rod.attachments.Count == 0) return null; + + // Loop through attachments + for (int i = 0; i < rod.attachments.Count; i++) { - return; + int rodIndex = rod.attachments[i]?.ParentSheetIndex ?? -1; + if (rodIndex > -1) + { + // Bait vs Tackle + if (i == 0) + dictList[rod.attachments[i].QualifiedItemId] = rod.attachments[i].Stack; + else + dictList[rod.attachments[i].QualifiedItemId] = FishingRod.maxTackleUses - rod.attachments[i].uses.Value; + } } - DrawProbBox(_fishingDictionary); + + return dictList; } - private static Dictionary GetFishes(GameLocation location, int bait, int waterDepth, Farmer who, int trial = 1) + private static Dictionary GetFishes(GameLocation location, bool magicBait, int bait, int waterDepth, Farmer who, int trial = 1) { List> dictList = new List>(); for (int i = 0; i < trial; i++) @@ -70,95 +106,94 @@ private static Dictionary GetFishes(GameLocation location, int b switch (location) { case Farm _: - dictList.Add(GetFishesFarm(waterDepth, who)); + dictList.Add(GetFishesFarm(waterDepth, who, magicBait)); break; case MineShaft shaft: -// dictList.Add(GetFishes(waterDepth, who)); - dictList.Add(GetFishesMine(shaft, bait, waterDepth, who)); + dictList.Add(GetFishesMine(shaft, magicBait, bait, waterDepth, who)); break; case Submarine _: dictList.Add(GetFishesSubmarine()); break; default: - dictList.Add(GetFishes(waterDepth, who)); + dictList.Add(GetFishesGeneric(waterDepth, who, magicBait)); break; } } Dictionary dict = ShuffleAndAverageFishingDictionary(dictList); - - Dictionary dict2 = - dict.OrderByDescending(x => x.Value) - .Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value); + Dictionary dict2 = dict.OrderByDescending(x => x.Value).Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value); double sum = dict2.Sum(kv => kv.Value); if (1 - sum >= 0.0001) - { dict2.Add("168", 1 - sum); - } + return dict2; } - private static Dictionary GetFishes(int waterDepth, Farmer who, string locationName = null) + private static Dictionary GetFishesGeneric(int waterDepth, Farmer who, bool magicBait, string locationName = null) { Dictionary dictFish = new Dictionary(); GameLocation currLocation = Game1.currentLocation; Season season = Game1.GetSeasonForLocation(currLocation); - LocationData thisLocData = Game1.currentLocation.GetData(); - String jThisLocData = JsonSerializer.Serialize(thisLocData, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"This LocationData: {jThisLocData}"); - + // Load all Fish and Locations Dictionary allFishData = DataLoader.Fish(Game1.content); + Dictionary dictionary = DataLoader.Locations(Game1.content); + // Get Location Data + LocationData thisLocData = Game1.currentLocation.GetData(); string locName = locationName ?? currLocation.Name; - //Logger.Info($"GetFishes: Loc: {locName} ** Season: {season}"); + if (Game1.debugMode) Logger.Info($"GetFishes: Loc: {locName} ** Season: {season}"); - if (locName.Equals("WitchSwamp") - && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") - && !Game1.player.Items.ContainsId("Void Mayonnaise", 1)) + // If the Henchman is gone, and the user has no void mayo, 25% chance to fish it up + if (locName.Equals("WitchSwamp") && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") && !Game1.player.Items.ContainsId("Void Mayonnaise", 1)) + return new Dictionary { { "308", 0.25 } }; + + // Show all available fishes + if (Game1.debugMode) { - return new Dictionary - { - { "308", 0.25 } // If the Henchman is gone, and the user has no void mayo, 25% chance to fish it up - }; + String JSONFishes = JsonSerializer.Serialize(allFishData, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"All Fishes: {JSONFishes}"); } - - String JSONFishes = JsonSerializer.Serialize(allFishData, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"All Fishes: {JSONFishes}"); - Dictionary dictionary = DataLoader.Locations(Game1.content); - String jDict = JsonSerializer.Serialize(dictionary, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"All Location Data: {jDict}"); - + + // Get all possible fish in the area IEnumerable possibleFish = dictionary["Default"].Fish; if (thisLocData != null && thisLocData.Fish?.Count > 0) - { possibleFish = possibleFish.Concat(thisLocData.Fish); - } - - if (!(who.CurrentTool is FishingRod rod)) - { - return dictFish; + // Debug Location Data + if (Game1.debugMode) { + Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} ** {currLocation.locationContextId} ** "); + LocationContextData bubba = currLocation.GetLocationContext(); + String jsonBubba = JsonSerializer.Serialize(bubba, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"GameLocationContext: {jsonBubba}"); } - //Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} [bobber] {rod.bobber.X},{rod.bobber.Y} ** {currLocation.locationContextId} ** "); - LocationContextData bubba = currLocation.GetLocationContext(); - String jsonBubba = JsonSerializer.Serialize(bubba, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"GameLocationContext: {jsonBubba}"); - + // Get all fish for the current location currLocation.TryGetFishAreaForTile(who.Tile, out var fishAreaID, out var fishAreaData); - //Logger.Info($"FishAreaID: {fishAreaID}"); - String jsonFishAreaData = JsonSerializer.Serialize(fishAreaData, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"FishAreaData: {jsonFishAreaData}"); - - possibleFish = from p in possibleFish - orderby p.Precedence, Game1.random.Next() - where (p.FishAreaId == fishAreaID || p.FishAreaId == null) && (p.Season == season || p.Season == null) - select p; + if (Game1.debugMode) + { + String jsonFishAreaData = JsonSerializer.Serialize(fishAreaData, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"FishAreaData: {jsonFishAreaData}"); + } - String JSON = JsonSerializer.Serialize(possibleFish, new JsonSerializerOptions{WriteIndented = true}); - //Logger.Info($"Possibru Fishu:\n{JSON}"); + // If we are using magic bait, include all seasons + if (magicBait) + possibleFish = from p in possibleFish + orderby p.Precedence, Game1.random.Next() + where (p.FishAreaId == fishAreaID || p.FishAreaId == null) + select p; + else + possibleFish = from p in possibleFish + orderby p.Precedence, Game1.random.Next() + where (p.FishAreaId == fishAreaID || p.FishAreaId == null) && (p.Season == season || p.Season == null) + select p; + // Show all possible fish + if (Game1.debugMode) + { + String JSON = JsonSerializer.Serialize(possibleFish, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"Possibru Fishu:\n{JSON}"); + } // Reference: https://stardewvalleywiki.com/Modding:Fish_data#Fish_data_and_spawn_criteria // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 // "143": "Catfish/ 75/mixed/ 12/72/600 2400/spring fall winter/ rainy/689 .4 680 .1/4/.40/.1/0/true", @@ -180,63 +215,60 @@ 12 fishingLevel */ foreach (SpawnFishData f in possibleFish) { // Use ItemId unless its null. Account for mods with non-standard IDs for vanilla records - String id = f.ItemId; - if (id == null) { id = f.Id; } + String id = f.ItemId ?? f.Id; + String qualifiedID = id; id = Regex.Replace(id, "\\(O\\)", ""); - //Logger.Info($"Testing Fish ID: {id}"); - // Any list item like "(O)167|(O)168|(O)169|(O)170|(O)171|(O)172" is a list of garbage. Handle it. - if (id.Contains('|')) - { - dictFish["168"] = f.Chance; - continue; - } + // Debug + if (Game1.debugMode) Logger.Info($"Testing Fish ID: {id}"); + + // Skip Garbage, Furniture and items that dont exist + if (id.Contains('|') || id.Contains("(F)") || !ItemRegistry.Exists(id)) continue; - // Furniture, wrong conditions or the item doesnt exist. Skip it - if (id.Contains("(F)") || !GameStateQuery.CheckConditions(f.Condition) || !ItemRegistry.Exists(id)) + // Remove season check when using magic bait + String newCondition = f.Condition; + if (magicBait && f.Condition != null) { - continue; - } + List conditions = f.Condition.Split(',').ToList(); + conditions.RemoveAll(u => u.ToUpper().Contains("LOCATION_SEASON")); + newCondition = String.Join(",", conditions); + } + if (!GameStateQuery.CheckConditions(newCondition)) continue; // If it's not found in the allFishData, assign the chance from possibleFish instead if (!allFishData.ContainsKey(id)) { - //Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); - dictFish[id] = f.Chance; + if (Game1.debugMode) Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); + dictFish[qualifiedID] = f.Chance; continue; } - - //Logger.Info($"Parsing through allFishData for {f.Id} now..."); + + // Get the data for the fish String[] fishData = allFishData[id].Split('/'); - String jFishData = JsonSerializer.Serialize(fishData, new JsonSerializerOptions{WriteIndented = true}); - //Logger.Info($"\tID: {id} *** {jFishData}"); - // If the time isn't in the fish's catch times, go on to next fish. - String[] catchTimes = fishData[5].Split(' '); - if (Game1.timeOfDay < Convert.ToInt32(catchTimes[0]) || - Game1.timeOfDay >= Convert.ToInt32(catchTimes[1])) + // Debug code for fish data + if (Game1.debugMode) { - continue; + Logger.Info($"Parsing through allFishData for {f.Id} now..."); + String jFishData = JsonSerializer.Serialize(fishData, new JsonSerializerOptions{WriteIndented = true}); + Logger.Info($"\tID: {id} *** {jFishData}"); } + // Check the time window of the fish + String[] catchTimes = fishData[5].Split(' '); + if (!magicBait && (Game1.timeOfDay < Convert.ToInt32(catchTimes[0]) || Game1.timeOfDay >= Convert.ToInt32(catchTimes[1]))) continue; + // Make sure weather matches the fish pool. [Hackswell: pun intended] - if (! fishData[7].Equals("both")) + if (!fishData[7].Equals("both") && !magicBait) { - if (fishData[7].Equals("rainy") && !Game1.isRaining) - { - continue; - } - else if (fishData[7].Equals("sunny") && Game1.isRaining) - { - continue; - } + if (fishData[7].Equals("rainy") && !Game1.isRaining) continue; + else if (fishData[7].Equals("sunny") && Game1.isRaining) continue; } - if (who.FishingLevel < Convert.ToInt32(fishData[12])) - { - continue; - } + // Below the required level + if (who.FishingLevel < Convert.ToInt32(fishData[12])) continue; + // Calculate chance int maxDepth = Convert.ToInt32(fishData[9]); double spawnMultiplier = Convert.ToDouble(fishData[10]); double depthMultiplier = Convert.ToDouble(fishData[11]) * spawnMultiplier; @@ -244,12 +276,16 @@ 12 fishingLevel */ spawnMultiplier += who.FishingLevel / 50f; chance = Math.Min(spawnMultiplier, 0.89999997615814209); - //Logger.Info($"dictFish: Adding {id} :: {chance}"); - dictFish[id] = chance; + if (Game1.debugMode) Logger.Info($"dictFish: Adding {id} :: {chance}"); + dictFish[qualifiedID] = chance; } - String jDictFish = JsonSerializer.Serialize(dictFish, new JsonSerializerOptions{WriteIndented = true}); - //Logger.Info($"Possible Fish:\n{jDictFish}"); + // Return fish list + if (Game1.debugMode) + { + String jDictFish = JsonSerializer.Serialize(dictFish, new JsonSerializerOptions { WriteIndented = true }); + Logger.Info($"Possible Fish:\n{jDictFish}"); + } return dictFish; } @@ -267,7 +303,7 @@ private static Dictionary GetFishesSubmarine() }; } - private static Dictionary GetFishesMine(MineShaft shaft, int bait, int waterDepth, Farmer who) + private static Dictionary GetFishesMine(MineShaft shaft, bool magicBait, int bait, int waterDepth, Farmer who) { Dictionary dict = new Dictionary(); double num2 = 1.0; @@ -275,6 +311,8 @@ private static Dictionary GetFishesMine(MineShaft shaft, int bai num2 += waterDepth * 0.1; double p; int level = shaft.getMineArea(); + + // Add fish based on mine level switch (level) { case 0: @@ -298,43 +336,37 @@ private static Dictionary GetFishesMine(MineShaft shaft, int bai } if (level == 10 || level == 40) - { - return ConcatDictionary(dict, - MagnifyProbabilities( - GetFishes(waterDepth, who, "UndergroundMine") - .Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value), - 1 - p)); - } + return ConcatDictionary(dict,MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "UndergroundMine").Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value),1 - p)); return dict; } - private static Dictionary GetFishesFarm(int waterDepth, Farmer who) + private static Dictionary GetFishesFarm(int waterDepth, Farmer who, bool magicBait) { switch (Game1.whichFarm) { case 1: - return ConcatDictionary(MagnifyProbabilities(GetFishes(waterDepth, who, "Forest"), 0.3), MagnifyProbabilities(GetFishes(waterDepth, who, "Town"), 0.7)); + return ConcatDictionary(MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "Forest"), 0.3), MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "Town"), 0.7)); case 3: - return MagnifyProbabilities(GetFishes(waterDepth, who, "Forest"), 0.5); + return MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "Forest"), 0.5); case 2: { double p = 0.05 + Game1.player.DailyLuck; return ConcatDictionary( new Dictionary { { "734", p } }, MagnifyProbabilities( - GetFishes(waterDepth, who, "Forest"), + GetFishesGeneric(waterDepth, who, magicBait, "Forest"), (1 - p) * 0.45) ); } case 4: { return MagnifyProbabilities( - GetFishes(waterDepth, who, "Mountain"), + GetFishesGeneric(waterDepth, who, magicBait, "Mountain"), 0.35); } default: - return GetFishes(waterDepth, who); + return GetFishesGeneric(waterDepth, who, magicBait); } } @@ -355,11 +387,9 @@ private static bool IsGarbage(String item) { try { - int index = int.Parse(item); - if (index is >= 167 and <= 172) - { - return true; - } + // Account for qualified item names + int index = int.Parse(Regex.Replace(item, "\\(O\\)", "")); + if (index is >= 167 and <= 172) return true; switch (index) { case 152: @@ -425,7 +455,7 @@ private static Dictionary ConcatDictionary(IDictionary a return dict; } - private static void DrawProbBox(Dictionary probabilities) + private static int DrawProbBox(Dictionary probabilities) { Rectangle window = Game1.game1.Window.ClientBounds; SpriteBatch b = Game1.spriteBatch; @@ -439,49 +469,136 @@ private static void DrawProbBox(Dictionary probabilities) yOffset = 0; } - IClickableMenu.drawTextureBox(Game1.spriteBatch, - InstanceHolder.Config.ProbBoxCoordinates.X, - yOffset, - size.Width, size.Height, Color.White); + // Draw menu without shadow + IClickableMenu.drawTextureBox(b,Game1.menuTexture,new Rectangle(0, 256, 60, 60),InstanceHolder.Config.ProbBoxCoordinates.X,yOffset,size.Width,size.Height,Color.White,1f,false,-1f); const int square = (int)(Game1.tileSize / 1.5); + int width = 16; + int x_space = 0; int x = InstanceHolder.Config.ProbBoxCoordinates.X + 8; int y = yOffset + 16; + int fishCount = 1; SpriteFont font = Game1.smallFont; + + // Draw Fish + foreach (KeyValuePair kv in probabilities) { - foreach (KeyValuePair kv in probabilities) - { - if (kv.Key.Contains("SECRET_NOTE")) - continue; + if (kv.Key.Contains("SECRET_NOTE")) continue; + string text = $"{kv.Value * 100:f1}%"; + Item fish = ItemRegistry.Create(kv.Key, 1); + fish.drawInMenu(b, new Vector2(x + 8 + x_space, y), 0.70f); + Utility.drawTextWithShadow(b, text, font, new Vector2(x + 32 + square + x_space, y + 18), Color.Black); - string text = $"{kv.Value * 100:f1}%"; - Object fish = new Object(kv.Key, 1); - fish.drawInMenu(b, new Vector2(x + 8, y), 0.70f); - Utility.drawTextWithShadow(b, text, font, new Vector2(x + 32 + square, y + 16), Color.Black); + Vector2 textSize = font.MeasureString(text); + int w = square + (int)textSize.X + 64 + x_space; + if (w > width) width = w; + + // Move cursor based on number of fish + if (fishCount % InstanceHolder.Config.ProbBoxMaxFish == 0) + { + x_space = 8 + w; + y = yOffset + 16; + } + else y += square + 16; - } + + // Track Count + fishCount++; } + + return size.Width; } private static Size GetProbBoxSize(Dictionary probabilities) { int width = 16, height = 48; int square = (int)(Game1.tileSize / 1.5); + int fishCount = 1; + int x_space = 0; + bool y_max = false; SpriteFont font = Game1.smallFont; + foreach (KeyValuePair kv in probabilities) { - foreach (KeyValuePair kv in probabilities) - { - if (kv.Key.Contains("SECRET_NOTE")) - continue; - string text = $"{kv.Value * 100:f1}%"; - Vector2 textSize = font.MeasureString(text); - int w = square + (int)textSize.X + 64; - if (w > width) - { - width = w; - } + if (kv.Key.Contains("SECRET_NOTE")) continue; + string text = $"{kv.Value * 100:f1}%"; + Vector2 textSize = font.MeasureString(text); + int w = square + (int)textSize.X + 64 + x_space; + if (w > width) width = w; + + // Increase Height if applicable + if (!y_max) height += square + 16; - } + + // Start a new column? + if (fishCount % InstanceHolder.Config.ProbBoxMaxFish == 0) + { + x_space = 8 + w; + y_max = true; + } + + // Index + fishCount++; + } + return new Size(width, height); + } + + private static void DrawTackleBox(Dictionary attachments, int x_add) + { + Rectangle window = Game1.game1.Window.ClientBounds; + SpriteBatch b = Game1.spriteBatch; + Size size = GetTackleBoxSize(attachments); + + // Determine location based on Probability box or defined coordinates + int xOffset, yOffset; + if (InstanceHolder.Config.TackleBoxAttach) { + xOffset = InstanceHolder.Config.ProbBoxCoordinates.X + x_add; + yOffset = InstanceHolder.Config.ProbBoxCoordinates.Y; + } + else + { + xOffset = InstanceHolder.Config.TackleBoxCoordinates.X; + yOffset = InstanceHolder.Config.TackleBoxCoordinates.Y; + } + + // Set the initial yOffset + if (size.Height > window.Height - yOffset) + { + yOffset = window.Height - size.Height; + if (yOffset < 0) + yOffset = 0; + } + + //Draw Window for Bait and Bobbers + IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), xOffset, yOffset, size.Width, size.Height, Color.White, 1f, false, -1f); + const int square = (int)(Game1.tileSize / 1.5); + int x = xOffset + 8; + int y = yOffset + 16; + SpriteFont font = Game1.smallFont; + + // Add Bait and Tackle + foreach (KeyValuePair kv in attachments) + { + string text = $"{kv.Value}"; + Item tackle = ItemRegistry.Create(kv.Key, 1); + tackle.drawInMenu(b, new Vector2(x + 8, y), 0.70f); + Utility.drawTextWithShadow(b, text, font, new Vector2(x + 32 + square, y + 18), Color.Black); + + y += square + 16; + } + } + + private static Size GetTackleBoxSize(Dictionary attachments) + { + int width = 16, height = 48; + int square = (int)(Game1.tileSize / 1.5); + SpriteFont font = Game1.smallFont; + foreach (KeyValuePair kv in attachments) + { + string text = $"{kv.Value}"; + Vector2 textSize = font.MeasureString(text); + int w = square + (int)textSize.X + 64; + if (w > width) width = w; + height += square + 16; } return new Size(width, height); } diff --git a/JoysOfEfficiency/Menus/JoeMenu.cs b/JoysOfEfficiency/Menus/JoeMenu.cs index 6b9b1eb..606c869 100644 --- a/JoysOfEfficiency/Menus/JoeMenu.cs +++ b/JoysOfEfficiency/Menus/JoeMenu.cs @@ -212,10 +212,17 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Fishing Probabilities Information")); tab.AddOptionsElement(new ModifiedCheckBox("FishingProbabilitiesInfo", 26, Config.FishingProbabilitiesInfo, OnCheckboxValueChanged)); + tab.AddOptionsElement(new ModifiedSlider("ProbBoxMaxFish", 19, Config.ProbBoxMaxFish, 5, 25, OnSliderValueChanged)); tab.AddOptionsElement(new ModifiedClickListener(this, "ProbBoxLocation", 0, Config.ProbBoxCoordinates.X, Config.ProbBoxCoordinates.Y, translation, OnSomewhereClicked, OnStartListeningClick)); tab.AddOptionsElement(new ModifiedCheckBox("MorePreciseProbabilities", 37, Config.MorePreciseProbabilities, OnCheckboxValueChanged, i => !Config.FishingProbabilitiesInfo)); tab.AddOptionsElement(new ModifiedSlider("TrialOfExamine", 15, Config.TrialOfExamine, 1, 50, OnSliderValueChanged, () => !(Config.FishingProbabilitiesInfo && Config.MorePreciseProbabilities))); + tab.AddOptionsElement(new EmptyLabel()); + tab.AddOptionsElement(new LabelComponent("Fishing Tackle Information")); + tab.AddOptionsElement(new ModifiedCheckBox("FishingTackleInfo", 43, Config.FishingTackleInfo, OnCheckboxValueChanged)); + tab.AddOptionsElement(new ModifiedCheckBox("TackleBoxAttach", 44, Config.TackleBoxAttach, OnCheckboxValueChanged)); + tab.AddOptionsElement(new ModifiedClickListener(this, "TackleBoxLocation", 2, Config.TackleBoxCoordinates.X, Config.TackleBoxCoordinates.Y, translation, OnSomewhereClicked, OnStartListeningClick)); + tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Show Shipping Price")); tab.AddOptionsElement(new ModifiedCheckBox("EstimateShippingPrice", 28, Config.EstimateShippingPrice, OnCheckboxValueChanged)); @@ -296,6 +303,9 @@ private void OnSomewhereClicked(int index, Point point) case 1: Config.PriceBoxCoordinates = point; break; + case 2: + Config.TackleBoxCoordinates = point; + break; default: return; } InstanceHolder.WriteConfig(); @@ -365,6 +375,8 @@ private void OnCheckboxValueChanged(int index, bool value) case 40: Config.BreakRocks = value; break; case 41: Config.ChopTwigs = value; break; case 42: Config.AutoDepositSeedMaker = value; break; + case 43: Config.FishingTackleInfo = value; break; + case 44: Config.TackleBoxAttach = value; break; default: return; } InstanceHolder.WriteConfig(); @@ -390,6 +402,7 @@ private void OnSliderValueChanged(int index, int value) case 16: Config.RadiusFarmCleanup = value; break; case 17: Config.ThrowPower = value / 10.0f; break; case 18: Config.ThresholdStaminaPercentage = value; break; + case 19: Config.ProbBoxMaxFish = value; break; default: return; } diff --git a/JoysOfEfficiency/i18n/de.json b/JoysOfEfficiency/i18n/de.json index de21950..933dd38 100644 --- a/JoysOfEfficiency/i18n/de.json +++ b/JoysOfEfficiency/i18n/de.json @@ -45,6 +45,10 @@ "options.FishInfo": "Zeige stets die Infobox fürs Fischen", "options.FishingInfo": "Zeigt die Infobox beim Fischen", "options.FishingProbabilitiesInfo": "Zeige die Wahrscheinlichkeit der Fische", + "options.FishingTackleInfo": "Ziehen Sie aktuelle Köder und Bobber", + "options.TackleBoxAttach": "Befestigen Sie die Angelbox an der Fischwahrscheinlichkeitsbox", + "options.TackleBoxLocation": "Koordinaten oben links für das Informationsfeld", + "options.ProbBoxMaxFish": "Anzahl der Fische pro Spalte", "options.GiftInformation": "Zeige den Tooltip für Geschenke", "options.HealthToEatRatio": "Automatisches Essen, um Gesundheit aufzufüllent", "options.IdleTimeout": "Leerlauf-Timeout für das Pausieren des Spiels", diff --git a/JoysOfEfficiency/i18n/default.json b/JoysOfEfficiency/i18n/default.json index 9187d76..675e946 100644 --- a/JoysOfEfficiency/i18n/default.json +++ b/JoysOfEfficiency/i18n/default.json @@ -85,15 +85,20 @@ "options.ChopTwigs": "Chop twigs (Axe)", "options.PriceBoxCoordinates": "Top-left coordinates for the information box", + "options.FishingTackleInfo": "Draw current bait and bobbers", + "options.TackleBoxAttach": "Attach the tackle box to fish probabilities box", + "options.TackleBoxLocation": "Top-left coordinates for the information box", + "options.ProbBoxMaxFish": "Number of fish per column", + "options.ThrowPower": "Bobber throwing strength", "options.ThresholdStaminaPersentage": "Stamina threshold to stop fishing", - "options.ToggleAFKFishing": "Toggle AFK Fishing mode", + "options.ToggleAFKFishing": "Toggle AFK Fishing mode", "hud.afk.passedout": "You stopped fishing because you passed out.", "hud.afk.on": "AFK Fishing enabled.", "hud.afk.off": "AFK Fishing disabled.", - "hud.afk.tired": "You stopped fishing because you felt tired.", + "hud.afk.tired": "You stopped fishing because you felt tired.", "options.flower": "Flower:{0}", "options.R": "R", diff --git a/JoysOfEfficiency/i18n/es.json b/JoysOfEfficiency/i18n/es.json index a841a7b..bf541e2 100644 --- a/JoysOfEfficiency/i18n/es.json +++ b/JoysOfEfficiency/i18n/es.json @@ -47,6 +47,10 @@ "options.FishInfo": "Dibujar información de peces", "options.FishingInfo": "Dibujar el cuadro de información de pesca", "options.FishingProbabilitiesInfo": "Dibujar probabilidades de pesca", + "options.FishingTackleInfo": "Dibujar cebos y bobbers actuales", + "options.TackleBoxAttach": "Adjunte la caja de aparejos a la caja de probabilidades de pescar.", + "options.TackleBoxLocation": "Coordenadas superior izquierda para el cuadro de información.", + "options.ProbBoxMaxFish": "Número de peces por columna", "options.GiftInformation": "Mostrar información de regalos", "options.HealthToEatRatio": "Salud para comer auto", "options.IdleTimeout": "Tiempo de espera para pausar el juego", diff --git a/JoysOfEfficiency/i18n/ja.json b/JoysOfEfficiency/i18n/ja.json index a74ca53..7768a40 100644 --- a/JoysOfEfficiency/i18n/ja.json +++ b/JoysOfEfficiency/i18n/ja.json @@ -57,6 +57,10 @@ "options.FindHoeFromInventory": "クワをインベントリから探す", "options.FishingInfo": "釣りの情報を表示", "options.FishingProbabilitiesInfo": "釣りの確率を表示", + "options.FishingTackleInfo": "現在のベイトと浮きを描く", + "options.TackleBoxAttach": "タックルボックスを魚の確率ボックスに取り付ける", + "options.TackleBoxLocation": "情報ボックスの左上の座標", + "options.ProbBoxMaxFish": "列ごとの魚の数", "options.GiftInformation": "贈り物情報を表示", "options.HealthToEatRatio": "体力しきい値", "options.IdleTimeout": "一時停止までの時間", diff --git a/JoysOfEfficiency/i18n/ko.json b/JoysOfEfficiency/i18n/ko.json index d02ec60..da70474 100644 --- a/JoysOfEfficiency/i18n/ko.json +++ b/JoysOfEfficiency/i18n/ko.json @@ -59,6 +59,10 @@ "options.FishInfo": "물고기 정보 상자 보기", "options.FishingInfo": "물고기 정보 상자 보기", "options.FishingProbabilitiesInfo": "낚시 확률 표시", + "options.FishingTackleInfo": "현재 미끼와 찌 그리기", + "options.TackleBoxAttach": "물고기 확률 상자에 태클 상자를 부착합니다.", + "options.TackleBoxLocation": "정보 상자의 왼쪽 상단 좌표", + "options.ProbBoxMaxFish": "열당 물고기 수", "options.GiftInformation": "선물 정보 표시 (선물할 것을 선택 후 NPC 위로 가져 가면 정보 표시)", "options.HealthToEatRatio": "자동 먹기 체력 최대치 값", "options.IdleTimeout": "게임 일시 정지를 위한 유휴 초과 시간", @@ -92,8 +96,8 @@ "hud.afk.passedout": "기절했기 때문에 낚시가 중단되었습니다.", "hud.afk.on": "AFK 낚시가 활성화되었습니다.", "hud.afk.off": "AFK 낚시가 비활성화되었습니다.", - "hud.afk.tired": "피곤해서 낚시가 중단되었습니다.", - + "hud.afk.tired": "피곤해서 낚시가 중단되었습니다.", + "options.flower": "꽃:{0}", "options.R": "R", "options.G": "G", diff --git a/JoysOfEfficiency/i18n/pt.json b/JoysOfEfficiency/i18n/pt.json index e9d71f4..8eb1be4 100644 --- a/JoysOfEfficiency/i18n/pt.json +++ b/JoysOfEfficiency/i18n/pt.json @@ -52,6 +52,10 @@ "options.FishInfo": "Mostrar informação dos peixes", "options.FishingInfo": "Mostrar informação de pesca", "options.FishingProbabilitiesInfo": "Mostrar probabilidades de pesca", + "options.FishingTackleInfo": "Desenhe iscas e bobbers atuais", + "options.TackleBoxAttach": "Anexe a caixa de equipamento à caixa de probabilidades de pesca", + "options.TackleBoxLocation": "Coordenadas no canto superior esquerdo da caixa de informações", + "options.ProbBoxMaxFish": "Número de peixes por coluna", "options.GiftInformation": "Mostrar dicas de informações sobre presentes", "options.HealthToEatRatio": "Limite de saúde para comer automaticamente", "options.IdleTimeout": "Tempo limite inativo para pausar o jogo", diff --git a/JoysOfEfficiency/i18n/ru.json b/JoysOfEfficiency/i18n/ru.json index de76a14..6a157c4 100644 --- a/JoysOfEfficiency/i18n/ru.json +++ b/JoysOfEfficiency/i18n/ru.json @@ -2,9 +2,9 @@ "button.awaiting": "Нажмите любую кнопку, чтобы назначить её...", "button.conflict": "Нажатая вами Кнопка уже используется", "button.esc": "Нажмите Esc для Отмены", - + "estimatedprice.title": "Примерная Стоимость", - + "fishinfo.quality": "Качество: ", "fishinfo.size": "Размер: {0}дюймов", "fishinfo.species": "Особь: {0}", @@ -12,7 +12,7 @@ "fishinfo.treasure.caught": "Сокровище поймано!", "fishinfo.treasure.incoming": "Сокровище через {0:f1}с.", "fishinfo.price": "Цена продажи:{0}G", - + "hud.paused": "Игра на паузе.", "ladder": "Лестница появилась!", @@ -20,7 +20,7 @@ "location.awaiting": "Нажмите, чтобы выбрать локацию.", "monsters.tally": "{0}: {1} убито", - + "options.AnimalHarvestRadius": "Дальность поиска животных (в тайлах)", "options.AutoAnimalDoor": "Автоматически Открывать/Закрывать Двери Животных", "options.AutoCollectCollectibles": "Автоматически собирать дикие растения поблизости", @@ -59,6 +59,10 @@ "options.FishInfo": "Показывать окошко с информацией по рыбе", "options.FishingInfo": "Показывать окошко с информацией по рыбе", "options.FishingProbabilitiesInfo": "Показывать вероятность ловли рыбы", + "options.FishingTackleInfo": "Нарисуйте текущую наживку и поплавки.", + "options.TackleBoxAttach": "Прикрепите коробку для снастей к коробке вероятности вылова рыбы.", + "options.TackleBoxLocation": "Координаты верхнего левого информационного окна", + "options.ProbBoxMaxFish": "Количество рыб в столбце", "options.GiftInformation": "Показывать Окошко с Информацией по Подаркам", "options.HealthToEatRatio": "Порог Здоровья", "options.IdleTimeout": "Длительность простоя перед паузой", @@ -89,11 +93,11 @@ "options.B": "B", "options.previewColor": "Просмотр Оттенка:", "options.register": "Учитывать", - + "flower.register": "{0} цветов будет объединяться.", "flower.unregister": "{0} цветов больше не будет объединяться.", "flower.vanilla": "Нельзя не учитывать обычные цветы.", - + "quality.gold": "Золотое", "quality.iridium": "Иридиевое", "quality.normal": "Нормальное", diff --git a/JoysOfEfficiency/i18n/zh.json b/JoysOfEfficiency/i18n/zh.json index 95b44a0..425c397 100644 --- a/JoysOfEfficiency/i18n/zh.json +++ b/JoysOfEfficiency/i18n/zh.json @@ -4,7 +4,7 @@ "button.esc": "按 Esc 取消", "estimatedprice.title": "预估价格", - + "fishinfo.quality": "品质: ", "fishinfo.size": "尺寸: {0} 厘米", "fishinfo.species": "品种: {0}", @@ -18,7 +18,7 @@ "ladder": "梯子出现了!", "location.awaiting": "单击某处以指定所需的位置。", - + "monsters.tally": "{0}:{1} 击杀", "options.AnimalHarvestRadius": "搜索动物的地图格半径", @@ -59,6 +59,10 @@ "options.FishInfo": "显示钓鱼信息", "options.FishingInfo": "显示钓鱼信息", "options.FishingProbabilitiesInfo": "显示鱼的上竿几率", + "options.FishingTackleInfo": "绘制当前的鱼饵和浮标", + "options.TackleBoxAttach": "将钓具盒连接到鱼类概率盒", + "options.TackleBoxLocation": "信息框的左上角坐标", + "options.ProbBoxMaxFish": "每列的鱼数", "options.GiftInformation": "显示礼物提示", "options.HealthToEatRatio": "自动进食阈值(生命值)", "options.IdleTimeout": "暂停游戏的空闲超时", @@ -83,16 +87,16 @@ "options.BreakRocks": "打破小石头(镐)", "options.ChopTwigs": "砍树枝(斧头)", "options.PriceBoxCoordinates": "信息框的左上角坐标", - + "options.ThrowPower": "鱼钩投掷力度", "options.ThresholdStaminaPersentage": "停止钓鱼的体力值", - "options.ToggleAFKFishing": "切换 AFK 钓鱼模式", + "options.ToggleAFKFishing": "切换 AFK 钓鱼模式", "hud.afk.passedout": "已停止钓鱼,因为你昏过去了。", "hud.afk.on": "AFK 钓鱼模式开启", "hud.afk.off": "AFK 钓鱼模式关闭", - "hud.afk.tired": "已停止钓鱼,因为你累了。", + "hud.afk.tired": "已停止钓鱼,因为你累了。", "options.flower": "花:{0}", "options.R": "R", From 711478b22ea9a29b078a30619688b403870c070d Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Fri, 12 Apr 2024 18:37:50 -0700 Subject: [PATCH 12/29] Fix AutoHarvest on Mod crops --- JoysOfEfficiency/Automation/HarvestAutomation.cs | 16 ++++++++-------- JoysOfEfficiency/Core/Config.cs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index 5b624f0..a462263 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -5,6 +5,9 @@ using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; +using StardewValley.GameData.Crops; +using StardewValley.Internal; +using StardewValley.ItemTypeDefinitions; using StardewValley.Objects; using StardewValley.TerrainFeatures; using StardewValley.Tools; @@ -148,16 +151,13 @@ public static void ToggleBlacklistUnderCursor() return; if (dirt.crop == null) - { Util.ShowHudMessage("There is no crop under the cursor"); - } else { - string name = dirt.crop.whichForageCrop.Value; + string cropID = dirt.crop.indexOfHarvest.Value; + string name = ItemRegistry.ResolveMetadata(cropID)?.GetParsedData().DisplayName; if (name == "") - { return; - } string text = ToggleBlackList(dirt.crop) ? $"{name} has been added to AutoHarvest exception" @@ -278,7 +278,7 @@ public static void ShakeNearbyFruitedBush() private static bool IsBlackListed(Crop crop) { String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; - return InstanceHolder.Config.HarvestException.Contains(Int32.Parse(index)); + return InstanceHolder.Config.HarvestException.Contains(index); } private static bool ToggleBlackList(Crop crop) @@ -286,11 +286,11 @@ private static bool ToggleBlackList(Crop crop) String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; if (IsBlackListed(crop)) { - InstanceHolder.Config.HarvestException.Remove(Int32.Parse(index)); + InstanceHolder.Config.HarvestException.Remove(index); } else { - InstanceHolder.Config.HarvestException.Add(Int32.Parse(index)); + InstanceHolder.Config.HarvestException.Add(index); } InstanceHolder.WriteConfig(); diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index fbcc3e4..c57f0f3 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -51,7 +51,7 @@ internal class Config public bool AutoHarvest { get; set; } = true; public int AutoHarvestRadius { get; set; } = 1; public bool ProtectNectarProducingFlower { get; set; } = true; - public List HarvestException { get; set; } = new List(); + public List HarvestException { get; set; } = new List(); public SButton ButtonToggleBlackList { get; set; } = Keys.F2.ToSButton(); public bool AutoDestroyDeadCrops { get; set; } = true; From 24c2b1964300ffd579b9586c17f858e50592be8c Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Fri, 12 Apr 2024 18:49:01 -0700 Subject: [PATCH 13/29] Fixed Harvest Automation for mod crops --- JoysOfEfficiency/Automation/HarvestAutomation.cs | 9 +++++---- JoysOfEfficiency/Core/Config.cs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index 5b624f0..6f1fe38 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -153,7 +153,8 @@ public static void ToggleBlacklistUnderCursor() } else { - string name = dirt.crop.whichForageCrop.Value; + string cropID = dirt.crop.indexOfHarvest.Value; + string name = ItemRegistry.ResolveMetadata(cropID)?.GetParsedData().DisplayName; if (name == "") { return; @@ -278,7 +279,7 @@ public static void ShakeNearbyFruitedBush() private static bool IsBlackListed(Crop crop) { String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; - return InstanceHolder.Config.HarvestException.Contains(Int32.Parse(index)); + return InstanceHolder.Config.HarvestException.Contains(index); } private static bool ToggleBlackList(Crop crop) @@ -286,11 +287,11 @@ private static bool ToggleBlackList(Crop crop) String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; if (IsBlackListed(crop)) { - InstanceHolder.Config.HarvestException.Remove(Int32.Parse(index)); + InstanceHolder.Config.HarvestException.Remove(index); } else { - InstanceHolder.Config.HarvestException.Add(Int32.Parse(index)); + InstanceHolder.Config.HarvestException.Add(index); } InstanceHolder.WriteConfig(); diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index 02ef0ef..b1ce42d 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -48,7 +48,7 @@ internal class Config public bool AutoHarvest { get; set; } = true; public int AutoHarvestRadius { get; set; } = 1; public bool ProtectNectarProducingFlower { get; set; } = true; - public List HarvestException { get; set; } = new List(); + public List HarvestException { get; set; } = new List(); public SButton ButtonToggleBlackList { get; set; } = Keys.F2.ToSButton(); public bool AutoDestroyDeadCrops { get; set; } = true; From a75a7a2ff516a0682749c5ea62b7bae24dc2a4e1 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:19:14 -0400 Subject: [PATCH 14/29] [Hackswell] Too much stuff to describe. Need to make smaller commits! --- .../Automation/AnimalAutomation.cs | 3 +- JoysOfEfficiency/Automation/FoodAutomation.cs | 83 ++++++++++++++++++- .../Automation/HarvestAutomation.cs | 12 +-- .../Automation/MachineOperator.cs | 33 +++++--- JoysOfEfficiency/Core/Config.cs | 46 ++++++++-- JoysOfEfficiency/Core/ModEntry.cs | 32 +++++-- .../EventHandler/ArtifactSpotDigger.cs | 13 ++- .../Huds/FishingProbabilitiesBox.cs | 39 +++++---- JoysOfEfficiency/Menus/JoeMenu.cs | 11 +-- JoysOfEfficiency/i18n/default.json | 5 +- JoysOfEfficiency/manifest.json | 2 +- testplan.txt | 5 -- 12 files changed, 214 insertions(+), 70 deletions(-) diff --git a/JoysOfEfficiency/Automation/AnimalAutomation.cs b/JoysOfEfficiency/Automation/AnimalAutomation.cs index 994097b..d681936 100644 --- a/JoysOfEfficiency/Automation/AnimalAutomation.cs +++ b/JoysOfEfficiency/Automation/AnimalAutomation.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using JoysOfEfficiency.Core; using JoysOfEfficiency.Utils; diff --git a/JoysOfEfficiency/Automation/FoodAutomation.cs b/JoysOfEfficiency/Automation/FoodAutomation.cs index 2606f74..bf5363f 100644 --- a/JoysOfEfficiency/Automation/FoodAutomation.cs +++ b/JoysOfEfficiency/Automation/FoodAutomation.cs @@ -1,7 +1,12 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using JoysOfEfficiency.Core; +using JoysOfEfficiency.Utils; +using StardewModdingAPI; using StardewValley; using StardewValley.Tools; +using StardewModdingAPI.Events; +using StardewValley.GameData.Objects; using SVObject = StardewValley.Object; namespace JoysOfEfficiency.Automation @@ -9,6 +14,8 @@ namespace JoysOfEfficiency.Automation internal class FoodAutomation { private static Config Config => InstanceHolder.Config; + private static readonly Logger Logger = new Logger("FoodAutomation"); + private static HashSet _dontEat = new HashSet(); public static void TryToEatIfNeeded(Farmer player) { @@ -16,6 +23,7 @@ public static void TryToEatIfNeeded(Farmer player) { return; } + if (player.CurrentTool != null && player.CurrentTool is FishingRod rod) { if (rod.inUse() && !player.UsingTool) @@ -37,7 +45,8 @@ public static void TryToEatIfNeeded(Farmer player) continue; //It's a edible item - if (itemToEat == null || itemToEat.Edibility / itemToEat.salePrice() < item.Edibility / item.salePrice()) + if (itemToEat == null || + itemToEat.Edibility / itemToEat.salePrice() < item.Edibility / item.salePrice()) { //Found good edibility per price or just first food itemToEat = item; @@ -56,5 +65,75 @@ public static void TryToEatIfNeeded(Farmer player) player.removeItemFromInventory(itemToEat); } } + + + // Don't Eat This mod copied and update here! Liberated from Pyrohead37. + public static void InitDontEat() + { + _dontEat.Clear(); + // public const int artisanGoodsCategory = -26; + // public const int ingredientsCategory = -25; + // public const int meatCategory = -14; + // public const int flowersCategory = -80; + // public const int FruitsCategory = -79; + // public const int VegetableCategory = -75; + // public const int FishCategory = -4; + // public const int EggCategory = -5; + // public const int MilkCategory = -6; + // public const int CookingCategory = -7; + // public const int inedible = -300; + // public const int GreensCategory = -81; + + // Go through all game objects and add any that are in our DontEatCategories first + foreach (KeyValuePair item in Game1.objectData) + { + string itemName = item.Value.Name; + int itemEdibility = item.Value.Edibility; + int itemCategory = item.Value.Category; + string categoryName = Object.GetCategoryDisplayName(itemCategory); + + if (itemEdibility == -300) { continue; } + if (Config.DontEatCategories.Contains(categoryName)) + { + _dontEat.Add(itemName); + Logger.Log($"Adding from Category [{item.Key}] {itemName} to the diet\t({categoryName})"); + } + } + + // Add individual items from DontEat list + foreach (var item in Config.DontEat) + { + _dontEat.Add(item); + Logger.Log($"Adding from DontEat {item} to the diet\t"); + } + + // REMOVE any items in the DoEat list! This must be last! + foreach (var item in Config.DoEat) + { + _dontEat.Remove(item); + Logger.Log($"REMOVING from DontEat {item}\t(DoEat exception)"); + } + + _dontEat.TrimExcess(); + } + + public static void ButtonPressed(object sender, ButtonPressedEventArgs e) + { + SVObject activePlayerItem = Game1.player.ActiveObject; + + if (Context.IsWorldReady && e.Button.IsActionButton() && activePlayerItem != null) + { + string itemName = activePlayerItem.DisplayName; + + // Logger.Log($"Testing item {itemName} for dontEatability"); + if (_dontEat.Contains(itemName)) + { + activePlayerItem.Edibility = -300; + Logger.Log($"Don't eat that {activePlayerItem.DisplayName}! Spoofing inedibility."); + } + } + } } + + } diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index 5b624f0..7d18f02 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -5,6 +5,7 @@ using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; +using StardewValley.GameData.Crops; using StardewValley.Objects; using StardewValley.TerrainFeatures; using StardewValley.Tools; @@ -52,6 +53,7 @@ public static void HarvestNearbyCrops(Farmer player) { Vector2 loc = kv.Key; HoeDirt dirt = kv.Value; + if (dirt.crop != null) Logger.Log($"Crop: {dirt.crop.indexOfHarvest} ** {dirt.crop.whichForageCrop}"); if (dirt.crop == null || !dirt.readyForHarvest()) { continue; @@ -277,20 +279,20 @@ public static void ShakeNearbyFruitedBush() private static bool IsBlackListed(Crop crop) { - String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; - return InstanceHolder.Config.HarvestException.Contains(Int32.Parse(index)); + String cropName = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; + return InstanceHolder.Config.HarvestException.Contains(cropName); } private static bool ToggleBlackList(Crop crop) { - String index = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; + String cropName = crop.forageCrop.Value ? crop.whichForageCrop.Value : crop.indexOfHarvest.Value; if (IsBlackListed(crop)) { - InstanceHolder.Config.HarvestException.Remove(Int32.Parse(index)); + InstanceHolder.Config.HarvestException.Remove(cropName); } else { - InstanceHolder.Config.HarvestException.Add(Int32.Parse(index)); + InstanceHolder.Config.HarvestException.Add(cropName); } InstanceHolder.WriteConfig(); diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/JoysOfEfficiency/Automation/MachineOperator.cs index a627d6e..f496cb7 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/JoysOfEfficiency/Automation/MachineOperator.cs @@ -21,6 +21,7 @@ public static void DepositIngredientsToMachines() { return; } + foreach (SVObject obj in Util.GetObjectsWithin(InstanceHolder.Config.MachineRadius).Where(IsObjectMachine)) { Vector2 loc = Util.GetLocationOf(currentLocation, obj); @@ -30,12 +31,12 @@ public static void DepositIngredientsToMachines() if (obj.Name == "Keg" && item.ParentSheetIndex == 433 && item.Stack < 5) { // You don't have enough beans. - Logger.Info($"Trying to deposit {item.Name} into KEG: {obj.Name}. Not enough beans!"); + Logger.Log($"Trying to deposit {item.Name} into KEG: {obj.Name}. Not enough beans!"); return; } bool accepted = obj.Name == "Furnace" ? CanFurnaceAcceptItem(item, player) : Utility.isThereAnObjectHereWhichAcceptsThisItem(currentLocation, item, (int)loc.X * tileSize, (int)loc.Y * tileSize); - Logger.Info($"Trying to deposit ({accepted}) {item.Name} into machine: {obj.Name}"); + Logger.Log($"Trying to deposit ({accepted}) {item.Name} into machine: {obj.Name}"); if (obj is Cask) { if (ModEntry.IsCoGOn || ModEntry.IsCaOn) @@ -56,25 +57,26 @@ public static void DepositIngredientsToMachines() if (item.Name == "Bait" || item.Name == "Magic Bait") { accepted = true; - Logger.Info($"\tCrab Pot and {item.Name} are now ACCEPTED."); + Logger.Log($"\tCrab Pot and {item.Name} are now ACCEPTED."); } } - else if (obj.Name == "Seed Maker") + else if (obj.Name == "Seed Maker" && InstanceHolder.Config.AutoDepositSeedMaker == false) { - accepted = InstanceHolder.Config.AutoDepositSeedMaker == false ? false : true; + continue; } if (!accepted) continue; - Logger.Info($"Trying to drop {item.Name} into {obj}."); // performObjectDropInAction but only if it's currently empty - obj.performObjectDropInAction(item, false, player); - if (!(obj.Name == "Furnace" || obj.Name == "Charcoal Kiln") || item.Stack == 0) + if (obj.performObjectDropInAction(item, false, player, true)) { player.reduceActiveItemByOne(); + Logger.Log($"Item {obj} MANUALLY consuming {item.Name}"); + } else { + Logger.Log($"Item {obj} should have already consumed {item.Name}"); } - Logger.Info($"DONE dropping {item.Name} into {obj}."); + Logger.Log($"DONE dropping {item.Name} into {obj}."); return; } @@ -85,8 +87,16 @@ public static void PullMachineResult() Farmer player = Game1.player; foreach (SVObject obj in Util.GetObjectsWithin(InstanceHolder.Config.MachineRadius).Where(IsObjectMachine)) { - if (!obj.readyForHarvest.Value || obj.heldObject.Value == null) + // Nothing in the machine... + if (obj.heldObject.Value == null) + { continue; + } + else if (!obj.readyForHarvest.Value) + { + Logger.Log($"Time until {obj.Name} ready for collecting item {obj.heldObject.Value.Name}: {obj.MinutesUntilReady} game minutes."); + continue; + } Item item = obj.heldObject.Value; if (player.couldInventoryAcceptThisItem(item)) @@ -96,7 +106,7 @@ public static void PullMachineResult() private static bool CanFurnaceAcceptItem(Item item, Farmer player) { - Logger.Info($"{player.Items.ContainsId(Object.coalQID)} ** {item.Stack} ** {item.ParentSheetIndex}"); + Logger.Log($"{player.Items.ContainsId(Object.coalQID)} ** {item.Stack} ** {item.ParentSheetIndex}"); // Minimum of one coal in inventory if (! player.Items.ContainsId(Object.coalQID, 1)) @@ -128,7 +138,6 @@ private static bool CanFurnaceAcceptItem(Item item, Farmer player) private static bool IsObjectMachine(SVObject obj) { - Logger.Log($"IsObjectMachine: Name: {obj.Name}"); if (InstanceHolder.Config.MachineTypes.Contains(obj.Name)) { return true; diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index 02ef0ef..b37bb85 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -45,10 +45,39 @@ internal class Config public float StaminaToEatRatio { get; set; } = 0.2f; public float HealthToEatRatio { get; set; } = 0.2f; + + public bool DontEatThat { get; set; } = false; + + public List DontEatCategories { get; set; } = new List() + { + "Artisan Goods", + "Animal Product", + "Fish", + "Crop", + "Vegetable", + "Flower", + "Harmful", + }; + public List DontEat { get; set; } = new List() + { + "Holly", + "Oil", + "Red Mushroom", + "Sap", + "Truffle", + }; + public List DoEat { get; set; } = new List() + { + "Mayonnaise", + "Beer", + "Green Tea", + }; + + public bool AutoHarvest { get; set; } = true; public int AutoHarvestRadius { get; set; } = 1; public bool ProtectNectarProducingFlower { get; set; } = true; - public List HarvestException { get; set; } = new List(); + public List HarvestException { get; set; } = new List(); public SButton ButtonToggleBlackList { get; set; } = Keys.F2.ToSButton(); public bool AutoDestroyDeadCrops { get; set; } = true; @@ -74,6 +103,8 @@ internal class Config public List MachineTypes { get; set; } = new List() { + "Anvil", + "Bait Maker", "Bee House", "Cask", "Charcoal Kiln", @@ -81,13 +112,19 @@ internal class Config "Coffee Maker", "Crab Pot", "Crystalarium", + "Dehydrator", + "Deluxe Worm Bin", + "Fish Smoker", "Furnace", + "Heavy Furnace", "Heavy Tapper", "Incubator", "Keg", "Loom", + "Lightning Rod", "Mayonnaise Machine", "Mushroom Box", + "Mushroom Log", "Oil Maker", "Preserves Jar", "Recycling Machine", @@ -99,13 +136,6 @@ internal class Config "Statue Of Perfection", "Tapper", "Worm Bin", - "Deluxe Worm Bin", - "Dehydrator", - "Mushroom Log", - "Bait Maker", - "Heavy Furnace", - "Fish Smoker", - "Anvil" }; //Fishing Probabilities diff --git a/JoysOfEfficiency/Core/ModEntry.cs b/JoysOfEfficiency/Core/ModEntry.cs index db5aaa5..c70bd22 100644 --- a/JoysOfEfficiency/Core/ModEntry.cs +++ b/JoysOfEfficiency/Core/ModEntry.cs @@ -1,17 +1,18 @@ using System.IO; +using JoysOfEfficiency.Automation; using JoysOfEfficiency.EventHandler; using JoysOfEfficiency.Harmony; using JoysOfEfficiency.Huds; using JoysOfEfficiency.ModCheckers; using JoysOfEfficiency.Utils; using StardewModdingAPI; +using StardewModdingAPI.Events; using StardewValley; namespace JoysOfEfficiency.Core { using Player = Farmer; - /// /// This class is a representation of the mod itself. /// @@ -39,14 +40,13 @@ public override void Entry(IModHelper helper) // Register events. EventHolder.RegisterEvents(Helper.Events); + // Limit config values. + ConfigLimitation.LimitConfigValues(); // Registration commands. Helper.ConsoleCommands.Add("joedebug", "Debug command for JoE", OnDebugCommand); Helper.ConsoleCommands.Add("joerelcon", "Reloading config command for JoE", OnReloadConfigCommand); - - - // Limit config values. - ConfigLimitation.LimitConfigValues(); + Helper.Events.GameLoop.GameLaunched += OnGameLaunched; // Check mod compatibilities. if(ModChecker.IsCoGLoaded(helper)) @@ -72,6 +72,13 @@ public override void Entry(IModHelper helper) } helper.WriteConfig(Conf); + + if (Conf.DontEatThat) + { + Logger.Log($"Don't Eat That(tm) is enabled!"); + Helper.Events.Input.ButtonPressed += FoodAutomation.ButtonPressed; + } + MineIcons.Init(helper); } @@ -79,13 +86,26 @@ private static void OnReloadConfigCommand(string name, string[] args) { // Loads configuration from file. InstanceHolder.LoadConfig(); + if (Conf.DontEatThat) + { + Logger.Log($"Don't Eat That(tm) is enabled!"); + FoodAutomation.InitDontEat(); + } Logger.Log("Reloaded JoE's config."); } + private static void OnGameLaunched(object sender, GameLaunchedEventArgs e) + { + if (Conf.DontEatThat) + { + Logger.Log($"Don't Eat That(tm) is enabled!"); + FoodAutomation.InitDontEat(); + } + } + private static void OnDebugCommand(string name, string[] args) { DebugMode = !DebugMode; - } public string GetFilePath(string fileName) diff --git a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs index de1480d..f6562af 100644 --- a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs +++ b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs @@ -37,14 +37,23 @@ public static void DigNearbyArtifactSpots() continue; } - if (location.Objects[loc].name == "Artifact Spot" || location.Objects[loc].name == "Seed Spot") + if (location.Objects[loc].name == "Artifact Spot") { - Logger.Info($"** {location.Objects[loc].name} ** at [{loc.X},{loc.Y}]"); + Logger.Log($"ArtifactSpot: {location.Objects[loc].name} at [{loc.X},{loc.Y}]"); location.digUpArtifactSpot(x, y, player); location.Objects.Remove(loc); location.terrainFeatures.Add(loc, new HoeDirt()); flag = true; } + else if (location.Objects[loc].name == "Seed Spot") + { + Logger.Log($"SeedSpot: {location.Objects[loc].name} at [{loc.X},{loc.Y}]"); +// location.performUseAction(location); +// location.performToolAction(hoe, x, y); +// hoe.DoFunction(location, x, y, 1, player); +// location.Objects.Remove(loc); +// location.terrainFeatures.Add(loc, new HoeDirt()); + } } } diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index 6729816..c4e93a0 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -106,12 +106,12 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, LocationData thisLocData = Game1.currentLocation.GetData(); String jThisLocData = JsonSerializer.Serialize(thisLocData, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"This LocationData: {jThisLocData}"); + Logger.Log($"This LocationData: {jThisLocData}"); Dictionary allFishData = DataLoader.Fish(Game1.content); string locName = locationName ?? currLocation.Name; - //Logger.Info($"GetFishes: Loc: {locName} ** Season: {season}"); + Logger.Log($"GetFishes: Loc: {locName} ** Season: {season}"); if (locName.Equals("WitchSwamp") && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") @@ -124,10 +124,10 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, } String JSONFishes = JsonSerializer.Serialize(allFishData, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"All Fishes: {JSONFishes}"); + Logger.Log($"All Fishes: {JSONFishes}"); Dictionary dictionary = DataLoader.Locations(Game1.content); String jDict = JsonSerializer.Serialize(dictionary, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"All Location Data: {jDict}"); + Logger.Log($"All Location Data: {jDict}"); IEnumerable possibleFish = dictionary["Default"].Fish; if (thisLocData != null && thisLocData.Fish?.Count > 0) @@ -141,15 +141,15 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, return dictFish; } - //Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} [bobber] {rod.bobber.X},{rod.bobber.Y} ** {currLocation.locationContextId} ** "); + Logger.Log($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} [bobber] {rod.bobber.X},{rod.bobber.Y} ** {currLocation.locationContextId} ** "); LocationContextData bubba = currLocation.GetLocationContext(); String jsonBubba = JsonSerializer.Serialize(bubba, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"GameLocationContext: {jsonBubba}"); + Logger.Log($"GameLocationContext: {jsonBubba}"); currLocation.TryGetFishAreaForTile(who.Tile, out var fishAreaID, out var fishAreaData); - //Logger.Info($"FishAreaID: {fishAreaID}"); + Logger.Log($"FishAreaID: {fishAreaID}"); String jsonFishAreaData = JsonSerializer.Serialize(fishAreaData, new JsonSerializerOptions { WriteIndented = true }); - //Logger.Info($"FishAreaData: {jsonFishAreaData}"); + Logger.Log($"FishAreaData: {jsonFishAreaData}"); possibleFish = from p in possibleFish orderby p.Precedence, Game1.random.Next() @@ -157,7 +157,7 @@ private static Dictionary GetFishes(int waterDepth, Farmer who, select p; String JSON = JsonSerializer.Serialize(possibleFish, new JsonSerializerOptions{WriteIndented = true}); - //Logger.Info($"Possibru Fishu:\n{JSON}"); + Logger.Log($"Possibru Fishu:\n{JSON}"); // Reference: https://stardewvalleywiki.com/Modding:Fish_data#Fish_data_and_spawn_criteria // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 @@ -179,11 +179,10 @@ 12 fishingLevel */ double chance = 0.0d; foreach (SpawnFishData f in possibleFish) { - // Use ItemId unless its null. Account for mods with non-standard IDs for vanilla records - String id = f.ItemId; - if (id == null) { id = f.Id; } + String id = f.Id; + Logger.Log($"Testing Fish ID: {id}"); id = Regex.Replace(id, "\\(O\\)", ""); - //Logger.Info($"Testing Fish ID: {id}"); + Logger.Log($"Testing Fish ID: {id}"); // Any list item like "(O)167|(O)168|(O)169|(O)170|(O)171|(O)172" is a list of garbage. Handle it. if (id.Contains('|')) @@ -201,15 +200,15 @@ 12 fishingLevel */ // If it's not found in the allFishData, assign the chance from possibleFish instead if (!allFishData.ContainsKey(id)) { - //Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); - dictFish[id] = f.Chance; + Logger.Log($"\tdictFish: Adding {id} :: {f.Chance}"); + dictFish.Add(id, f.Chance); continue; } - //Logger.Info($"Parsing through allFishData for {f.Id} now..."); + Logger.Log($"Parsing through allFishData for {f.Id} now..."); String[] fishData = allFishData[id].Split('/'); String jFishData = JsonSerializer.Serialize(fishData, new JsonSerializerOptions{WriteIndented = true}); - //Logger.Info($"\tID: {id} *** {jFishData}"); + Logger.Log($"\tID: {id} *** {jFishData}"); // If the time isn't in the fish's catch times, go on to next fish. String[] catchTimes = fishData[5].Split(' '); @@ -244,11 +243,11 @@ 12 fishingLevel */ spawnMultiplier += who.FishingLevel / 50f; chance = Math.Min(spawnMultiplier, 0.89999997615814209); - //Logger.Info($"dictFish: Adding {id} :: {chance}"); - dictFish[id] = chance; + Logger.Log($"dictFish: Adding {id} :: {chance}"); + dictFish.Add(id, chance); } String jDictFish = JsonSerializer.Serialize(dictFish, new JsonSerializerOptions{WriteIndented = true}); - //Logger.Info($"Possible Fish:\n{jDictFish}"); + Logger.Log($"Possible Fish:\n{jDictFish}"); return dictFish; } diff --git a/JoysOfEfficiency/Menus/JoeMenu.cs b/JoysOfEfficiency/Menus/JoeMenu.cs index 6b9b1eb..0bc7a9a 100644 --- a/JoysOfEfficiency/Menus/JoeMenu.cs +++ b/JoysOfEfficiency/Menus/JoeMenu.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using JoysOfEfficiency.Core; using JoysOfEfficiency.OptionsElements; using JoysOfEfficiency.Utils; @@ -109,7 +108,7 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new ModifiedSlider("CPUThresholdFishing", 0, (int)(Config.CpuThresholdFishing * 10), 0, 5, OnSliderValueChanged, () => !Config.AutoFishing, Format)); tab.AddOptionsElement(new ModifiedCheckBox("AutoReelRod", 6, Config.AutoReelRod, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedSlider("ThrowPower", 17, (int)(Config.ThrowPower * 10), 0, 10, OnSliderValueChanged, null, Format)); - tab.AddOptionsElement(new ModifiedSlider("ThresholdStaminaPersentage", 18, Config.ThresholdStaminaPercentage, 10, 60, OnSliderValueChanged, null, Format)); + tab.AddOptionsElement(new ModifiedSlider("ThresholdStaminaPercentage", 18, Config.ThresholdStaminaPercentage, 10, 60, OnSliderValueChanged, null, Format)); tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Auto Gate")); @@ -120,6 +119,7 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new ModifiedCheckBox("AutoEat", 10, Config.AutoEat, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedSlider("StaminaToEatRatio", 1, (int)(Config.StaminaToEatRatio * 10), 1, 8, OnSliderValueChanged, () => !Config.AutoEat, Format)); tab.AddOptionsElement(new ModifiedSlider("HealthToEatRatio", 2, (int)(Config.HealthToEatRatio * 10), 1, 8, OnSliderValueChanged, () => !Config.AutoEat, Format)); + tab.AddOptionsElement(new ModifiedCheckBox("DontEatThat", 43, Config.DontEatThat, OnCheckboxValueChanged)); tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Auto Harvest")); @@ -173,7 +173,7 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new LabelComponent("Auto Shearing and Milking")); tab.AddOptionsElement(new ModifiedCheckBox("AutoShearingAndMilking", 35, Config.AutoShearingAndMilking, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedSlider("AnimalHarvestRadius", 14, Config.AnimalHarvestRadius, 1, 3, OnSliderValueChanged, () => !Config.AutoShearingAndMilking || Config.BalancedMode)); - + tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Collect Letter Attachments And Quests")); tab.AddOptionsElement(new ModifiedCheckBox("CollectLetterAttachmentsAndQuests", 36, Config.CollectLetterAttachmentsAndQuests, OnCheckboxValueChanged)); @@ -365,6 +365,7 @@ private void OnCheckboxValueChanged(int index, bool value) case 40: Config.BreakRocks = value; break; case 41: Config.ChopTwigs = value; break; case 42: Config.AutoDepositSeedMaker = value; break; + case 43: Config.DontEatThat = value; break; default: return; } InstanceHolder.WriteConfig(); @@ -852,7 +853,7 @@ private int GetLastVisibleIndex() } /// - /// Try changing tab to a specified tab. + /// Try changing tab to a specified tab. /// /// Which tab index to change. private void TryToChangeTab(int which) @@ -868,4 +869,4 @@ private void TryToChangeTab(int which) Game1.playSound("drumkit6"); } } -} \ No newline at end of file +} diff --git a/JoysOfEfficiency/i18n/default.json b/JoysOfEfficiency/i18n/default.json index 9187d76..9eced3b 100644 --- a/JoysOfEfficiency/i18n/default.json +++ b/JoysOfEfficiency/i18n/default.json @@ -31,7 +31,7 @@ "options.AutoDigArtifactSpot": "Auto-dig nearby artifact spots", "options.AutoDigRadius": "How far tiles to auto-dig", "options.AutoEat": "Auto-eat something if in the pinch", - "options.AutoFishing": "Automatic Fishing minigame", + "options.AutoFishing": "Automatic Fishing mini-game", "options.AutoGate": "Open/Close gates automatically", "options.AutoHarvest": "Auto-Harvest grown crops", "options.AutoHarvestRadius": "How far tiles to harvest", @@ -53,6 +53,7 @@ "options.CollectLetterAttachmentsAndQuests": "Auto-accept quests or item attached to mail", "options.CPUThresholdFishing": "How often AI operates bar", "options.CraftingFromChests": "Crafting using items in nearby chests", + "options.DontEatThat": "Enable 'Don't Eat That(tm)'", "options.EstimateShippingPrice": "Estimate Shipping Price", "options.FilterBackgroundInMenu": "Outside of config menu will be darker", "options.FindCanFromInventory": "Find Watering Can from inventory", @@ -132,4 +133,4 @@ "taste.love.male": "He loves this gift.", "taste.neutral.female": "She has neutral feelings about this gift.", "taste.neutral.male": "He has neutral feelings about this gift." -} \ No newline at end of file +} diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 62b4ce3..0e63c0c 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -6,5 +6,5 @@ "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.5.0-unofficial.3-Hackswell" + "Version": "1.5.0-unofficial.4-Hackswell" } diff --git a/testplan.txt b/testplan.txt index 64953c5..a816579 100644 --- a/testplan.txt +++ b/testplan.txt @@ -1,8 +1,3 @@ -*** KNOWN BROKEN *** --------------------- - - - *** APPARENTLY WORKING *** -------------------------- +[Fence Gate Automation] From a8038444c4feb9e7a7934d2cefd61e3970290e3c Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:13:04 -0400 Subject: [PATCH 15/29] [Hackswell] Added check for WateringCan.IsBottomless before decreasing water amount. Updated docs FeaturesAndConfigs.md and WhatsNew.md --- .../Automation/HarvestAutomation.cs | 7 +- JoysOfEfficiency/FeaturesAndConfigs.md | 296 +++++++----------- JoysOfEfficiency/WhatsNew.md | 40 ++- 3 files changed, 160 insertions(+), 183 deletions(-) diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index c4361a9..3b2983f 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -5,9 +5,6 @@ using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; -using StardewValley.GameData.Crops; -using StardewValley.Internal; -using StardewValley.ItemTypeDefinitions; using StardewValley.Objects; using StardewValley.TerrainFeatures; using StardewValley.Tools; @@ -117,7 +114,7 @@ public static void WaterNearbyCrops() dirt.state.Value = 1; Game1.player.Stamina -= consume; - can.WaterLeft--; + if (!can.IsBottomless) can.WaterLeft--; watered = true; } foreach (IndoorPot pot in Util.GetObjectsWithin(InstanceHolder.Config.AutoWaterRadius)) @@ -132,7 +129,7 @@ public static void WaterNearbyCrops() dirt.state.Value = 1; pot.showNextIndex.Value = true; Game1.player.Stamina -= consume; - can.WaterLeft--; + if (!can.IsBottomless) can.WaterLeft--; watered = true; } } diff --git a/JoysOfEfficiency/FeaturesAndConfigs.md b/JoysOfEfficiency/FeaturesAndConfigs.md index c74c72a..d73fdcf 100644 --- a/JoysOfEfficiency/FeaturesAndConfigs.md +++ b/JoysOfEfficiency/FeaturesAndConfigs.md @@ -4,15 +4,12 @@ This is a list of features and configs available in [Joys of Efficiency (JoE)](h Config description will be like: - Name("Category Tab in config menu", Type, default value, [minimum or maximum value if its type is int or float]) - "discription of the config". - "Category Tab in config menu" is one of following: "Automation", "UIs", "Cheats", "Misc", "Controls", and "Not on menu". # Features - ## Safe Mode If Safe Mode is enabled, JoE won't patch the game itself, so it's much safer. @@ -28,110 +25,77 @@ You can open mod configuration menu when specified key(Default:R). You can't disable this feature because it's a core feature. **[CONFIG]** - - - KeyShowMenu("Controls", SButton, default:"R") - The key to open config menu. - - - FilterBackgroundInMenu("UIs", bool, default:true) - When config menu is opened, outside of it will be darker like inventory menu. - - ShowMousePositionWhenAssigningLocation("UIs", bool, default:true) - When assigning coordinates of window, shows mouse cursor's position. + ## Balanced Mode -Did you thought following utilities are a bit cheaty? +Did you think the following utilities are a bit cheaty? -This utility lets them not to be executed so often(almost 1 executing per seconds), and -automation radius will be 1 tile. +This utility lets them not to be executed so often(almost 1 executing per seconds), and +automation radius will be 1 tile. - -This utility affects to ***AutoWaterNearbyCrops, AutoPetNearbyAnimals, AutoHarvest, AutoCollectCollectibles, AutoShakeFruitedPlants, +This utility affects to ***AutoWaterNearbyCrops, AutoPetNearbyAnimals, AutoHarvest, AutoCollectCollectibles, AutoShakeFruitedPlants, AutoDigArtifactSpot, AutoDepositIngredient, and AutoPullMachineResult.*** - **[CONFIG]** - - BalancedMode("Automation" bool, default:true) - whether this utility is enabled. ## Mine Info GUI -With this utility, you can check how many stones left, and monster kills tally counter, and whether ladder has spawned in mines. -You can see those when your mouse hovered over the icons. +With this utility, you can check how many stones left, and monster kills tally counter, and whether ladder has spawned in mines. +You can see those when your mouse hovered over the icons. **[CONFIG]** - -- MineInfoGUI("UIs", bool, default:true) - whether this utility is enabled. +- MineInfoGUI("UIs", bool, default:true) - whether this utility is enabled. ## Auto Water Nearby Crops -With this utility, the crops planted on the soil will be watered automatically. -To use this, you must have at least one of Watering Can and it to have enough water within, and this costs stamina of the farmer each crops. +With this utility, the crops planted on the soil will be watered automatically. +To use this, you must have at least one of Watering Can and it to have enough water within, and this costs stamina of the farmer each crops. **[CONFIG]** - -- AutoWaterNearbyCrops("Automation", bool, default:true) - whether this utility is enabled.  - - +- AutoWaterNearbyCrops("Automation", bool, default:true) - whether this utility is enabled. - AutoWaterRadius("Automation", int, default:1) - How far tiles can be affected by this utility. - - - FindCanFromInventory("Automation", bool, default:true) - Find Can from entire inventory or just held by player. + ## Auto Refill Watering Can You can refill your watering can automatically from nearby water source. **[CONFIG]** - -- AutoRefillWateringCan("Automation", bool, default:true) - whether this utility is enabled.  +- AutoRefillWateringCan("Automation", bool, default:true) - whether this utility is enabled. ## Gift Information Tooltip ![](https://i.imgur.com/NOYidaU.gif) - -With this utility, you can check how much do villagers like, dislike the gift before giving it to them. +With this utility, you can check how much do villagers like, dislike the gift before giving it to them. - **[CONFIG]** - - GiftInformation("UIs", bool, default:true) - whether this utility is enabled. ## Auto Pet Nearby Animals -With this utility, you don't have to click on animals to pet, just get close to them. +With this utility, you don't have to click on animals to pet, just get close to them. **[CONFIG]** - - AutoPetNearbyAnimals("Automation", bool, default:false) - whether this utility is enabled. - - - AutoPetRadius("Automation", int, default:1) - How far tiles can be affected by this utility. ## Auto Animal Door -With this utility, animal doors will open in morning if it is sunny and not winter, and close at the time day changed without click it manually. +With this utility, animal doors will open in morning if it is sunny and not winter, and close at the time day changed without click it manually. **[CONFIG]** - - - - AutoAnimalDoor("Automation", bool, default:true) - whether this utility is enabled. ## AFK Fishing Are you tired to deal with fishing? When this utility is enabled, your computer will catch fish instead of you. -This was requested by @GastlyMister. Many thanks! +This was requested by @GastlyMister. Many thanks! **[CONFIG]** - - AutoFishing("Automation", bool, default:false) - whether this plays fishing minigame. - - -- CPUThresholdFishing("Automation", float, default:0.2 min:0.0 max:0.5) - determines how often cpu reel up the rod. - - -- ThrowPower("Automation", float, default:1.0 min:0.0 max:1.0) - How strong a bobber will be thrown. - - +- CPUThresholdFishing("Automation", float, default:0.2 min:0.0 max:0.5) - determines how often cpu reel up the rod. +- ThrowPower("Automation", float, default:1.0 min:0.0 max:1.0) - How strong a bobber will be thrown. - ThresholdStaminaPercentage("Automation", int, default:20 min:10 max:60) - If farmer's stamina percentage is lower than this value, AFK mode will be stopped. - - -- AutoReelRod("Automation", bool, default:true) - whether it automatically reels up the rod when fish nibbled. - - +- AutoReelRod("Automation", bool, default:true) - whether it automatically reels up the rod when fish nibbled. - ToggleAFKFishing("Controls", SButton, default: 'End') - The button to activate/deactivate AFK fishing mode. @@ -141,126 +105,139 @@ Are you tired to deal with fishing? When this utility is enabled, your computer This feature shows the information about the fish when playing fishing minigame. - **[CONFIG]** - - FishingInfo("UIs", bool, default:true) - whether this utility enabled. -## Auto Gate +## Auto Gate ![Auto Gate](https://i.imgur.com/ZUiI9Zr.gif) - -Are you tired of clicking fence gates? Then try this. -This feature let gates open when farmer is close to them, and otherwise, close them automatically. -It should work with both single-player and coop game modes. -This was requested by @plaah007. Thanks alot! +Are you tired of clicking fence gates? Then try this. +This feature let gates open when farmer is close to them, and otherwise, close them automatically. +It should work with both single-player and coop game modes. +This was requested by @plaah007. Thanks alot! **[CONFIG]** - - AutoGate("Automation", bool, default:true) - whether this utility enabled. ## Auto Eat -This utility let the farmer to eat something automatically when his/her health or stamina is low. -These threshold ratio can be changed. -This was requested by @GastlyMister. thanks! +This utility let the farmer to eat something automatically when his/her health or stamina is low. +These threshold ratio can be changed. +This was requested by @GastlyMister. thanks! **[CONFIG]** - - - - AutoEat("Automation", bool, default:false) - whether this utility enabled. - - - StaminaToEatRatio("Automation", float, default:0.3 min:0.3 max:0.8) - the threshold ratio of stamina to eat something - - - HealthToEatRatio("Automation", float, default:0.3 min:0.3 max:0.8) - the threshold ratio of health to eat something ## Auto Harvest -This utility let the farmer to harvest crops (and spring onions) automatically when he/she gets closed to it. +This utility let the farmer to harvest crops (and spring onions) automatically when he/she gets closed to it. **[CONFIG]** - -AutoHarvest("Automation", bool, default:false) - whether this utility enabled. -ProtectNectarProducingFlower("Automation", bool, default:true) - this option protects flowers producing nectar not to be Auto harvested. -AutoHarvestRadius("Automation", int, default:1) - How far tiles can be affected by this utility. -HarvestException("Automation", List) - Crop id list not to be auto harvested. -KeyToggleBlackList("Controls", SButton, default:"F2") - Add/Remove crop under cursor to/from blacklist. +- AutoHarvest("Automation", bool, default:false) - whether this utility enabled. +- ProtectNectarProducingFlower("Automation", bool, default:true) - this option protects flowers producing nectar not to be Auto harvested. +- AutoHarvestRadius("Automation", int, default:1) - How far tiles can be affected by this utility. +- HarvestException("Automation", List) - Crop id list not to be auto harvested. +- KeyToggleBlackList("Controls", SButton, default:"F2") - Add/Remove crop under cursor to/from blacklist. ## Auto Destroy Dead Crops This utility destorys dead crops automatically when he/she gets closed to it. **[CONFIG]** - -AutoDestroyDeadCrops("Automation", bool, default:true) - whether this utility enabled. +- AutoDestroyDeadCrops("Automation", bool, default:true) - whether this utility enabled. ## Auto Collect Collectibles -This utility let the farmer to collect collectibles (crystals, forages, animal products, and so on) automatically -when he/she gets closed to it. +This utility let the farmer to collect collectibles (crystals, forages, animal products, and so on) automatically when he/she gets closed to it. **[CONFIG]** - -AutoCollectCollectibles("Automation", bool, default:false) - whether this utility enabled. -AutoCollectRadius("Automation", int, default:1) - How far tiles can be affected by this utility. +- AutoCollectCollectibles("Automation", bool, default:false) - whether this utility enabled. +- AutoCollectRadius("Automation", int, default:1) - How far tiles can be affected by this utility. ## Auto Shake Fruited Plants -This utility shakes fruited tree(pines, acorns, apples, cherries, and so on) and berry bushes -automatically when the farmer gets closed to it. +This utility shakes fruited tree(pines, acorns, apples, cherries, and so on) and berry bushes automatically when the farmer gets closed to it. **[CONFIG]** - -AutoShakeFruitedPlamts("Automation", bool, default:true) - whether this utility enabled. -AutoShakeRadius("Automation", int, default:1) - How far tiles can be affected by this utility. +- AutoShakeFruitedPlamts("Automation", bool, default:true) - whether this utility enabled. +- AutoShakeRadius("Automation", int, default:1) - How far tiles can be affected by this utility. ## Auto Dig Artifact Spot -This utility digs artifact spots nearby the farmer automatically. +This utility digs artifact spots nearby the farmer automatically. -**[CONFIG]** +Currently does **NOT** handle Seed Spots. -AutoDigArtifactSpot("Automation", bool, default:false) - whether this utility enabled. -AutoDigRadius("Automation", int, default:1) - How far tiles can be affected by this utility. -FindHoeFromInventory("Automation", bool, default:true) - Find hoe from entire inventory or just held by player. +**[CONFIG]** +- AutoDigArtifactSpot("Automation", bool, default:false) - whether this utility enabled. +- AutoDigRadius("Automation", int, default:1) - How far tiles can be affected by this utility. +- FindHoeFromInventory("Automation", bool, default:true) - Find hoe from entire inventory or just held by player. ## Auto Deposit Ingredient -This utility will try to deposit ingredient you held to nearby machines automatically. +This utility will try to deposit ingredient you held to nearby machines automatically. **[CONFIG]** +- AutoDepositIngredient("Automation", bool, default:false) - whether this utility enabled. +- MachineRadius("Automation", int, default:1) - How far tiles can be affected by this utility. +- AutoDepositSeedMaker("Automation, bool, default:false) - Whether to auto-deposit into Seed Makers. -AutoDepositIngredient("Automation", bool, default:false) - whether this utility enabled. -MachineRadius("Automation", int, default:1) - How far tiles can be affected by this utility. ## Auto Pull Machine Result -This utility will try to pull results from nearby machines and give it to the farmer automatically. +This utility will try to pull results from nearby machines and give it to the farmer automatically. **[CONFIG]** +- AutoPullMachineResult("Automation", bool, default:true) - whether this utility enabled. +- MachineRadius("Automation", int, default:1) - How far tiles can be affected by this utility. + + +## List of Valid Machines (for auto-push and auto-pull) +- MachineTypes [List of Machine Name strings] - You can disable or add new machine types by editing config.json. If a new version of SdV comes out with a new machine, you can add it here without waiting for a new version of JoE! + - "Anvil", + "Bait Maker", + "Bee House", + "Cask", + "Charcoal Kiln", + "Cheese Press", + "Coffee Maker", + "Crab Pot", + "Crystalarium", + "Dehydrator", + "Deluxe Worm Bin", + "Fish Smoker", + "Furnace", + "Heavy Furnace", + "Heavy Tapper", + "Incubator", + "Keg", + "Loom", + "Lightning Rod", + "Mayonnaise Machine", + "Mushroom Box", + "Mushroom Log", + "Oil Maker", + "Preserves Jar", + "Recycling Machine", + "Seed Maker", + "Sewing Machine", + "Slime Egg-Press", + "Slime Incubator", + "Statue Of Endless Fortune", + "Statue Of Perfection", + "Tapper", + "Worm Bin" -AutoPullMachineResult("Automation", bool, default:true) - whether this utility enabled. -MachineRadius("Automation", int, default:1) - How far tiles can be affected by this utility. - ## Auto Pet Nearby Pets -Oh, seriously you want to pet pets automatically? -All right, this utility pets nearby pets automatically. +Oh, seriously you want to pet pets automatically? +All right, this utility pets nearby pets automatically. **[CONFIG]** - - AutoPetNearbyPets("Automation", bool, default:false) - whether this utility is enabled. - AutoPetRadius("Automation", int, default:1 min:1 max:3) - How far tiles can be affected by this utility. ## Fishing Probabilities Info -This utility let you know what fish could be caught (and estimated probability of catching) when you are fishing. +This utility let you know what fish could be caught (and estimated probability of catching) when you are fishing. **[CONFIG]** - - FishingProbabilitiesInfo("UIs", bool, default:false) - whether this utility is enabled. - - - ProbBoxCoordinates("UIs", Point, default:[100,400]) - Top-left coordinates of the window. - - - MorePreciseProbabilities("UIs", bool, default:true) - Displays more plactical and precise probabiilities. - - - TrialOfExamine("UIs", int, default:10 min:1 max:50) - Trial number of computing probabilities. @@ -268,9 +245,7 @@ MachineRadius("Automation", int, default:1) - How far tiles can be affected by t This utility shows estimated total shipping price when you opened shipping box. **[CONFIG]** - - EstimateShippingPrice("UIs", bool, default:true) - whether this utility is enabled. - - PriceBoxCoordinates("UIs", Point, default:[100,100]) - Top-left coordinates of the window. ## Unify Flower Colors @@ -278,126 +253,93 @@ This utility unifies flower colors to reduce occupied spaces according to its sp In config file, you can change the color using "R, G, B, A" format. **[CONFIG]** - - UnifyFlowerColors("Misc", bool, default:false) - whether this utility is enabled. - - - JazzColor("Misc", Color, default:{0, 255, 255, 255}) - The color of Blue Jazz. - - - TulipColor("Misc", Color, default:{255, 0, 0, 255}) - The color of Turip. - - - PoppyColor("Misc", Color, default:{255, 69, 0, 255}) - The color of Poppy. - - - SummerSpangleColor("Misc", Color, default:{255, 215, 0, 255}) - The color of Summer Spangle. - - - FairyRoseColor("Misc", Color, default:{216, 191, 216, 255}) - The color of Fairy Rose. - - - ButtonToggleFlowerColorUnification("Controls", SButton, default: 'L') - The button to register/unregister flowers to unify their colors. - - - CustomizedFlowerColors("Misc", Dictionary) - Customized flower colors for unification. ## Auto Loot Treasures - - This utility loots all acceptable items in treasure box, not chests player placed or shipping bin. (e.g. fishing treasures, mine treasures) - **[CONFIG]** - - - AutoLootTreasures("Automation", bool, default:true) - whether this utility is enabled. - - - CloseTreasureWhenAllLooted("Automation", bool, default:false) - Closes the treasure chest menu when all items taken. ## Collect Letter Attachments And Quests - - This feature collects attached items or accepts quests when you opened mail contains those. **[CONFIG]** - - - CollectLetterAttachmentsAndQuests("Automation", bool, default:false) - whether this utility is enabled. ## Pause When Idle - - This feature pauses game when you are not in work. - It helps you not to waste in-game time when idling. **[CONFIG]** - - - PauseWhenIdle("Misc", bool, default:false) - whether this utility is enabled. - - - IdleTimeout("Misc", int, default:180 min:1 max:300) - Timeout needed to pause the game in seconds. - - - PauseNotificationX("Not on menu", int, default:100) - X position of paused notification. - - - PauseNotificationY("Not on menu", int, default:700) - Y position of paused notification. ## Auto Pick Up Trash - - This feature searches trash can and pick up trash without being detected. - +**[CONFIG]** - AutoPickUpTrash("Automation", bool, default:false) - whether this utility is enabled. - - - ScavengingRadius("Automation", int, default:2 min:1 max:3) - How far tiles can be affected by this utility. ## Auto Shearing and Milking - - This feature let you shear/milk nearby mature sheep/cows automatically when you held shears/bucket. - +**[CONFIG]** - AutoShearingAndMilking("Automation", bool, default:true) - whether this utility is enabled. - - - AnimalHarvestRadius("Automation", int, default:1 min:1 max:3) - How far tiles can be affected by this utility. ## Farm Cleaner - - This feature will clean up small rocks, twigs, and weeds in farm. - Please note that it can consume the farmer's stamina relatively easily. - You have to select appropriate tool in hotbar to use. - **[CONFIG]** - - RadiusFarmCleanup("Automation", int, default:1 min:1 max:3) - How far tiles can be affected by this utility. - - - CutWeeds("Automation", bool, default:false) - Cuts weeds nearby (requires Scythe). - - - BreakRocks("Automation", bool, default:false) - Breaks small rocks nearby (requires Pickaxe). +- ChopTwigs("Automation", bool, default:false) - Chops twigs nearby (requires Axe). + +## Don't Eat That +[Don't Eat That](https://www.nexusmods.com/stardewvalley/mods/1951) was an old mod by [Pyrohead37]. Since it hasn't been updated since 2019, I've decompiled the code, updated it, and added it to JoE! -- ChopTwigs("Automation", bool, default:false) - Chops twigs nearby (requires Axe). \ No newline at end of file +**[CONFIG]** +- DontEatCategories [List of Category strings] - Which categories of items NOT to eat. Defaults are: + - Artisan Goods + - Animal Product + - Crop + - Fish + - Flower + - Harmful + - Vegetable +- DontEat [List of Item name strings] - Which specific ITEMS not to eat. It's okay if they overlap categories. Defaults: + - Holly + - Oil + - Red Mushroom + - Sap + - Truffle +- DoEat [List of Item name strings] - Which specific ITEMS to **ALLOW** eating. These are actually _removed_ from the "don't eat" list that was compiled from the above entries. Defaults: + - Mayonnaise + - Beer + - Green Tea diff --git a/JoysOfEfficiency/WhatsNew.md b/JoysOfEfficiency/WhatsNew.md index e1aaa25..91c3add 100644 --- a/JoysOfEfficiency/WhatsNew.md +++ b/JoysOfEfficiency/WhatsNew.md @@ -1,7 +1,45 @@ # Overview -This is a changelog from 1.4.9 +This is a changelog from 1.5.0 # Changelog +## 1.5.0 +- Update build files to work with net6.0 / SdV 1.6 [Hackswell + others] + - Removed all Reflections and use updated public methods + - Converted all ObjectIDs from Int32 to string. Still unoptimized, but should be more compatible. +- Added config option "AutoDepositSeedMaker" to NOT auto-drop into Seed Makers. [Hackswell] +- Added new config item "MachineTypes" in config.json. [Hackswell] + - All machines are enumerated by default now, and up to date as of SdV 1.6.4. + - If a new machine is added to SdV, you can manually add the name to the list. No need to recompile JoE! +- Updated some of the Fishing HUDs and probability code. [Sandman534] + - New config items: + - FishingTackleInfo: true / FALSE [default] + - TackleBoxAttach: true / FALSE [default] + - TackleBoxCoordinates: [x, y] + - ProbMaxFish: 10 [maximum number of probabilities to list] +- Added code from "Don't Eat This" mod by [Pyrohead37]. Module hasn't been updated since 2019. + - New config items, loaded in this order: + - DontEatThat: true / FALSE [default] + - DontEatCategories: Which categories of items NOT to eat. Defaults are: + - Artisan Goods + - Animal Product + - Crop + - Fish + - Flower + - Harmful + - Vegetable + - DontEat: Which specific ITEMS not to eat. It's okay if they overlap categories. Defaults: + - Holly + - Oil + - Red Mushroom + - Sap + - Truffle + - DoEat: Which specific ITEMS to ALLOW eating. These are actually _removed_ from the "don't eat" list that was compiled from the above entries. Defaults: + - Mayonnaise + - Beer + - Green Tea +- Removed heaps of antiquated code from SdV 1.3/1.4 [Hackswell] +- May still contain inefficient algorithms. Still need to modernize some of the loops with "newly" available methods. + ## 1.4.9 - Updated build files to work with net5.0 From 094f95c5f8ed61c6309f6dc4b437194b226cf4fd Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:25:56 -0400 Subject: [PATCH 16/29] [Hackswell] Re-ordered some small blocks of code. Moved GetAnimalList() into AnimalAutomation. Seed Spots now work. Changed frequency of JoE actions to once every 6 ticks (shorter than the previous 8 ticks). Now actions are approx ever 0.10 second. --- .../Automation/AnimalAutomation.cs | 32 ++++++++++++--- JoysOfEfficiency/Automation/FarmCleaner.cs | 2 +- .../EventHandler/ArtifactSpotDigger.cs | 16 ++++---- JoysOfEfficiency/EventHandler/UpdateEvents.cs | 41 ++++++++----------- JoysOfEfficiency/Utils/Util.cs | 20 --------- 5 files changed, 55 insertions(+), 56 deletions(-) diff --git a/JoysOfEfficiency/Automation/AnimalAutomation.cs b/JoysOfEfficiency/Automation/AnimalAutomation.cs index d681936..aa21e34 100644 --- a/JoysOfEfficiency/Automation/AnimalAutomation.cs +++ b/JoysOfEfficiency/Automation/AnimalAutomation.cs @@ -110,17 +110,17 @@ public static void PetNearbyAnimals() { int radius = Config.AutoPetRadius * Game1.tileSize; Rectangle bb = Util.Expand(Game1.player.GetBoundingBox(), radius); - foreach (FarmAnimal animal in Util.GetAnimalsList(Game1.player)) + foreach (FarmAnimal animal in GetAnimalsList(Game1.player)) { - if (!bb.Contains((int) animal.Position.X, (int) animal.Position.Y) || animal.wasPet.Value) + if (Game1.timeOfDay >= 1900 && !animal.isMoving()) { continue; } - - if (Game1.timeOfDay >= 1900 && !animal.isMoving()) + if (!bb.Contains((int) animal.Position.X, (int) animal.Position.Y) || animal.wasPet.Value) { continue; } + Logger.Log($"Petted {animal.displayType}'{animal.Name}' @{animal.position}"); animal.pet(Game1.player); } @@ -130,7 +130,7 @@ public static void ShearingAndMilking(Farmer player) { int radius = InstanceHolder.Config.AnimalHarvestRadius * Game1.tileSize; Rectangle bb = Util.Expand(player.GetBoundingBox(), radius); - foreach (FarmAnimal animal in Util.GetAnimalsList(player)) + foreach (FarmAnimal animal in GetAnimalsList(player)) { string lowerType = animal.type.Value.ToLower(); if (animal.currentProduce.Value is null || animal.isBaby() || @@ -180,5 +180,27 @@ private static bool WasPetToday(Pet pet) return pet.lastPetDay.ContainsKey(Game1.player.UniqueMultiplayerID) && pet.lastPetDay[Game1.player.UniqueMultiplayerID] == Game1.Date.TotalDays; } + + + private static IEnumerable GetAnimalsList(Character player) + { + HashSet list = new HashSet(); + switch (player.currentLocation) + { + case Farm farm: + { + list.IntersectWith(farm.animals.Values); + break; + } + + case AnimalHouse house: + { + list.IntersectWith(house.animals.Values); + break; + } + } + return list; + } + } } diff --git a/JoysOfEfficiency/Automation/FarmCleaner.cs b/JoysOfEfficiency/Automation/FarmCleaner.cs index 31a9a3f..54ada8c 100644 --- a/JoysOfEfficiency/Automation/FarmCleaner.cs +++ b/JoysOfEfficiency/Automation/FarmCleaner.cs @@ -17,7 +17,7 @@ internal class FarmCleaner private static readonly Logger Logger = new Logger("FarmCleaner"); - public static void OnEighthUpdate() + public static void OnSixthUpdate() { GameLocation farm = Game1.currentLocation; if (!(farm is Farm || farm is IslandWest)) diff --git a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs index f6562af..9541288 100644 --- a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs +++ b/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs @@ -11,19 +11,19 @@ internal class ArtifactSpotDigger { private static Config Config => InstanceHolder.Config; private static readonly Logger Logger = new Logger("ArtifactSpotDigger"); + private static Farmer player = Game1.player; public static void DigNearbyArtifactSpots() { - Farmer player = Game1.player; int radius = Config.AutoDigRadius; Hoe hoe = Util.FindToolFromInventory(player, InstanceHolder.Config.FindHoeFromInventory); - GameLocation location = player.currentLocation; if (hoe == null) { return; } bool flag = false; + GameLocation location = player.currentLocation; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) @@ -40,6 +40,7 @@ public static void DigNearbyArtifactSpots() if (location.Objects[loc].name == "Artifact Spot") { Logger.Log($"ArtifactSpot: {location.Objects[loc].name} at [{loc.X},{loc.Y}]"); + location.digUpArtifactSpot(x, y, player); location.Objects.Remove(loc); location.terrainFeatures.Add(loc, new HoeDirt()); @@ -48,11 +49,12 @@ public static void DigNearbyArtifactSpots() else if (location.Objects[loc].name == "Seed Spot") { Logger.Log($"SeedSpot: {location.Objects[loc].name} at [{loc.X},{loc.Y}]"); -// location.performUseAction(location); -// location.performToolAction(hoe, x, y); -// hoe.DoFunction(location, x, y, 1, player); -// location.Objects.Remove(loc); -// location.terrainFeatures.Add(loc, new HoeDirt()); + + // Liberated this from Pathoschild's "TractorMod" + player.lastClick = (loc * Game1.tileSize) + new Vector2(Game1.tileSize / 2f); + hoe.swingTicker++; + hoe.DoFunction(location, (int)player.lastClick.X, (int)player.lastClick.Y, 0, player); + flag = true; } } } diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/JoysOfEfficiency/EventHandler/UpdateEvents.cs index bfa42b2..6b03776 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/JoysOfEfficiency/EventHandler/UpdateEvents.cs @@ -24,12 +24,13 @@ internal class UpdateEvents private static readonly Logger Logger = new Logger("UpdateEvent"); + // This updates every GameTick (approx 60x / second) public void OnGameUpdateEvent(object sender, UpdateTickedEventArgs args) { OnEveryUpdate(); - if (args.IsMultipleOf(8)) + if (args.IsMultipleOf(6)) { - OnGameEighthUpdate(); + OnGameSixthUpdate(); } } @@ -57,9 +58,10 @@ public void OnEveryUpdate() GiftInformationTooltip.UpdateTooltip(); } - private void OnGameEighthUpdate() + // Every sixth tick. Approx 0.10 seconds + private void OnGameSixthUpdate() { - if (Game1.currentGameTime == null) + if (Game1.currentGameTime == null || !Context.IsWorldReady || !Context.IsPlayerFree) { return; } @@ -69,42 +71,36 @@ private void OnGameEighthUpdate() InventoryAutomation.TryCloseItemGrabMenu(menu); } - if (!Context.IsWorldReady || !Context.IsPlayerFree) - { - return; - } - Farmer player = Game1.player; GameLocation location = Game1.currentLocation; try { - if (Conf.AutoReelRod) + if (Game1.currentLocation is MineShaft { isFallingDownShaft: true }) { - AutoFisher.AutoReelRod(); - } - if (Game1.currentLocation is MineShaft shaft) - { - if (shaft.isFallingDownShaft) - { - return; - } + return; } if (!Context.CanPlayerMove) { return; } - if (Conf.UnifyFlowerColors) + if (Conf.AutoReelRod) { - FlowerColorUnifier.UnifyFlowerColors(); + AutoFisher.AutoReelRod(); } - _ticks = (_ticks + 1) % 8; + // Balanced mode tries to keep JoE actions to once every 1.0 second + _ticks = (_ticks + 1) % 6; if (Conf.BalancedMode && _ticks != 0) { return; } - FarmCleaner.OnEighthUpdate(); + + FarmCleaner.OnSixthUpdate(); + if (Conf.UnifyFlowerColors) + { + FlowerColorUnifier.UnifyFlowerColors(); + } if (Conf.AutoEat) { FoodAutomation.TryToEatIfNeeded(player); @@ -121,7 +117,6 @@ private void OnGameEighthUpdate() { AnimalAutomation.PetNearbyAnimals(); } - if (Conf.AutoShearingAndMilking) { AnimalAutomation.ShearingAndMilking(player); diff --git a/JoysOfEfficiency/Utils/Util.cs b/JoysOfEfficiency/Utils/Util.cs index 246e291..72b6f99 100644 --- a/JoysOfEfficiency/Utils/Util.cs +++ b/JoysOfEfficiency/Utils/Util.cs @@ -70,26 +70,6 @@ public static void ShowHudMessageTranslated(string key, int duration = 3500) ShowHudMessage(Translation.Get(key), duration); } - public static IEnumerable GetAnimalsList(Character player) - { - List list = new List(); - switch (player.currentLocation) - { - case Farm farm: - { - list.AddRange(farm.animals.Values); - break; - } - - case AnimalHouse house: - { - list.AddRange(house.animals.Values); - break; - } - } - return list; - } - public static Rectangle Expand(Rectangle rect, int radius) { return new Rectangle(rect.Left - radius, rect.Top - radius, 2 * radius, 2 * radius); From 4cdf6b4862d008532e669a3dd099362e6dd81b70 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Thu, 25 Apr 2024 08:39:58 -0400 Subject: [PATCH 17/29] [Hackswell] Reworked timing/tick handling. Now configurable: Balanced Mode [60 ticks] or custom N ticks per JoE update. --- JoysOfEfficiency/Automation/FarmCleaner.cs | 2 +- JoysOfEfficiency/Core/Config.cs | 6 +++-- JoysOfEfficiency/EventHandler/UpdateEvents.cs | 26 +++++++------------ JoysOfEfficiency/FeaturesAndConfigs.md | 5 +++- JoysOfEfficiency/Menus/JoeMenu.cs | 3 ++- JoysOfEfficiency/WhatsNew.md | 1 + JoysOfEfficiency/i18n/default.json | 4 ++- JoysOfEfficiency/i18n/es.json | 4 ++- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/JoysOfEfficiency/Automation/FarmCleaner.cs b/JoysOfEfficiency/Automation/FarmCleaner.cs index 54ada8c..3bcccc9 100644 --- a/JoysOfEfficiency/Automation/FarmCleaner.cs +++ b/JoysOfEfficiency/Automation/FarmCleaner.cs @@ -17,7 +17,7 @@ internal class FarmCleaner private static readonly Logger Logger = new Logger("FarmCleaner"); - public static void OnSixthUpdate() + public static void OnNthTickUpdate() { GameLocation farm = Game1.currentLocation; if (!(farm is Farm || farm is IslandWest)) diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index def6d89..f9bd1fb 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -8,7 +8,8 @@ namespace JoysOfEfficiency.Core { internal class Config { - + public bool BalancedMode { get; set; } = true; + public uint RunEveryNthTick { get; set; } = 15; // If BalancedMode is False, then run every 15th tick by default (0.25 seconds) public bool SafeMode { get; set; } = false; public bool MineInfoGui { get; set; } = true; @@ -97,7 +98,6 @@ internal class Config public bool AutoShakeFruitedPlants { get; set; } = true; public int AutoShakeRadius { get; set; } = 1; - public bool BalancedMode { get; set; } = true; public bool AutoDepositIngredient { get; set; } = false; public bool AutoDepositSeedMaker { get; set; } = false; @@ -109,6 +109,7 @@ internal class Config "Anvil", "Bait Maker", "Bee House", + "Bone Mill", "Cask", "Charcoal Kiln", "Cheese Press", @@ -138,6 +139,7 @@ internal class Config "Statue Of Endless Fortune", "Statue Of Perfection", "Tapper", + "Wood Chipper", "Worm Bin", }; diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/JoysOfEfficiency/EventHandler/UpdateEvents.cs index 6b03776..9a3afc4 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/JoysOfEfficiency/EventHandler/UpdateEvents.cs @@ -17,20 +17,21 @@ internal class UpdateEvents { public static bool DayEnded { get; set; } - private int _ticks; - - private static Config Conf => InstanceHolder.Config; private static readonly Logger Logger = new Logger("UpdateEvent"); + // Run Every Nth tick... unless balanced mode, then it's 60 ticks (1 second) + private uint NthTick = (Conf.BalancedMode) ? 60 : Conf.RunEveryNthTick; + // This updates every GameTick (approx 60x / second) public void OnGameUpdateEvent(object sender, UpdateTickedEventArgs args) { OnEveryUpdate(); - if (args.IsMultipleOf(6)) + if (args.IsMultipleOf(NthTick)) { - OnGameSixthUpdate(); + OnGameNthTickUpdate(); + NthTick = (Conf.BalancedMode) ? 60 : Conf.RunEveryNthTick; // Update in case config has changed... } } @@ -58,14 +59,13 @@ public void OnEveryUpdate() GiftInformationTooltip.UpdateTooltip(); } - // Every sixth tick. Approx 0.10 seconds - private void OnGameSixthUpdate() + // Every Nth tick. Default is 15. 60 == 1.00 seconds; 15 == 0.25 seconds; 6 == 0.10 seconds. + private void OnGameNthTickUpdate() { if (Game1.currentGameTime == null || !Context.IsWorldReady || !Context.IsPlayerFree) { return; } - if (Conf.CloseTreasureWhenAllLooted && Game1.activeClickableMenu is ItemGrabMenu menu) { InventoryAutomation.TryCloseItemGrabMenu(menu); @@ -88,15 +88,7 @@ private void OnGameSixthUpdate() AutoFisher.AutoReelRod(); } - // Balanced mode tries to keep JoE actions to once every 1.0 second - _ticks = (_ticks + 1) % 6; - if (Conf.BalancedMode && _ticks != 0) - { - return; - } - - - FarmCleaner.OnSixthUpdate(); + FarmCleaner.OnNthTickUpdate(); if (Conf.UnifyFlowerColors) { FlowerColorUnifier.UnifyFlowerColors(); diff --git a/JoysOfEfficiency/FeaturesAndConfigs.md b/JoysOfEfficiency/FeaturesAndConfigs.md index d73fdcf..ab16593 100644 --- a/JoysOfEfficiency/FeaturesAndConfigs.md +++ b/JoysOfEfficiency/FeaturesAndConfigs.md @@ -41,6 +41,7 @@ AutoDigArtifactSpot, AutoDepositIngredient, and AutoPullMachineResult.*** **[CONFIG]** - BalancedMode("Automation" bool, default:true) - whether this utility is enabled. +- RunEveryNthTick("General" uint, default:15) - Run JoE timing loops every Nth tick (1 tick == 1/60 second). ## Mine Info GUI With this utility, you can check how many stones left, and monster kills tally counter, and whether ladder has spawned in mines. @@ -192,6 +193,7 @@ This utility will try to pull results from nearby machines and give it to the fa - "Anvil", "Bait Maker", "Bee House", + - "Bone Mill", "Cask", "Charcoal Kiln", "Cheese Press", @@ -221,7 +223,8 @@ This utility will try to pull results from nearby machines and give it to the fa "Statue Of Endless Fortune", "Statue Of Perfection", "Tapper", - "Worm Bin" + - "Wood Chipper", + "Worm Bin", ## Auto Pet Nearby Pets Oh, seriously you want to pet pets automatically? diff --git a/JoysOfEfficiency/Menus/JoeMenu.cs b/JoysOfEfficiency/Menus/JoeMenu.cs index b75a178..fda0d0c 100644 --- a/JoysOfEfficiency/Menus/JoeMenu.cs +++ b/JoysOfEfficiency/Menus/JoeMenu.cs @@ -85,6 +85,7 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Balanced Mode")); tab.AddOptionsElement(new ModifiedCheckBox("BalancedMode", 20, Config.BalancedMode, OnCheckboxValueChanged)); + tab.AddOptionsElement(new ModifiedSlider("EveryNthTick", 20, (int)Config.RunEveryNthTick, 5, 60, OnSliderValueChanged, () => Config.BalancedMode)); tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Auto Water Nearby Crops")); @@ -163,7 +164,6 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new ModifiedCheckBox("AutoLootTreasures", 30, Config.AutoLootTreasures, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedCheckBox("CloseTreasureWhenAllLooted", 31, Config.CloseTreasureWhenAllLooted, OnCheckboxValueChanged)); - tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Auto Pick Up Trash")); tab.AddOptionsElement(new ModifiedCheckBox("AutoPickUpTrash", 34, Config.AutoPickUpTrash, OnCheckboxValueChanged)); @@ -404,6 +404,7 @@ private void OnSliderValueChanged(int index, int value) case 17: Config.ThrowPower = value / 10.0f; break; case 18: Config.ThresholdStaminaPercentage = value; break; case 19: Config.ProbBoxMaxFish = value; break; + case 20: Config.RunEveryNthTick = (uint)value; break; default: return; } diff --git a/JoysOfEfficiency/WhatsNew.md b/JoysOfEfficiency/WhatsNew.md index 91c3add..9616be3 100644 --- a/JoysOfEfficiency/WhatsNew.md +++ b/JoysOfEfficiency/WhatsNew.md @@ -10,6 +10,7 @@ This is a changelog from 1.5.0 - Added new config item "MachineTypes" in config.json. [Hackswell] - All machines are enumerated by default now, and up to date as of SdV 1.6.4. - If a new machine is added to SdV, you can manually add the name to the list. No need to recompile JoE! +- Added new config item "RunEveryNthTick". If BalancedMode is FALSE, then run the JoE loops every "RunEveryNthTick"/60.0 seconds. - Updated some of the Fishing HUDs and probability code. [Sandman534] - New config items: - FishingTackleInfo: true / FALSE [default] diff --git a/JoysOfEfficiency/i18n/default.json b/JoysOfEfficiency/i18n/default.json index 7d95e6a..2e87032 100644 --- a/JoysOfEfficiency/i18n/default.json +++ b/JoysOfEfficiency/i18n/default.json @@ -48,7 +48,8 @@ "options.AutoShearingAndMilking": "Auto-shear/milk mature sheep/cows", "options.AutoWaterNearbyCrops": "Automatic Watering to crops", "options.AutoWaterRadius": "How far tiles to be watered", - "options.BalancedMode": "Toggle Balanced Mode", + "options.BalancedMode": "Balanced Mode (JoE once per second limit)", + "options.EveryNthTick": "Update Every Nth Tick", "options.CloseTreasureWhenAllLooted": "Close treasure box when all items taken", "options.CollectLetterAttachmentsAndQuests": "Auto-accept quests or item attached to mail", "options.CPUThresholdFishing": "How often AI operates bar", @@ -61,6 +62,7 @@ "options.FishInfo": "Draw fish information box", "options.FishingInfo": "Draw fish information box", "options.FishingProbabilitiesInfo": "Draw probabilities of fishing", + "options.ThresholdStaminaPercentage": "Percent Stamina Threshold", "options.GiftInformation": "Shows Gift Information Tooltips", "options.HealthToEatRatio": "Health Threshold to auto-eat", "options.IdleTimeout": "Idle timeout for pausing the game", diff --git a/JoysOfEfficiency/i18n/es.json b/JoysOfEfficiency/i18n/es.json index bf541e2..d1e0d42 100644 --- a/JoysOfEfficiency/i18n/es.json +++ b/JoysOfEfficiency/i18n/es.json @@ -38,6 +38,7 @@ "options.AutoWaterNearbyCrops": "Riego automático a cultivos", "options.AutoWaterRadius": "Baldosas para regar", "options.BalancedMode": "Alternar el modo balanceado", + "options.EveryNthTick": "Actualizar cada N Ticks", "options.CloseTreasureWhenAllLooted": "Cerrar la caja del tesoro cuando haya robado todo", "options.CPUThresholdFishing": "Con qué frecuencia AI opera la barra", "options.CraftingFromChests": "Artesanías de los cofres cercanos", @@ -65,6 +66,7 @@ "options.ScavengingRadius": "Qué tan lejos las baldosas para buscarlo", "options.StaminaToEatRatio": "Resistencia para comer auto", "options.UnifyFlowerColors": "Unificar los colores de las flores", + "options.DontEatThat": "Habilitar 'No Comas Eso(tm)'", "quality.gold": "Oro", "quality.iridium": "Iridium", "quality.normal": "Normal", @@ -86,4 +88,4 @@ "taste.love.male": "Él ama este regalo", "taste.neutral.female": "Ella tiene un sentimiento neutral acerca de este regalo", "taste.neutral.male": "Él tiene un sentimiento neutral acerca de este regalo" -} \ No newline at end of file +} From 53e2a8956a85e2e5ed12723d50004867dd428cbe Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Thu, 25 Apr 2024 13:00:14 -0400 Subject: [PATCH 18/29] [Hackswell] Streamlined Utils.GetObjectsWithin(). Changed some configuration types to HashSet from List. Double the amount of resources from FarmAnimals if they have eaten an AnimalCracker. --- JoysOfEfficiency/Automation/AnimalAutomation.cs | 2 +- JoysOfEfficiency/Core/Config.cs | 4 ++-- JoysOfEfficiency/Utils/Util.cs | 11 ++++------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/JoysOfEfficiency/Automation/AnimalAutomation.cs b/JoysOfEfficiency/Automation/AnimalAutomation.cs index aa21e34..a0b3b47 100644 --- a/JoysOfEfficiency/Automation/AnimalAutomation.cs +++ b/JoysOfEfficiency/Automation/AnimalAutomation.cs @@ -146,7 +146,7 @@ public static void ShearingAndMilking(Farmer player) if (!player.addItemToInventoryBool( new StardewValley.Object(animal.currentProduce.Value, - 1, + animal.hasEatenAnimalCracker.Value ? 2 : 1, false, -1, animal.produceQuality.Value))) diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index f9bd1fb..a8e72fd 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -81,7 +81,7 @@ internal class Config public bool AutoHarvest { get; set; } = true; public int AutoHarvestRadius { get; set; } = 1; public bool ProtectNectarProducingFlower { get; set; } = true; - public List HarvestException { get; set; } = new List(); + public HashSet HarvestException { get; set; } = new HashSet(); public SButton ButtonToggleBlackList { get; set; } = Keys.F2.ToSButton(); public bool AutoDestroyDeadCrops { get; set; } = true; @@ -104,7 +104,7 @@ internal class Config public bool AutoPullMachineResult { get; set; } = true; public int MachineRadius { get; set; } = 1; - public List MachineTypes { get; set; } = new List() + public HashSet MachineTypes { get; set; } = new HashSet() { "Anvil", "Bait Maker", diff --git a/JoysOfEfficiency/Utils/Util.cs b/JoysOfEfficiency/Utils/Util.cs index 72b6f99..be1dcb1 100644 --- a/JoysOfEfficiency/Utils/Util.cs +++ b/JoysOfEfficiency/Utils/Util.cs @@ -154,9 +154,10 @@ public static T FindToolFromInventory(Player player, bool findFromInventory) public static List GetObjectsWithin(int radius, bool ignoreBalancedMode = false) where T : SVObject { + List list = new List(); if (!Context.IsWorldReady || currentLocation?.Objects == null) { - return new List(); + return list; } if (InstanceHolder.Config.BalancedMode && !ignoreBalancedMode) { @@ -165,16 +166,12 @@ public static List GetObjectsWithin(int radius, bool ignoreBalancedMode = GameLocation location = player.currentLocation; Vector2 ov = player.Tile; - List list = new List(); for (int dx = -radius; dx <= radius; dx++) { for (int dy = -radius; dy <= radius; dy++) { - Vector2 loc = ov + new Vector2(dx, dy); - if (location.Objects.ContainsKey(loc) && location.Objects[loc] is T t) - { - list.Add(t); - } + location.Objects.TryGetValue(ov + new Vector2(dx, dy), out Object obj); + if (obj is T t) list.Add(t); } } return list; From c21856a90e0cec10ec143b14f537a75077d0ed62 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Fri, 26 Apr 2024 08:22:33 -0400 Subject: [PATCH 19/29] [Hackswell] Alpha5: Fixed auto-petting bug. --- JoysOfEfficiency/Automation/AnimalAutomation.cs | 5 +++-- JoysOfEfficiency/manifest.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/JoysOfEfficiency/Automation/AnimalAutomation.cs b/JoysOfEfficiency/Automation/AnimalAutomation.cs index a0b3b47..5799ead 100644 --- a/JoysOfEfficiency/Automation/AnimalAutomation.cs +++ b/JoysOfEfficiency/Automation/AnimalAutomation.cs @@ -6,6 +6,7 @@ using StardewValley; using StardewValley.Buildings; using StardewValley.Characters; +using StardewValley.Extensions; using StardewValley.Tools; namespace JoysOfEfficiency.Automation @@ -189,13 +190,13 @@ private static IEnumerable GetAnimalsList(Character player) { case Farm farm: { - list.IntersectWith(farm.animals.Values); + list.AddRange(farm.animals.Values); break; } case AnimalHouse house: { - list.IntersectWith(house.animals.Values); + list.AddRange(house.animals.Values); break; } } diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 0e63c0c..925ca9d 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -6,5 +6,5 @@ "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.5.0-unofficial.4-Hackswell" + "Version": "1.5.0-unofficial.ALPHA5-Hackswell" } From 54575ea7d25c2bf22aaf2997763c7e8416111833 Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:53:45 -0700 Subject: [PATCH 20/29] Updated Feature and Config --- JoysOfEfficiency/FeaturesAndConfigs.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/JoysOfEfficiency/FeaturesAndConfigs.md b/JoysOfEfficiency/FeaturesAndConfigs.md index ab16593..d247e99 100644 --- a/JoysOfEfficiency/FeaturesAndConfigs.md +++ b/JoysOfEfficiency/FeaturesAndConfigs.md @@ -239,10 +239,19 @@ This utility let you know what fish could be caught (and estimated probability o **[CONFIG]** - FishingProbabilitiesInfo("UIs", bool, default:false) - whether this utility is enabled. +- ProbBoxMaxFish("UIs", int, default:10 min:5 max:25) - How many fish to show per column. - ProbBoxCoordinates("UIs", Point, default:[100,400]) - Top-left coordinates of the window. - MorePreciseProbabilities("UIs", bool, default:true) - Displays more plactical and precise probabiilities. - TrialOfExamine("UIs", int, default:10 min:1 max:50) - Trial number of computing probabilities. +## Fishing Tackle Info +This utility lets you know what type of bait and bobber you have equipped, and how many uses you have left. + +**[CONFIG]** +- FishingTackleInfo("UIs", bool, default:false) - whether this utility is enabled. +- TackleBoxAttach("UIs", bool, default:false) - Attaches the tackle info window to fishing probabilites. +- TackleBoxCoordinates("UIs", Point, default:[40,500]) - Top-left coordinates of the window. + ## Show Shipping Price This utility shows estimated total shipping price when you opened shipping box. From 1c1d8062c9f00c4ca7240161d329a428bcae348d Mon Sep 17 00:00:00 2001 From: Mimodin Date: Wed, 1 May 2024 21:04:39 +0200 Subject: [PATCH 21/29] Add option to harvest slime balls --- JoysOfEfficiency/Automation/HarvestAutomation.cs | 10 ++++++++++ JoysOfEfficiency/Core/Config.cs | 1 + JoysOfEfficiency/EventHandler/UpdateEvents.cs | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/JoysOfEfficiency/Automation/HarvestAutomation.cs index 3b2983f..ffc87ed 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/JoysOfEfficiency/Automation/HarvestAutomation.cs @@ -93,6 +93,16 @@ public static void HarvestNearbyCrops(Farmer player) } } + public static void HarvestNearbySlimeBalls(Farmer player) + { + int radius = Config.AutoHarvestRadius; + + foreach (SVObject obj in Util.GetObjectsWithin(radius).Where(obj => obj.QualifiedItemId == "(BC)56")) + { + obj.checkForAction(player); + } + } + public static void WaterNearbyCrops() { WateringCan can = Util.FindToolFromInventory(Game1.player, InstanceHolder.Config.FindCanFromInventory); diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index a8e72fd..df8a643 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -79,6 +79,7 @@ internal class Config public bool AutoHarvest { get; set; } = true; + public bool AutoHarvestSlimeBalls { get; set; } = true; public int AutoHarvestRadius { get; set; } = 1; public bool ProtectNectarProducingFlower { get; set; } = true; public HashSet HarvestException { get; set; } = new HashSet(); diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/JoysOfEfficiency/EventHandler/UpdateEvents.cs index 9a3afc4..ea4c005 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/JoysOfEfficiency/EventHandler/UpdateEvents.cs @@ -125,6 +125,10 @@ private void OnGameNthTickUpdate() { HarvestAutomation.HarvestNearbyCrops(player); } + if (Conf.AutoHarvestSlimeBalls) + { + HarvestAutomation.HarvestNearbySlimeBalls(player); + } if (Conf.AutoDestroyDeadCrops) { HarvestAutomation.DestroyNearDeadCrops(player); From fa755fb7b5af7e7b27632ff82882a1bb10009ab4 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Thu, 2 May 2024 17:10:00 -0400 Subject: [PATCH 22/29] [Hackswell] Add new config option 'TrashDisgustsNPCs'. Set to true by default. --- JoysOfEfficiency/Automation/TrashCanScavenger.cs | 4 +++- JoysOfEfficiency/Core/Config.cs | 1 + JoysOfEfficiency/Menus/JoeMenu.cs | 2 ++ JoysOfEfficiency/manifest.json | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/JoysOfEfficiency/Automation/TrashCanScavenger.cs b/JoysOfEfficiency/Automation/TrashCanScavenger.cs index 416f8a8..f23a47b 100644 --- a/JoysOfEfficiency/Automation/TrashCanScavenger.cs +++ b/JoysOfEfficiency/Automation/TrashCanScavenger.cs @@ -8,6 +8,8 @@ namespace JoysOfEfficiency.Automation { internal class TrashCanScavenger { + private static Config Config => InstanceHolder.Config; + public static void ScavengeTrashCan() { if (!(Game1.currentLocation is Town town)) @@ -30,7 +32,7 @@ public static void ScavengeTrashCan() if (layer.Tiles[x, y]?.TileIndex == 78) { string whichGarbage = Game1.currentLocation.doesTileHaveProperty(x, y, "Action", "Buildings"); - town.CheckGarbage(whichGarbage, new Vector2(x, y), Game1.player, true, true); + town.CheckGarbage(whichGarbage, new Vector2(x, y), Game1.player, true, Config.GarbageDisgustsNPCs); } } } diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index df8a643..b7f7a76 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -175,6 +175,7 @@ internal class Config public int PauseNotificationY { get; set; } = 700; public bool AutoPickUpTrash { get; set; } = false; + public bool GarbageDisgustsNPCs { get; set; } = true; public int ScavengingRadius { get; set; } = 2; public bool AutoShearingAndMilking { get; set; } = true; diff --git a/JoysOfEfficiency/Menus/JoeMenu.cs b/JoysOfEfficiency/Menus/JoeMenu.cs index fda0d0c..e20b19f 100644 --- a/JoysOfEfficiency/Menus/JoeMenu.cs +++ b/JoysOfEfficiency/Menus/JoeMenu.cs @@ -167,6 +167,7 @@ internal JoeMenu(int width, int height) tab.AddOptionsElement(new EmptyLabel()); tab.AddOptionsElement(new LabelComponent("Auto Pick Up Trash")); tab.AddOptionsElement(new ModifiedCheckBox("AutoPickUpTrash", 34, Config.AutoPickUpTrash, OnCheckboxValueChanged)); + tab.AddOptionsElement(new ModifiedCheckBox("GarbageDisgustsNPCs", 46, Config.GarbageDisgustsNPCs, OnCheckboxValueChanged)); tab.AddOptionsElement(new ModifiedSlider("ScavengingRadius", 13, Config.ScavengingRadius, 1, 3, OnSliderValueChanged, () => !Config.AutoPickUpTrash || Config.BalancedMode)); tab.AddOptionsElement(new EmptyLabel()); @@ -378,6 +379,7 @@ private void OnCheckboxValueChanged(int index, bool value) case 43: Config.FishingTackleInfo = value; break; case 44: Config.TackleBoxAttach = value; break; case 45: Config.DontEatThat = value; break; + case 46: Config.GarbageDisgustsNPCs = value; break; default: return; } InstanceHolder.WriteConfig(); diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 925ca9d..7031141 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -6,5 +6,5 @@ "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.5.0-unofficial.ALPHA5-Hackswell" + "Version": "1.5.0-unofficial.6-Hackswell" } From 586ccf4e899440c21f34bd7e334540f1662c5ec4 Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Mon, 6 May 2024 06:33:15 -0700 Subject: [PATCH 23/29] Tons of work on Fish Probabilities --- .../Huds/FishingProbabilitiesBox.cs | 675 ++++++++++-------- 1 file changed, 365 insertions(+), 310 deletions(-) diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index 6a5b668..83aca38 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -1,36 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Text.Json; -using System.Linq; -using System.Text.RegularExpressions; using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; -using StardewValley.GameData.LocationContexts; +using StardewValley.GameData; using StardewValley.GameData.Locations; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Tools; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; using xTile.Dimensions; using Game1 = StardewValley.Game1; using Object = StardewValley.Object; using Rectangle = Microsoft.Xna.Framework.Rectangle; -using System.Net.Mail; -using static System.Net.Mime.MediaTypeNames; -using System.Xml; -using StardewValley.Buildings; -using Microsoft.VisualBasic; namespace JoysOfEfficiency.Huds { public class FishingProbabilitiesBox { - private static readonly Logger Logger = new Logger("FishingProbabilitiesInfo"); - - private static Dictionary _fishingDictionary; - private static Dictionary _attachmentDictionary; + private static Dictionary _fishingDictionary; + private static Dictionary _attachmentDictionary; private static bool _isFirstTimeOfFishing = true; @@ -43,18 +34,25 @@ public static void UpdateProbabilities(FishingRod rod) // Only run the probablies once when line is cast _isFirstTimeOfFishing = false; - // Get water depth + // Game Location GameLocation location = Game1.currentLocation; - Rectangle rectangle = new Rectangle(location.fishSplashPoint.X * 64, location.fishSplashPoint.Y * 64, 64, 64); - Rectangle value = new Rectangle((int)rod.bobber.X - 80, (int)rod.bobber.Y - 80, 64, 64); + + // Water Depth + Rectangle rectangle = new(location.fishSplashPoint.X * 64, location.fishSplashPoint.Y * 64, 64, 64); + Rectangle value = new((int)rod.bobber.X - 80, (int)rod.bobber.Y - 80, 64, 64); bool flag = rectangle.Intersects(value); int clearWaterDistance = rod.clearWaterDistance; - // Populate dictionaries - _fishingDictionary = GetFishes(location, rod.HasMagicBait() ,rod.attachments[0]?.ParentSheetIndex ?? -1, clearWaterDistance + (flag ? 1 : 0), Game1.player, InstanceHolder.Config.MorePreciseProbabilities ? InstanceHolder.Config.TrialOfExamine : 1); + // Bobber Location + Vector2 vector = new(rod.bobber.X / 64f, rod.bobber.Y / 64f); + + // Populate Fish and Tackle + _fishingDictionary = GetFishes(location, vector, clearWaterDistance + (flag ? 1 : 0), Game1.player, rod, InstanceHolder.Config.MorePreciseProbabilities ? InstanceHolder.Config.TrialOfExamine : 1); _attachmentDictionary = GetAttachments(rod); } } + + // Clear out lists when not fishing else { _isFirstTimeOfFishing = true; @@ -65,316 +63,376 @@ public static void UpdateProbabilities(FishingRod rod) public static void PrintFishingInfo() { + // Draw Fishing Window int x_pos_add = 0; if (InstanceHolder.Config.FishingProbabilitiesInfo && _fishingDictionary != null) x_pos_add = DrawProbBox(_fishingDictionary); + // Draw Tackle Window if (InstanceHolder.Config.FishingTackleInfo && _attachmentDictionary != null && _attachmentDictionary.Count > 0) DrawTackleBox(_attachmentDictionary, x_pos_add); - } - private static Dictionary GetAttachments(FishingRod rod) + private static Dictionary GetAttachments(FishingRod rod) { - Dictionary dictList = new Dictionary(); + Dictionary dictList = new(); - // If no attachments, return null set - if (rod.attachments.Count == 0) return null; + // Get Bait and Tackle from Rod + Object baitObject = rod.GetBait(); + List tackleObjects = rod.GetTackle(); - // Loop through attachments - for (int i = 0; i < rod.attachments.Count; i++) - { - int rodIndex = rod.attachments[i]?.ParentSheetIndex ?? -1; - if (rodIndex > -1) - { - // Bait vs Tackle - if (i == 0) - dictList[rod.attachments[i].QualifiedItemId] = rod.attachments[i].Stack; - else - dictList[rod.attachments[i].QualifiedItemId] = FishingRod.maxTackleUses - rod.attachments[i].uses.Value; - } - } + // Add Bait + if (baitObject != null) + dictList[baitObject.QualifiedItemId] = baitObject.Stack; + + // Add Tackle + foreach (Object tackle in tackleObjects) + if (tackle != null) + dictList[tackle.QualifiedItemId] = FishingRod.maxTackleUses - tackle.uses.Value; return dictList; } - private static Dictionary GetFishes(GameLocation location, bool magicBait, int bait, int waterDepth, Farmer who, int trial = 1) + private static Dictionary GetFishes(GameLocation location, Vector2 bobbleTile, int waterDepth, Farmer player, FishingRod rod, int trial = 1) { - List> dictList = new List>(); + // Run X amount of trials and get the results + List> dictList = new(); for (int i = 0; i < trial; i++) { - switch (location) - { - case Farm _: - dictList.Add(GetFishesFarm(waterDepth, who, magicBait)); - break; - case MineShaft shaft: - dictList.Add(GetFishesMine(shaft, magicBait, bait, waterDepth, who)); - break; - case Submarine _: - dictList.Add(GetFishesSubmarine()); - break; - default: - dictList.Add(GetFishesGeneric(waterDepth, who, magicBait)); - break; - } + // Mineshaft have to be handled slightly differently + if (location is MineShaft) + dictList.Add(GetFishesMine((MineShaft)location, bobbleTile, waterDepth, player, rod)); + else + dictList.Add(GetFishesGeneric(bobbleTile, waterDepth, player, rod)); } - Dictionary dict = ShuffleAndAverageFishingDictionary(dictList); - Dictionary dict2 = dict.OrderByDescending(x => x.Value).Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value); - double sum = dict2.Sum(kv => kv.Value); - if (1 - sum >= 0.0001) - dict2.Add("168", 1 - sum); - - return dict2; + // Shuffle and get a list of valid items + Dictionary shuffledDict = ShuffleAndAverageFishingDictionary(dictList); + Dictionary fishDict = shuffledDict.OrderByDescending(x => x.Value).Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value); + + // Add in sum of Garbage items if they have a probability + Dictionary garbageDict = shuffledDict.OrderByDescending(x => x.Value).Where(kv => IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value); + double garbageSum = garbageDict.Sum(kv => kv.Value); + if (garbageSum > 0.0001) + fishDict.Add("(O)168", garbageSum); + + // Get probability to 100% + double totalSum = fishDict.Sum(kv => kv.Value); + Dictionary finalDict = fishDict.ToDictionary(x => x.Key, x => x.Value / totalSum); + + return finalDict; } - private static Dictionary GetFishesGeneric(int waterDepth, Farmer who, bool magicBait, string locationName = null) + private static Dictionary GetFishesMine(MineShaft shaft, Vector2 bobbleTile, int waterDepth, Farmer player, FishingRod rod) { - Dictionary dictFish = new Dictionary(); - GameLocation currLocation = Game1.currentLocation; - Season season = Game1.GetSeasonForLocation(currLocation); + Dictionary dict = new Dictionary(); + double p; - // Load all Fish and Locations - Dictionary allFishData = DataLoader.Fish(Game1.content); - Dictionary dictionary = DataLoader.Locations(Game1.content); + // If player is using training rod in mines, return trash + if (rod.QualifiedItemId.Contains("TrainingRod")) + { + dict["(O)167"] = 1; + return dict; + } - // Get Location Data - LocationData thisLocData = Game1.currentLocation.GetData(); - string locName = locationName ?? currLocation.Name; - Logger.Log($"GetFishes: Loc: {locName} ** Season: {season}"); + // Setup initial chance + double num = 1.0; + num += 0.4 * player.FishingLevel; + num += waterDepth * 0.1; - // If the Henchman is gone, and the user has no void mayo, 25% chance to fish it up - if (locName.Equals("WitchSwamp") && !Game1.MasterPlayer.mailReceived.Contains("henchmanGone") && !Game1.player.Items.ContainsId("Void Mayonnaise", 1)) - return new Dictionary { { "308", 0.25 } }; + // Lure Check + if (rod.HasCuriosityLure()) + num += 5.0; - // Show all available fishes - if (Game1.debugMode) + // Target Bait Check + string textTarget = rod.GetBait()?.Name ?? ""; + + // Add specific fish based on mine level + int level = shaft.getMineArea(); + switch (level) { - String JSONFishes = JsonSerializer.Serialize(allFishData, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"All Fishes: {JSONFishes}"); - } - - // Get all possible fish in the area - IEnumerable possibleFish = dictionary["Default"].Fish; - if (thisLocData != null && thisLocData.Fish?.Count > 0) - possibleFish = possibleFish.Concat(thisLocData.Fish); - - // Debug Location Data - if (Game1.debugMode) { - Logger.Info($"Finding fish area for farmer: {who.Tile.X},{who.Tile.Y} ** {currLocation.locationContextId} ** "); - LocationContextData bubba = currLocation.GetLocationContext(); - String jsonBubba = JsonSerializer.Serialize(bubba, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"GameLocationContext: {jsonBubba}"); + case 0: + case 10: + num += textTarget.Contains("Stonefish") ? 10 : 0; + p = 0.02 + 0.01 * num; + dict.Add("(O)158", p); + break; + case 40: + num += textTarget.Contains("Ice Pip") ? 10 : 0; + p = 0.015 + 0.009 * num; + dict.Add("(O)161", p); + break; + case 80: + num += textTarget.Contains("Lava Eel") ? 10 : 0; + p = 0.01 + 0.008 * num; + dict.Add("(O)162", p); + break; + default: + return dict; } - // Get all fish for the current location - currLocation.TryGetFishAreaForTile(who.Tile, out var fishAreaID, out var fishAreaData); - if (Game1.debugMode) + // Get general fish data on level 10/40, and add Cave Jelly to level 80 + if (level == 10 || level == 40) + return ConcatDictionary(dict, GetFishesGeneric(bobbleTile, waterDepth, player, rod, "UndergroundMine")); + else if (level == 80) { - String jsonFishAreaData = JsonSerializer.Serialize(fishAreaData, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"FishAreaData: {jsonFishAreaData}"); + p = 0.05 + player.LuckLevel * 0.05; + dict.Add("(O)CaveJelly", p); } - // If we are using magic bait, include all seasons - if (magicBait) - possibleFish = from p in possibleFish - orderby p.Precedence, Game1.random.Next() - where (p.FishAreaId == fishAreaID || p.FishAreaId == null) - select p; - else - possibleFish = from p in possibleFish - orderby p.Precedence, Game1.random.Next() - where (p.FishAreaId == fishAreaID || p.FishAreaId == null) && (p.Season == season || p.Season == null) - select p; + return dict; + } + + private static Dictionary GetFishesGeneric(Vector2 bobberTile, int waterDepth, Farmer player, FishingRod rod, string locationName = null) + { + Dictionary dictFish = new(); - // Show all possible fish - if (Game1.debugMode) + // GameData + GameLocation location = Game1.currentLocation; + Dictionary dictionary = DataLoader.Locations(Game1.content); + LocationData locationData = ((location != null) ? location.GetData() : GameLocation.GetData(locationName)); + Dictionary allFishData = DataLoader.Fish(Game1.content); + Season seasonForLocation = Game1.GetSeasonForLocation(location); + + // Get Fish Area for Tile + if (location == null || !location.TryGetFishAreaForTile(bobberTile, out var id, out var _)) + id = null; + + // Magic Bait + bool flagMagicBait = false; // flag + bool hasCuriosityLure = false; + string textTarget = null; + flagMagicBait = rod.HasMagicBait(); + + // Curiosity Lure + hasCuriosityLure = rod.HasCuriosityLure(); + + // Targeted Bait + StardewValley.Object bait = rod.GetBait(); + if (bait?.QualifiedItemId == "(O)SpecificBait" && bait.preservedParentSheetIndex.Value != null) + textTarget = "(O)" + bait.preservedParentSheetIndex.Value; + + // Keys + HashSet ignoreQueryKeys = (flagMagicBait ? GameStateQuery.MagicBaitIgnoreQueryKeys : null); + Point tilePoint = player.TilePoint; + + // Fish Data + IEnumerable enumerable = dictionary["Default"].Fish; + if (locationData != null && locationData.Fish?.Count > 0) + enumerable = enumerable.Concat(locationData.Fish); + + // Add Inherited Locations if found in spawn data + IEnumerable inherited = enumerable.Where(x => x.Id.Contains("LOCATION_FISH")); + foreach (SpawnFishData spawn in inherited) { - String JSON = JsonSerializer.Serialize(possibleFish, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"Possibru Fishu:\n{JSON}"); + string[] inheritedLocation = spawn.Id.Split(' '); + enumerable = enumerable.Concat(dictionary[inheritedLocation[1]].Fish.Where(x => x.CanBeInherited)); } - // Reference: https://stardewvalleywiki.com/Modding:Fish_data#Fish_data_and_spawn_criteria - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 - // "143": "Catfish/ 75/mixed/ 12/72/600 2400/spring fall winter/ rainy/689 .4 680 .1/4/.40/.1/0/true", - // "800": "Blobfish/ 75/floater/8/25/600 2600/spring summer fall winter/both/685 .35/ 3/.40/.1/0/false" - // "701": "Tilapia/ 50/mixed/ 11/30/600 1400/summer fall/ both/683 .35/ 3/.4/.2/0/false", - // "838": "Blue Discus/ 60/dart/ 2/ 9/600 2600/spring summer fall winter/both/685 .35/ 1/.25/.1/0/false", - // "162": "Lava Eel/ 90/mixed/ 32/32/600 2600/spring summer fall winter/both/684 .1/ 2/.05/.1/7/false", - - /* 0 Name - 5 startTime endTime - 6 season1 season2 ... - 7 rainy|sunny|both - 9 maxDepth - 10 spawnMultiplier - 11 depthMultiplier - 12 fishingLevel */ - - double chance = 0.0d; - foreach (SpawnFishData f in possibleFish) - { - // Use ItemId unless its null. Account for mods with non-standard IDs for vanilla records - String id = f.ItemId ?? f.Id; - String qualifiedID = id; - id = Regex.Replace(id, "\\(O\\)", ""); - // Debug - if (Game1.debugMode) Logger.Info($"Testing Fish ID: {id}"); + // Gather all fish and order them by presidence + enumerable = from p in enumerable + orderby p.Precedence, Game1.random.Next() + select p; - // Skip Garbage, Furniture and items that dont exist - if (id.Contains('|') || id.Contains("(F)") || !ItemRegistry.Exists(id)) continue; + // Loop through spawn data + foreach (SpawnFishData spawn in enumerable) + { + string fishIDQualified = spawn.ItemId ?? spawn.Id; + string fishID = Regex.Replace(fishIDQualified, "\\(O\\)", ""); - // Remove season check when using magic bait - String newCondition = f.Condition; - if (magicBait && f.Condition != null) + // If we get multiple options, select the first + if (fishIDQualified.Contains('|')) { - List conditions = f.Condition.Split(',').ToList(); - conditions.RemoveAll(u => u.ToUpper().Contains("LOCATION_SEASON")); - newCondition = String.Join(",", conditions); - } - if (!GameStateQuery.CheckConditions(newCondition)) continue; + fishIDQualified = fishIDQualified.Split('|')[0]; + fishID = Regex.Replace(fishIDQualified, "\\(O\\)", ""); + } - // If it's not found in the allFishData, assign the chance from possibleFish instead - if (!allFishData.ContainsKey(id)) - { - if (Game1.debugMode) Logger.Info($"\tdictFish: Adding {id} :: {f.Chance}"); - dictFish[qualifiedID] = f.Chance; + // Secret Notes / Inherited Fish Types + if (fishIDQualified.Contains("SECRET_NOTE_OR_ITEM") || fishIDQualified.Contains("LOCATION_FISH")) continue; + + // Not the correct area or season + if ((spawn.FishAreaId != null && id != spawn.FishAreaId) || (spawn.Season.HasValue && !flagMagicBait) && spawn.Season != seasonForLocation) + continue; + + // Player Position + Rectangle? playerPosition = spawn.PlayerPosition; + if (playerPosition.HasValue && !playerPosition.GetValueOrDefault().Contains(tilePoint.X, tilePoint.Y)) + continue; + + // Bobber Position + playerPosition = spawn.BobberPosition; + if ((playerPosition.HasValue && !playerPosition.GetValueOrDefault().Contains((int)bobberTile.X, (int)bobberTile.Y)) || player.FishingLevel < spawn.MinFishingLevel || waterDepth < spawn.MinDistanceFromShore || (spawn.MaxDistanceFromShore > -1 && waterDepth > spawn.MaxDistanceFromShore) || (spawn.RequireMagicBait && !flagMagicBait)) + continue; + + // Spawn Conditions + if (spawn.Condition != null && !GameStateQuery.CheckConditions(spawn.Condition, location, null, null, null, null, ignoreQueryKeys)) continue; - } - - // Get the data for the fish - String[] fishData = allFishData[id].Split('/'); - // Debug code for fish data - if (Game1.debugMode) + // We have caught the limit of the fish + if (spawn.CatchLimit > 0 && !player.fishCaught.TryGetValue(fishIDQualified, out var value2) && value2[0] >= spawn.CatchLimit) + continue; + + // If fish it not actually a fish + if (!allFishData.TryGetValue(fishID, out var fishArray)) { - Logger.Info($"Parsing through allFishData for {f.Id} now..."); - String jFishData = JsonSerializer.Serialize(fishData, new JsonSerializerOptions{WriteIndented = true}); - Logger.Info($"\tID: {id} *** {jFishData}"); + float chance = spawn.GetChance(hasCuriosityLure, player.DailyLuck, player.LuckLevel, (float value, IList modifiers, QuantityModifier.QuantityModifierMode mode) => Utility.ApplyQuantityModifiers(value, modifiers, mode, location), spawn.ItemId == textTarget); + chance = Math.Min(chance, 1f); + dictFish[fishIDQualified] = chance; + + // If this item has a 100% chance, we stop + if (chance >= 1f) + break; + else + continue; } - // Check the time window of the fish - String[] catchTimes = fishData[5].Split(' '); - if (!magicBait && (Game1.timeOfDay < Convert.ToInt32(catchTimes[0]) || Game1.timeOfDay >= Convert.ToInt32(catchTimes[1]))) continue; + // Split Fish Data to Array + string[] fishData = fishArray.Split('/'); - // Make sure weather matches the fish pool. [Hackswell: pun intended] - if (!fishData[7].Equals("both") && !magicBait) + // Training Rod Check + bool flagTrainingRod = rod.QualifiedItemId == "(T)TrainingRod"; + if (flagTrainingRod) { - if (fishData[7].Equals("rainy") && !Game1.isRaining) continue; - else if (fishData[7].Equals("sunny") && Game1.isRaining) continue; + bool? canUseTrainingRod = spawn.CanUseTrainingRod; + if (canUseTrainingRod.HasValue) + { + if (!canUseTrainingRod.GetValueOrDefault()) + continue; + else if (ArgUtility.TryGetInt(fishData, 1, out var value, out var error) && value >= 50) + continue; + } } - // Below the required level - if (who.FishingLevel < Convert.ToInt32(fishData[12])) continue; + // If we do not ingore requirements, check and get spawn chance + if (!spawn.IgnoreFishDataRequirements) + { + // Time and Weather Check if not using Magic Bait + if (!flagMagicBait) + { + // Time of Day Check + if (!ArgUtility.TryGet(fishData, 5, out var timeData, out var errorTime)) + continue; + + string[] timeArray = ArgUtility.SplitBySpace(timeData); + bool flagTime = false; + for (int i = 0; i < timeArray.Length; i += 2) + { + if (!ArgUtility.TryGetInt(timeArray, i, out var startTime, out errorTime) || !ArgUtility.TryGetInt(timeArray, i + 1, out var stopTime, out errorTime)) + continue; + + if (Game1.timeOfDay >= startTime && Game1.timeOfDay < stopTime) + flagTime = true; + break; + } + + if (!flagTime) + continue; + + // Weather Check + if (!ArgUtility.TryGet(fishData, 7, out var value, out var errorWeather)) + continue; + + if (!value.Equals("both")) + { + if (value.Equals("sunny") && location.IsRainingHere()) + continue; + if (value.Equals("rainy") && !location.IsRainingHere()) + continue; + } + } - // Calculate chance - int maxDepth = Convert.ToInt32(fishData[9]); - double spawnMultiplier = Convert.ToDouble(fishData[10]); - double depthMultiplier = Convert.ToDouble(fishData[11]) * spawnMultiplier; - spawnMultiplier -= Math.Max(0, maxDepth - waterDepth) * depthMultiplier; - spawnMultiplier += who.FishingLevel / 50f; - chance = Math.Min(spawnMultiplier, 0.89999997615814209); + // Fishing Level Check + if (ArgUtility.TryGetInt(fishData, 12, out var value8, out var error) && player.FishingLevel < value8) + continue; + + // Max Depth, Spawn Chance, Spawn Depth Check + if (!ArgUtility.TryGetInt(fishData, 9, out var maxDepth, out error) || !ArgUtility.TryGetFloat(fishData, 10, out var spawnMultiplier, out error) || !ArgUtility.TryGetFloat(fishData, 11, out var depthMultiplier, out error)) + continue; + + // Chance to Catch + float num = depthMultiplier * spawnMultiplier; + spawnMultiplier -= (float)Math.Max(0, maxDepth - waterDepth) * num; + spawnMultiplier += (float)player.FishingLevel / 50f; + if (flagTrainingRod) + spawnMultiplier *= 1.1f; + + spawnMultiplier = Math.Min(spawnMultiplier, 0.9f); + if ((double)spawnMultiplier < 0.25 && hasCuriosityLure) + if (spawn.CuriosityLureBuff > -1f) + spawnMultiplier += spawn.CuriosityLureBuff; + else + { + float num2 = 0.25f; + float num3 = 0.08f; + spawnMultiplier = (num2 - num3) / num2 * spawnMultiplier + (num2 - num3) / 2f; + } + + if (spawn.ItemId == textTarget) + spawnMultiplier *= 1.66f; + + if (spawn.ApplyDailyLuck) + spawnMultiplier += (float)player.DailyLuck; + + List chanceModifiers = spawn.ChanceModifiers; + if (chanceModifiers != null && chanceModifiers.Count > 0) + spawnMultiplier = Utility.ApplyQuantityModifiers(spawnMultiplier, spawn.ChanceModifiers, spawn.ChanceModifierMode, location); + + // Only if fish has a chance to sapwn + if (spawnMultiplier > 0) + { + spawnMultiplier = Math.Min(spawnMultiplier, 1f); + dictFish[fishIDQualified] = spawnMultiplier; + } - if (Game1.debugMode) Logger.Info($"dictFish: Adding {id} :: {chance}"); - dictFish[qualifiedID] = chance; - } + // If this item has a 100% chance, we stop + if (spawnMultiplier >= 1f) + break; + } - // Return fish list - if (Game1.debugMode) - { - String jDictFish = JsonSerializer.Serialize(dictFish, new JsonSerializerOptions { WriteIndented = true }); - Logger.Info($"Possible Fish:\n{jDictFish}"); + // If we ignore requirements, get chance from spawn + else + { + float chance = spawn.GetChance(hasCuriosityLure, player.DailyLuck, player.LuckLevel, (float value, IList modifiers, QuantityModifier.QuantityModifierMode mode) => Utility.ApplyQuantityModifiers(value, modifiers, mode, location), spawn.ItemId == textTarget); + chance = Math.Min(chance, 1f); + dictFish[fishIDQualified] = chance; + + // If this item has a 100% chance, we stop + if (chance >= 1f) + break; + } } + return dictFish; } - private static Dictionary GetFishesSubmarine() + private static bool IsGarbage(string item) { - return new Dictionary - { - { "800", 0.1 }, - { "799", 0.18 }, - { "798", 0.28 }, - { "154", 0.1 }, - { "155", 0.08 }, - { "149", 0.05 }, - { "797", 0.01 } - }; - } + // Return false for any Non-Objects + if (!item.Contains("(O)")) + return false; - private static Dictionary GetFishesMine(MineShaft shaft, bool magicBait, int bait, int waterDepth, Farmer who) - { - Dictionary dict = new Dictionary(); - double num2 = 1.0; - num2 += 0.4 * who.FishingLevel; - num2 += waterDepth * 0.1; - double p; - int level = shaft.getMineArea(); + // Get object information + string itemID = Regex.Replace(item, "\\(O\\)", ""); + var objectData = Game1.objectData[itemID]; - // Add fish based on mine level - switch (level) - { - case 0: - case 10: - num2 += bait == 689 ? 3 : 0; - p = 0.02 + 0.01 * num2; - dict.Add("158", p); // Stonefish - break; - case 40: - num2 += bait == 682 ? 3 : 0; - p = 0.015 + 0.009 * num2; - dict.Add("161", p); // Ice Pip - break; - case 80: - num2 += bait == 684 ? 3 : 0; - p = 0.01 + 0.008 * num2; - dict.Add("162", p); // Lava Eel - break; - default: - return dict; - } + // Fish items that are not fish + if (objectData != null && objectData.ContextTags.Contains("fish_nonfish") && !objectData.ContextTags.Contains("counts_as_fish_catch")) + return true; - if (level == 10 || level == 40) - return ConcatDictionary(dict,MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "UndergroundMine").Where(kv => !IsGarbage(kv.Key)).ToDictionary(x => x.Key, x => x.Value),1 - p)); + // JoJa Garbage + if (item == "(O)167" || item == "(O)168" || item == "(O)169" || item == "(O)170" || item == "(O)171" || item == "(O)172") + return true; - return dict; - } - - private static Dictionary GetFishesFarm(int waterDepth, Farmer who, bool magicBait) - { - switch (Game1.whichFarm) - { - case 1: - return ConcatDictionary(MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "Forest"), 0.3), MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "Town"), 0.7)); - case 3: - return MagnifyProbabilities(GetFishesGeneric(waterDepth, who, magicBait, "Forest"), 0.5); - case 2: - { - double p = 0.05 + Game1.player.DailyLuck; - return ConcatDictionary( - new Dictionary { { "734", p } }, - MagnifyProbabilities( - GetFishesGeneric(waterDepth, who, magicBait, "Forest"), - (1 - p) * 0.45) - ); - } - case 4: - { - return MagnifyProbabilities( - GetFishesGeneric(waterDepth, who, magicBait, "Mountain"), - 0.35); - } - default: - return GetFishesGeneric(waterDepth, who, magicBait); - } + return false; } - private static Dictionary GetFinalProbabilities(Dictionary dict) + private static Dictionary GetFinalProbabilities(Dictionary dict) { - Dictionary result = new Dictionary(); + Dictionary result = new(); double ratio = 1.0; - foreach (KeyValuePair kv in dict) + + // Get the result of each fish while moving down from 100% + foreach (KeyValuePair kv in dict) { result.Add(kv.Key, kv.Value * ratio); ratio *= (1 - kv.Value); @@ -383,79 +441,76 @@ private static Dictionary GetFinalProbabilities(Dictionary ShuffleAndAverageFishingDictionary(IEnumerable> list) { - try - { - // Account for qualified item names - int index = int.Parse(Regex.Replace(item, "\\(O\\)", "")); - if (index is >= 167 and <= 172) return true; - switch (index) - { - case 152: - case 153: - case 157: - return true; - } - } - catch { } - - return false; + List> dicts = list.Select(dict => GetFinalProbabilities(ShuffleDictionary(dict))).ToList(); + return AverageDictionary(dicts); } - private static Dictionary ShuffleAndAverageFishingDictionary(IEnumerable> list) + private static Dictionary ShuffleDictionary(Dictionary dict) { - List> dicts = list.Select(dict => GetFinalProbabilities(ShuffleDictionary(dict))).ToList(); + // Get the last value of the dictionary if higher than 100% + double? probability = null; + string LastKey = ""; + if (dict[dict.Keys.Last()] >= 1f) + { + LastKey = dict.Keys.Last(); + dict.Remove(LastKey); - return AverageDictionary(dicts); - } + // Get the probabilities of the remaining fish + foreach (KeyValuePair kv in dict) + if (!probability.HasValue) + probability = 1 - kv.Value; + else + probability *= 1 - kv.Value; + } - private static Dictionary ShuffleDictionary(Dictionary dict) - { - KeyValuePair[] pairs = dict.ToArray(); + // Shuffle the remaining items + KeyValuePair[] pairs = dict.ToArray(); Utility.Shuffle(Game1.random, pairs); - return pairs.ToDictionary(x => x.Key, x => x.Value); + Dictionary itemsShuffled = pairs.ToDictionary(x => x.Key, x => x.Value); + + // Insert the probability of the 100% + if (LastKey != "") + itemsShuffled[LastKey] = probability ?? 1; + + + return itemsShuffled; } - private static Dictionary AverageDictionary(List> list) + private static Dictionary AverageDictionary(List> list) { - Dictionary sum = new Dictionary(); - foreach (Dictionary elem in list) + Dictionary sum = new(); + foreach (Dictionary elem in list) { - foreach (KeyValuePair pair in elem) + foreach (KeyValuePair pair in elem) { if (sum.ContainsKey(pair.Key)) - { sum[pair.Key] += pair.Value; - } else - { sum.Add(pair.Key, pair.Value); - } } } return MagnifyProbabilities(sum, 1.0 / list.Count); } - private static Dictionary MagnifyProbabilities(Dictionary dict, double ratio) + private static Dictionary MagnifyProbabilities(Dictionary dict, double ratio) { return dict.ToDictionary(kv => kv.Key, kv => kv.Value * ratio); } private static Dictionary ConcatDictionary(IDictionary a, Dictionary b) { - Dictionary dict = new Dictionary(a); + Dictionary dict = new(a); foreach (KeyValuePair kv in b.Where(kv => !dict.ContainsKey(kv.Key))) - { dict.Add(kv.Key, kv.Value); - } return dict; } - private static int DrawProbBox(Dictionary probabilities) + private static int DrawProbBox(Dictionary probabilities) { Rectangle window = Game1.game1.Window.ClientBounds; SpriteBatch b = Game1.spriteBatch; @@ -480,7 +535,7 @@ private static int DrawProbBox(Dictionary probabilities) SpriteFont font = Game1.smallFont; // Draw Fish - foreach (KeyValuePair kv in probabilities) + foreach (KeyValuePair kv in probabilities) { if (kv.Key.Contains("SECRET_NOTE")) continue; string text = $"{kv.Value * 100:f1}%"; @@ -509,7 +564,7 @@ private static int DrawProbBox(Dictionary probabilities) return size.Width; } - private static Size GetProbBoxSize(Dictionary probabilities) + private static Size GetProbBoxSize(Dictionary probabilities) { int width = 16, height = 48; int square = (int)(Game1.tileSize / 1.5); @@ -517,7 +572,7 @@ private static Size GetProbBoxSize(Dictionary probabilities) int x_space = 0; bool y_max = false; SpriteFont font = Game1.smallFont; - foreach (KeyValuePair kv in probabilities) + foreach (KeyValuePair kv in probabilities) { if (kv.Key.Contains("SECRET_NOTE")) continue; string text = $"{kv.Value * 100:f1}%"; @@ -542,7 +597,7 @@ private static Size GetProbBoxSize(Dictionary probabilities) return new Size(width, height); } - private static void DrawTackleBox(Dictionary attachments, int x_add) + private static void DrawTackleBox(Dictionary attachments, int x_add) { Rectangle window = Game1.game1.Window.ClientBounds; SpriteBatch b = Game1.spriteBatch; @@ -576,7 +631,7 @@ private static void DrawTackleBox(Dictionary attachments, int x_add SpriteFont font = Game1.smallFont; // Add Bait and Tackle - foreach (KeyValuePair kv in attachments) + foreach (KeyValuePair kv in attachments) { string text = $"{kv.Value}"; Item tackle = ItemRegistry.Create(kv.Key, 1); @@ -587,12 +642,12 @@ private static void DrawTackleBox(Dictionary attachments, int x_add } } - private static Size GetTackleBoxSize(Dictionary attachments) + private static Size GetTackleBoxSize(Dictionary attachments) { int width = 16, height = 48; int square = (int)(Game1.tileSize / 1.5); SpriteFont font = Game1.smallFont; - foreach (KeyValuePair kv in attachments) + foreach (KeyValuePair kv in attachments) { string text = $"{kv.Value}"; Vector2 textSize = font.MeasureString(text); From 05dcc6fb03ceab590ca9351ad8376a038abafa4e Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Fri, 10 May 2024 12:10:27 -0400 Subject: [PATCH 24/29] [Hackswell] Removed Anvil from list of machines; don't automate that! Moved AutoReel check from NthTick to every tick. AFKFishing should work again. --- JoysOfEfficiency/Automation/AutoFisher.cs | 34 ++++++++++--------- JoysOfEfficiency/Core/Config.cs | 1 - JoysOfEfficiency/EventHandler/UpdateEvents.cs | 8 ++--- JoysOfEfficiency/FeaturesAndConfigs.md | 7 ++-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/JoysOfEfficiency/Automation/AutoFisher.cs b/JoysOfEfficiency/Automation/AutoFisher.cs index 2e46b54..fa1f544 100644 --- a/JoysOfEfficiency/Automation/AutoFisher.cs +++ b/JoysOfEfficiency/Automation/AutoFisher.cs @@ -9,7 +9,7 @@ using StardewValley.Objects; using StardewValley.SpecialOrders; using StardewValley.Tools; -using Object = StardewValley.Object; +using SVObject = StardewValley.Object; namespace JoysOfEfficiency.Automation { @@ -21,8 +21,8 @@ internal class AutoFisher public static bool AfkMode { get; private set; } - public static int fishQuality { get; set; } - public static bool treasure { get; set; } + public static int FishQuality { get; set; } + public static bool Treasure { get; set; } private static bool CatchingTreasure { get; set; } private static int AutoFishingCounter { get; set; } @@ -92,7 +92,7 @@ private static void CollectFish(Farmer who, FishingRod rod) { ItemMetadata whichFish = rod.whichFish; String whichFishName = rod.whichFish.QualifiedItemId; - fishQuality = rod.fishQuality; + FishQuality = rod.fishQuality; string fishID = whichFish.GetParsedData().ItemId; int itemCategory = whichFish.GetParsedData().Category; @@ -110,17 +110,22 @@ private static void CollectFish(Farmer who, FishingRod rod) who.currentLocation.localSound("coin"); if (!rod.treasureCaught) { - Object @object = null; + SVObject @object = null; switch (itemCategory) { - case Object.furnitureCategory: + case SVObject.furnitureCategory: { + Logger.Log($"\tFurniture? {fishID}\tItemCategory: {itemCategory}"); @object = new Furniture(fishID, Vector2.Zero); break; } - case Object.FishCategory: + case SVObject.junkCategory: + case SVObject.litterCategory: + case SVObject.FishCategory: + default: { - @object = new StardewValley.Object(fishID, 1, false, -1, fishQuality); + Logger.Log($"\tFishy, Litter, or Junky! {fishID}"); + @object = new SVObject(fishID, 1, false, -1, FishQuality); if (fishID == GameLocation.CAROLINES_NECKLACE_ITEM_QID) { @object.questItem.Value = true; @@ -140,17 +145,12 @@ private static void CollectFish(Farmer who, FishingRod rod) break; } - default: - { - Logger.Log($"How did we get here?!?! Unhandled case in CollectFish! ItemCategory: {itemCategory}"); - break; - } } bool fromFishPond = rod.fromFishPond; who.completelyStopAnimatingOrDoingAction(); rod.doneFishing(who, !fromFishPond); - if (!Game1.isFestival() && !fromFishPond && (itemCategory == Object.FishCategory && Game1.player.team.specialOrders.Count > 0)) + if (!Game1.isFestival() && !fromFishPond && (itemCategory == SVObject.FishCategory && Game1.player.team.specialOrders.Count > 0)) { foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { @@ -167,6 +167,7 @@ private static void CollectFish(Farmer who, FishingRod rod) } else { + Logger.Log($"Treazhure Cot!"); rod.fishCaught = false; rod.showingTreasure = true; who.UsingTool = true; @@ -176,9 +177,10 @@ private static void CollectFish(Farmer who, FishingRod rod) initialStack = rod.numberOfFishCaught; } - Object @object = new Object(fishID, initialStack, false, -1, fishQuality); + SVObject @object = new SVObject(fishID, initialStack, false, -1, FishQuality); if (Game1.player.team.specialOrders.Count > 0) { + Logger.Log($"\tSpechul Treazhure!"); foreach (SpecialOrder specialOrder in Game1.player.team.specialOrders) { specialOrder.onFishCaught?.Invoke(Game1.player, @object); @@ -207,7 +209,7 @@ public static void AutoFishing(BobberBar bar) float bobberBarSpeed = bar.bobberBarSpeed; float top = barPos; - if (treasure && treasureAppearTimer <= 0 && !treasureCaught) + if (Treasure && treasureAppearTimer <= 0 && !treasureCaught) { if (!CatchingTreasure && distanceFromCatching > 0.7f) { diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index b7f7a76..8dbae20 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -107,7 +107,6 @@ internal class Config public HashSet MachineTypes { get; set; } = new HashSet() { - "Anvil", "Bait Maker", "Bee House", "Bone Mill", diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/JoysOfEfficiency/EventHandler/UpdateEvents.cs index ea4c005..4f90c4e 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/JoysOfEfficiency/EventHandler/UpdateEvents.cs @@ -54,6 +54,10 @@ public void OnEveryUpdate() { FishingProbabilitiesBox.UpdateProbabilities(rod); AutoFisher.AfkFishing(); + if (Conf.AutoReelRod) + { + AutoFisher.AutoReelRod(); + } } GiftInformationTooltip.UpdateTooltip(); @@ -83,10 +87,6 @@ private void OnGameNthTickUpdate() { return; } - if (Conf.AutoReelRod) - { - AutoFisher.AutoReelRod(); - } FarmCleaner.OnNthTickUpdate(); if (Conf.UnifyFlowerColors) diff --git a/JoysOfEfficiency/FeaturesAndConfigs.md b/JoysOfEfficiency/FeaturesAndConfigs.md index d247e99..b8cec41 100644 --- a/JoysOfEfficiency/FeaturesAndConfigs.md +++ b/JoysOfEfficiency/FeaturesAndConfigs.md @@ -190,10 +190,9 @@ This utility will try to pull results from nearby machines and give it to the fa ## List of Valid Machines (for auto-push and auto-pull) - MachineTypes [List of Machine Name strings] - You can disable or add new machine types by editing config.json. If a new version of SdV comes out with a new machine, you can add it here without waiting for a new version of JoE! - - "Anvil", - "Bait Maker", + - "Bait Maker", "Bee House", - - "Bone Mill", + "Bone Mill", "Cask", "Charcoal Kiln", "Cheese Press", @@ -223,7 +222,7 @@ This utility will try to pull results from nearby machines and give it to the fa "Statue Of Endless Fortune", "Statue Of Perfection", "Tapper", - - "Wood Chipper", + "Wood Chipper", "Worm Bin", ## Auto Pet Nearby Pets From aa8762c056777f9c18523126bbbc89b40f5a9376 Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Sun, 12 May 2024 14:06:05 -0700 Subject: [PATCH 25/29] Minor Fixes --- JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs index 83aca38..80bce76 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -125,13 +125,13 @@ private static Dictionary GetFishes(GameLocation location, Vecto private static Dictionary GetFishesMine(MineShaft shaft, Vector2 bobbleTile, int waterDepth, Farmer player, FishingRod rod) { - Dictionary dict = new Dictionary(); + Dictionary dict = new(); double p; // If player is using training rod in mines, return trash if (rod.QualifiedItemId.Contains("TrainingRod")) { - dict["(O)167"] = 1; + dict["(O)168"] = 1; return dict; } @@ -171,13 +171,14 @@ private static Dictionary GetFishesMine(MineShaft shaft, Vector2 return dict; } - // Get general fish data on level 10/40, and add Cave Jelly to level 80 + // Get general fish data on level 10/40, and add Cave Jelly and trash to level 80 if (level == 10 || level == 40) return ConcatDictionary(dict, GetFishesGeneric(bobbleTile, waterDepth, player, rod, "UndergroundMine")); else if (level == 80) { p = 0.05 + player.LuckLevel * 0.05; dict.Add("(O)CaveJelly", p); + dict.Add("(O)168", 1); } return dict; @@ -269,7 +270,7 @@ private static Dictionary GetFishesGeneric(Vector2 bobberTile, i continue; // We have caught the limit of the fish - if (spawn.CatchLimit > 0 && !player.fishCaught.TryGetValue(fishIDQualified, out var value2) && value2[0] >= spawn.CatchLimit) + if (spawn.CatchLimit > 0 && player.fishCaught.TryGetValue(fishIDQualified, out var value2) && value2[0] >= spawn.CatchLimit) continue; // If fish it not actually a fish @@ -321,8 +322,10 @@ private static Dictionary GetFishesGeneric(Vector2 bobberTile, i continue; if (Game1.timeOfDay >= startTime && Game1.timeOfDay < stopTime) + { flagTime = true; - break; + break; + } } if (!flagTime) From 198ab3504c28e08476ab2d98cec182a61ef1d893 Mon Sep 17 00:00:00 2001 From: CaranudLapin Date: Sun, 19 May 2024 17:07:55 +0200 Subject: [PATCH 26/29] Create fr.json --- JoysOfEfficiency/i18n/fr.json | 143 ++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 JoysOfEfficiency/i18n/fr.json diff --git a/JoysOfEfficiency/i18n/fr.json b/JoysOfEfficiency/i18n/fr.json new file mode 100644 index 0000000..aee93a7 --- /dev/null +++ b/JoysOfEfficiency/i18n/fr.json @@ -0,0 +1,143 @@ +{ + "button.awaiting": "Appuyez sur la touche ou le bouton pour l'assigner...", + "button.conflict": "La touche ou le bouton que vous avez pressé est déjà utilisée.", + "button.esc": "Appuyez sur la touche Échap pour annuler", + + "estimatedprice.title": "Prix de vente estimé", + + "fishinfo.quality": "Qualité :", + "fishinfo.size": "Taille : {0} pouce(s)", + "fishinfo.species": "Espèce : {0}", + "fishinfo.treasure.appear": "Trésor apparu !", + "fishinfo.treasure.caught": "Trésor attrapé !", + "fishinfo.treasure.incoming": "Un trésor apparaîtra dans {0:f1} s.", + "fishinfo.price": "Prix de vente : {0} po", + + "hud.paused": "Jeu en pause.", + + "ladder": "L'échelle est apparue !", + + "location.awaiting": "Cliquez quelque part pour désigner l'emplacement que vous voulez.", + + "monsters.tally": "{0} : {1} éliminés", + + "options.AnimalHarvestRadius": "Distance des animaux (cases) ", + "options.AutoAnimalDoor": "Auto-ouverture/fermeture des portes des animaux", + "options.AutoCollectCollectibles": "Auto-ramassage des objets récoltables proches", + "options.AutoCollectRadius": "Distance de ramassage (cases) ", + "options.AutoDepositIngredient": "Auto-dépôt d’ingrédients dans les machines", + "options.AutoDepositSeedMaker": "Auto-dépôt d’ingrédients dans les extracteurs de graines", + "options.AutoDestroyDeadCrops": "Auto-destruction des cultures mortes proches", + "options.AutoDigArtifactSpot": "Auto-creusage des sites d'artéfacts proches", + "options.AutoDigRadius": "Distance de creusage auto (cases) ", + "options.AutoEat": "Auto-consommer quelque chose en cas de besoin", + "options.AutoFishing": "Pêche automatique", + "options.AutoGate": "Auto-ouverture/fermeture des portails", + "options.AutoHarvest": "Auto-récolte des cultures mûres", + "options.AutoHarvestRadius": "Distance de récolte (cases) ", + "options.AutoLootTreasures": "Auto-ramassage des objets des boîtes à trésors", + "options.AutoPetNearbyAnimals": "Auto-caresse des animaux proches", + "options.AutoPetNearbyPets": "Auto-caresse des animaux de compagnie proches", + "options.AutoPetRadius": "Distance des animaux (cases) ", + "options.AutoPickUpTrash": "Auto-ramassage des déchets à proximité", + "options.AutoPullMachineResult": "Auto-récupération des résultats des machines", + "options.AutoReelRod": "Auto-rembobinage lorsqu'un poisson mord", + "options.AutoRefillWateringCan": "Auto-rechargement de l’arrosoir près de l'eau", + "options.AutoShakeFruitedPlants": "Auto-secouage des plantes fruitières à proximité", + "options.AutoShakeRadius": "Distance de secouage auto (cases) ", + "options.AutoShearingAndMilking": "Auto-tondre/traire les moutons/vaches matures", + "options.AutoWaterNearbyCrops": "Auto-arrosage des cultures", + "options.AutoWaterRadius": "Distance d'arrosage (cases) ", + "options.BalancedMode": "Mode équilibré (limiter JoE à 1x /seconde)", + "options.EveryNthTick": "Mise à jour tous les N ticks ", + "options.CloseTreasureWhenAllLooted": "Fermer la boîte à trésor lorsque tous les objets sont pris", + "options.CollectLetterAttachmentsAndQuests": "Auto-acceptation quêtes et pièces jointes des courriers", + "options.CPUThresholdFishing": "Fréquence de l’actualisation de l’IA", + "options.CraftingFromChests": "Fabrication en utilisant les objets dans les coffres proches", + "options.DontEatThat": "Activer \"Ne mange pas ça (©)\"", + "options.EstimateShippingPrice": "Estimer le prix d'expédition", + "options.FilterBackgroundInMenu": "Arrière-plan assombri en dehors du menu de config.", + "options.FindCanFromInventory": "Équiper l'arrosoir dans l'inventaire", + "options.FindHoeFromInventory": "Équiper la houe dans l'inventaire", + "options.FishInfo": "Afficher la boîte d'information sur le poisson", + "options.FishingInfo": "Afficher la boîte d'information sur la pêche", + "options.FishingProbabilitiesInfo": "Afficher les probabilités de pêche", + "options.ThresholdStaminaPercentage": "Pourcentage de seuil de stamina", + "options.GiftInformation": "Afficher les info-bulles sur les cadeaux", + "options.HealthToEatRatio": "Seuil santé pour l’auto-conso ", + "options.IdleTimeout": "Délai d'inactivité avant pause ", + "options.KeyShowMenu": "Afficher le menu des paramètres ", + "options.KeyToggleBlackList": "Activer/désactiver la liste noire de récolte ", + "options.MachineRadius": "Distance des machines (cases) ", + "options.MineInfoGui": "Afficher les icônes d'information dans les mines", + "options.MuchFasterBiting": "Réduit le temps de mordillage à \"immédiat\"", + "options.PauseWhenIdle": "Mettre en pause en cas d'inactivité", + "options.ProbBoxLocation": "Coordonnées (haut/gauche) boîte d'information", + "options.MorePreciseProbabilities": "Calculer des probabilités plus précises", + "options.TrialOfExamine": "Nombre de calculs de probabilités ", + "options.ProtectNectarProducingFlower": "Protéger les fleurs près des ruches", + "options.RadiusCraftingFromChests": "Distance des coffres (cases) ", + "options.ScavengingRadius": "Distance des poubelles (cases) ", + "options.StaminaToEatRatio": "Seuil endurance pour l'auto-conso ", + "options.UnifyFlowerColors": "Activer ou désactiver l'uniformisation des couleurs des fleurs", + "options.ShowMousePositionWhenAssigningLocation": "Afficher la position de la souris lorsqu’il y a attribution \nde coordonnées", + "options.ButtonToggleFlowerColorUnification": "Enregistrer/effacer couleur fleur uniforme ", + "options.RadiusFarmCleanup": "Rayon en cases pour nettoyer la ferme ", + "options.CutWeeds": "Couper les mauvaises herbes (faux)", + "options.BreakRocks": "Casser les cailloux (pioche)", + "options.ChopTwigs": "Coupe des branchages (hache)", + "options.PriceBoxCoordinates": "Coordonnées (haut/gauche) fenêtre info", + + "options.FishingTackleInfo": "Afficher les outils (appât et flotteurs)", + "options.TackleBoxAttach": "Attacher ensemble boîtes infos outils et probabilités poisson", + "options.TackleBoxLocation": "Coordonnées (haut/gauche) fenêtre info", + "options.ProbBoxMaxFish": "Nombre max poissons par colonne ", + + "options.ThrowPower": "Ajustement force de lancer flotteur ", + "options.ThresholdStaminaPersentage": "Pourcentage de seuil de stamina pour arrêter la pêche", + + "options.ToggleAFKFishing": "Activer/désactiver le mode de pêche AFK ", + + "hud.afk.passedout": "La pêche a cessé en raison de votre évanouissement.", + "hud.afk.on": "La pêche AFK est activée.", + "hud.afk.off": "La pêche AFK est désactivée.", + "hud.afk.tired": "La pêche a cessé parce que vous vous sentez fatigué.", + + "options.flower": "Fleur : {0}", + "options.R": "R", + "options.G": "V", + "options.B": "B", + "options.previewColor": "Couleur de prévisualisation", + "options.register": "Enregistrer", + + "flower.register": "Les couleurs de {0} seront unifiées.", + "flower.unregister": "Les couleurs de {0} ne seront plus unifiées.", + "flower.vanilla": "Vous ne pouvez pas annuler l'enregistrement des fleurs de base.", + + "quality.gold": "Or", + "quality.iridium": "Iridium", + "quality.normal": "Normal", + "quality.silver": "Argent", + "stones.many": "Il y a {0} pierres sur cet étage", + "stones.none": "Il n’y a pas de pierres sur cet étage.", + "stones.one": "Il y a une pierre restante sur cet étage.", + "tab.automation": "Automatisation.", + "tab.cheats": "Triche", + "tab.controls": "Raccourci", + "tab.misc": "Divers", + "tab.UIs": "Interface utilisateur", + "taste.dislike.female": "Elle n'aime pas ce cadeau.", + "taste.dislike.male": "Il n'aime pas ce cadeau.", + "taste.gavetoday.female": "Vous lui avez déjà offert un cadeau aujourd'hui.", + "taste.gavetoday.male": "Vous lui avez déjà offert un cadeau aujourd'hui.", + "taste.gavetwogifts.female": "Vous lui avez déjà offert deux cadeaux cette semaine.", + "taste.gavetwogifts.male": "Vous lui avez déjà offert deux cadeaux cette semaine.", + "taste.hate.female": "Elle HAIT ce cadeau.", + "taste.hate.male": "Il HAIT ce cadeau.", + "taste.like.female": "Elle aime ce cadeau.", + "taste.like.male": "Il aime ce cadeau.", + "taste.love.female": "Elle ADORE ce cadeau.", + "taste.love.male": "Il ADORE ce cadeau.", + "taste.neutral.female": "Il est neutre envers ce cadeau.", + "taste.neutral.male": "Elle est neutre envers ce cadeau." +} From 4202209f70010227292916ce8a72494b3e95ccb4 Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Sun, 19 May 2024 22:04:07 -0400 Subject: [PATCH 27/29] [Hackswell] Fix auto-close chest after fishing. Merged French i18n from Caranud. Fixed where DontEatThat doesn't recognize changes during game. --- JoysOfEfficiency/Automation/FoodAutomation.cs | 2 +- JoysOfEfficiency/Core/Config.cs | 5 +++++ JoysOfEfficiency/Core/ModEntry.cs | 12 ++++++++++++ JoysOfEfficiency/EventHandler/UpdateEvents.cs | 8 ++++---- JoysOfEfficiency/i18n/default.json | 1 + JoysOfEfficiency/i18n/fr.json | 13 ------------- JoysOfEfficiency/manifest.json | 2 +- 7 files changed, 24 insertions(+), 19 deletions(-) diff --git a/JoysOfEfficiency/Automation/FoodAutomation.cs b/JoysOfEfficiency/Automation/FoodAutomation.cs index bf5363f..b95e183 100644 --- a/JoysOfEfficiency/Automation/FoodAutomation.cs +++ b/JoysOfEfficiency/Automation/FoodAutomation.cs @@ -121,7 +121,7 @@ public static void ButtonPressed(object sender, ButtonPressedEventArgs e) { SVObject activePlayerItem = Game1.player.ActiveObject; - if (Context.IsWorldReady && e.Button.IsActionButton() && activePlayerItem != null) + if (Config.DontEatThat && Context.IsWorldReady && e.Button.IsActionButton() && activePlayerItem != null) { string itemName = activePlayerItem.DisplayName; diff --git a/JoysOfEfficiency/Core/Config.cs b/JoysOfEfficiency/Core/Config.cs index 8dbae20..151f6db 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/JoysOfEfficiency/Core/Config.cs @@ -186,5 +186,10 @@ internal class Config public bool ChopTwigs { get; set; } = false; public bool DisableConfigLimitation { get; set; } = false; + + public int WindowWidth { get; set; } = 1280; + public int WindowHeight { get; set; } = 800; + public int WindowX { get; set; } = 950; + public int WindowY { get; set; } = 300; } } diff --git a/JoysOfEfficiency/Core/ModEntry.cs b/JoysOfEfficiency/Core/ModEntry.cs index c70bd22..078680f 100644 --- a/JoysOfEfficiency/Core/ModEntry.cs +++ b/JoysOfEfficiency/Core/ModEntry.cs @@ -5,6 +5,7 @@ using JoysOfEfficiency.Huds; using JoysOfEfficiency.ModCheckers; using JoysOfEfficiency.Utils; +using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -101,6 +102,17 @@ private static void OnGameLaunched(object sender, GameLaunchedEventArgs e) Logger.Log($"Don't Eat That(tm) is enabled!"); FoodAutomation.InitDontEat(); } + + Game1.graphics.PreferredBackBufferWidth = Conf.WindowWidth; + Game1.graphics.PreferredBackBufferHeight = Conf.WindowHeight; + var viewport = Game1.graphics.GraphicsDevice.Viewport; + viewport.Width = Conf.WindowWidth; + viewport.Height = Conf.WindowHeight; +// viewport.X = Conf.WindowX; // Hackswell: seems to do nothing +// viewport.Y = Conf.WindowY; // Hackswell: seems to do nothing +// viewport.Bounds = new Rectangle(new Point(Conf.WindowX, Conf.WindowY), new Point(Conf.WindowWidth, Conf.WindowHeight)); // Hackswell: seems to do nothing + GameRunner.instance.Window.Position = new Point(Conf.WindowX, Conf.WindowY); // Hackswell: seems to do nothing + Game1.graphics.ApplyChanges(); } private static void OnDebugCommand(string name, string[] args) diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/JoysOfEfficiency/EventHandler/UpdateEvents.cs index 4f90c4e..fc756f0 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/JoysOfEfficiency/EventHandler/UpdateEvents.cs @@ -58,6 +58,10 @@ public void OnEveryUpdate() { AutoFisher.AutoReelRod(); } + if (Conf.CloseTreasureWhenAllLooted && Game1.activeClickableMenu is ItemGrabMenu menu) + { + InventoryAutomation.TryCloseItemGrabMenu(menu); + } } GiftInformationTooltip.UpdateTooltip(); @@ -70,10 +74,6 @@ private void OnGameNthTickUpdate() { return; } - if (Conf.CloseTreasureWhenAllLooted && Game1.activeClickableMenu is ItemGrabMenu menu) - { - InventoryAutomation.TryCloseItemGrabMenu(menu); - } Farmer player = Game1.player; GameLocation location = Game1.currentLocation; diff --git a/JoysOfEfficiency/i18n/default.json b/JoysOfEfficiency/i18n/default.json index 2e87032..b0f8aa0 100644 --- a/JoysOfEfficiency/i18n/default.json +++ b/JoysOfEfficiency/i18n/default.json @@ -40,6 +40,7 @@ "options.AutoPetNearbyPets": "Auto-pet nearby pets", "options.AutoPetRadius": "How far tiles to find animals", "options.AutoPickUpTrash": "Scavenges nearby trash can", + "options.GarbageDisgustsNPCs": "Scavenging garbage disgusts NPCs", "options.AutoPullMachineResult": "Auto-pull results from machines", "options.AutoReelRod": "Auto reeling when fish nibbled", "options.AutoRefillWateringCan": "Auto-refill watering can near water", diff --git a/JoysOfEfficiency/i18n/fr.json b/JoysOfEfficiency/i18n/fr.json index aee93a7..8a3cf1a 100644 --- a/JoysOfEfficiency/i18n/fr.json +++ b/JoysOfEfficiency/i18n/fr.json @@ -2,9 +2,7 @@ "button.awaiting": "Appuyez sur la touche ou le bouton pour l'assigner...", "button.conflict": "La touche ou le bouton que vous avez pressé est déjà utilisée.", "button.esc": "Appuyez sur la touche Échap pour annuler", - "estimatedprice.title": "Prix de vente estimé", - "fishinfo.quality": "Qualité :", "fishinfo.size": "Taille : {0} pouce(s)", "fishinfo.species": "Espèce : {0}", @@ -12,15 +10,10 @@ "fishinfo.treasure.caught": "Trésor attrapé !", "fishinfo.treasure.incoming": "Un trésor apparaîtra dans {0:f1} s.", "fishinfo.price": "Prix de vente : {0} po", - "hud.paused": "Jeu en pause.", - "ladder": "L'échelle est apparue !", - "location.awaiting": "Cliquez quelque part pour désigner l'emplacement que vous voulez.", - "monsters.tally": "{0} : {1} éliminés", - "options.AnimalHarvestRadius": "Distance des animaux (cases) ", "options.AutoAnimalDoor": "Auto-ouverture/fermeture des portes des animaux", "options.AutoCollectCollectibles": "Auto-ramassage des objets récoltables proches", @@ -87,22 +80,17 @@ "options.BreakRocks": "Casser les cailloux (pioche)", "options.ChopTwigs": "Coupe des branchages (hache)", "options.PriceBoxCoordinates": "Coordonnées (haut/gauche) fenêtre info", - "options.FishingTackleInfo": "Afficher les outils (appât et flotteurs)", "options.TackleBoxAttach": "Attacher ensemble boîtes infos outils et probabilités poisson", "options.TackleBoxLocation": "Coordonnées (haut/gauche) fenêtre info", "options.ProbBoxMaxFish": "Nombre max poissons par colonne ", - "options.ThrowPower": "Ajustement force de lancer flotteur ", "options.ThresholdStaminaPersentage": "Pourcentage de seuil de stamina pour arrêter la pêche", - "options.ToggleAFKFishing": "Activer/désactiver le mode de pêche AFK ", - "hud.afk.passedout": "La pêche a cessé en raison de votre évanouissement.", "hud.afk.on": "La pêche AFK est activée.", "hud.afk.off": "La pêche AFK est désactivée.", "hud.afk.tired": "La pêche a cessé parce que vous vous sentez fatigué.", - "options.flower": "Fleur : {0}", "options.R": "R", "options.G": "V", @@ -113,7 +101,6 @@ "flower.register": "Les couleurs de {0} seront unifiées.", "flower.unregister": "Les couleurs de {0} ne seront plus unifiées.", "flower.vanilla": "Vous ne pouvez pas annuler l'enregistrement des fleurs de base.", - "quality.gold": "Or", "quality.iridium": "Iridium", "quality.normal": "Normal", diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json index 7031141..3c69ff1 100644 --- a/JoysOfEfficiency/manifest.json +++ b/JoysOfEfficiency/manifest.json @@ -6,5 +6,5 @@ "Name": "JoysOfEfficiency", "UniqueID": "punyo.JoysOfEfficiency", "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.5.0-unofficial.6-Hackswell" + "Version": "1.5.0-unofficial.7-Hackswell" } From f84bbc90d0cab60d41273c7455e25972fe04252d Mon Sep 17 00:00:00 2001 From: Richard Balint <2632004+Hackswell@users.noreply.github.com> Date: Tue, 21 May 2024 10:56:35 -0400 Subject: [PATCH 28/29] [Hackswell] Forking and Renaming to GloryOfEfficiency. --- JoysOfEfficiency.sln => GloryOfEfficiency.sln | 2 +- .../Automation/AnimalAutomation.cs | 6 +++--- .../Automation/AutoFisher.cs | 6 +++--- .../Automation/CollectibleCollector.cs | 6 +++--- .../Automation/FarmCleaner.cs | 6 +++--- .../Automation/FenceGateAutomation.cs | 6 +++--- .../Automation/FlowerColorUnifier.cs | 14 +++++++------- .../Automation/FoodAutomation.cs | 6 +++--- .../Automation/HarvestAutomation.cs | 6 +++--- .../Automation/InventoryAutomation.cs | 6 +++--- .../Automation/MachineOperator.cs | 6 +++--- .../Automation/MailAutomation.cs | 4 ++-- .../Automation/TrashCanScavenger.cs | 4 ++-- .../Automation/WateringCanRefiller.cs | 6 +++--- .../Configs/ConfigCustomAnimalTool.cs | 4 ++-- .../Configs/CustomAnimalTool.cs | 2 +- .../Core/Config.cs | 2 +- .../Core/ConfigLimitation.cs | 4 ++-- .../Core/InstanceHolder.cs | 4 ++-- .../Core/ModEntry.cs | 14 +++++++------- .../EventHandler/ArtifactSpotDigger.cs | 6 +++--- .../EventHandler/EventHolder.cs | 4 ++-- .../EventHandler/GraphicsEvents.cs | 10 +++++----- .../EventHandler/InputEvents.cs | 8 ++++---- .../EventHandler/MenuEvents.cs | 6 +++--- .../EventHandler/SaveEvents.cs | 8 ++++---- .../EventHandler/UpdateEvents.cs | 12 ++++++------ .../FeaturesAndConfigs.md | 0 .../GloryOfEfficiency.csproj | 8 ++++---- .../Harmony/HarmonyPatcher.cs | 2 +- .../Huds/FishInformationHud.cs | 6 +++--- .../Huds/FishingProbabilitiesBox.cs | 14 +++++++------- .../Huds/FpsCounter.cs | 6 +++--- .../Huds/GiftInformationTooltip.cs | 6 +++--- .../Huds/MineHud.cs | 4 ++-- .../Huds/MineIcons.cs | 6 +++--- .../Huds/PausedHud.cs | 6 +++--- .../Huds/ShippingEstimationInfoBox.cs | 6 +++--- .../Menus/JoeMenu.cs | 8 ++++---- .../Menus/RegisterFlowerMenu.cs | 10 +++++----- .../Misc/IdlePause.cs | 8 ++++---- .../ModCheckers/ModChecker.cs | 2 +- .../OptionsElements/ButtonWithLabel.cs | 8 ++++---- .../OptionsElements/ColorBox.cs | 4 ++-- .../OptionsElements/EmptyLabel.cs | 2 +- .../OptionsElements/LabelComponent.cs | 2 +- .../OptionsElements/MenuTab.cs | 2 +- .../OptionsElements/ModifiedCheckBox.cs | 4 ++-- .../OptionsElements/ModifiedClickListener.cs | 6 +++--- .../OptionsElements/ModifiedInputListener.cs | 4 ++-- .../OptionsElements/ModifiedSlider.cs | 4 ++-- .../OptionsElements/OptionsElementWithLabel.cs | 4 ++-- .../Properties/AssemblyInfo.cs | 6 +++--- .../Properties/Resources.Designer.cs | 4 ++-- .../Properties/Resources.resx | 0 .../Utils/ConfigHolder.cs | 2 +- .../Utils/CustomAnimalConfigHolder.cs | 4 ++-- .../Utils/Logger.cs | 2 +- .../Utils/Util.cs | 4 ++-- .../WhatsNew.md | 0 .../assets/icon_ladder.png | Bin .../assets/icon_monster.png | Bin .../assets/icon_pickaxe.png | Bin .../i18n/de.json | 0 .../i18n/default.json | 0 .../i18n/es.json | 0 .../i18n/fr.json | 0 .../i18n/ja.json | 0 .../i18n/ko.json | 0 .../i18n/pt.json | 0 .../i18n/ru.json | 0 .../i18n/zh.json | 0 GloryOfEfficiency/manifest.json | 10 ++++++++++ .../packages.config | 0 JoysOfEfficiency/manifest.json | 10 ---------- LICENSE | 3 ++- 76 files changed, 173 insertions(+), 172 deletions(-) rename JoysOfEfficiency.sln => GloryOfEfficiency.sln (89%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/AnimalAutomation.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/AutoFisher.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/CollectibleCollector.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/FarmCleaner.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/FenceGateAutomation.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/FlowerColorUnifier.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/FoodAutomation.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/HarvestAutomation.cs (99%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/InventoryAutomation.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/MachineOperator.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/MailAutomation.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/TrashCanScavenger.cs (94%) rename {JoysOfEfficiency => GloryOfEfficiency}/Automation/WateringCanRefiller.cs (87%) rename {JoysOfEfficiency => GloryOfEfficiency}/Configs/ConfigCustomAnimalTool.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/Configs/CustomAnimalTool.cs (90%) rename {JoysOfEfficiency => GloryOfEfficiency}/Core/Config.cs (99%) rename {JoysOfEfficiency => GloryOfEfficiency}/Core/ConfigLimitation.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/Core/InstanceHolder.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/Core/ModEntry.cs (94%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/ArtifactSpotDigger.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/EventHolder.cs (93%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/GraphicsEvents.cs (90%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/InputEvents.cs (88%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/MenuEvents.cs (85%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/SaveEvents.cs (85%) rename {JoysOfEfficiency => GloryOfEfficiency}/EventHandler/UpdateEvents.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/FeaturesAndConfigs.md (100%) rename JoysOfEfficiency/JoysOfEfficiency.csproj => GloryOfEfficiency/GloryOfEfficiency.csproj (94%) rename {JoysOfEfficiency => GloryOfEfficiency}/Harmony/HarmonyPatcher.cs (87%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/FishInformationHud.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/FishingProbabilitiesBox.cs (99%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/FpsCounter.cs (92%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/GiftInformationTooltip.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/MineHud.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/MineIcons.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/PausedHud.cs (90%) rename {JoysOfEfficiency => GloryOfEfficiency}/Huds/ShippingEstimationInfoBox.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/Menus/JoeMenu.cs (99%) rename {JoysOfEfficiency => GloryOfEfficiency}/Menus/RegisterFlowerMenu.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/Misc/IdlePause.cs (92%) rename {JoysOfEfficiency => GloryOfEfficiency}/ModCheckers/ModChecker.cs (87%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/ButtonWithLabel.cs (94%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/ColorBox.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/EmptyLabel.cs (86%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/LabelComponent.cs (92%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/MenuTab.cs (91%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/ModifiedCheckBox.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/ModifiedClickListener.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/ModifiedInputListener.cs (98%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/ModifiedSlider.cs (97%) rename {JoysOfEfficiency => GloryOfEfficiency}/OptionsElements/OptionsElementWithLabel.cs (89%) rename {JoysOfEfficiency => GloryOfEfficiency}/Properties/AssemblyInfo.cs (88%) rename {JoysOfEfficiency => GloryOfEfficiency}/Properties/Resources.Designer.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/Properties/Resources.resx (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/Utils/ConfigHolder.cs (96%) rename {JoysOfEfficiency => GloryOfEfficiency}/Utils/CustomAnimalConfigHolder.cs (82%) rename {JoysOfEfficiency => GloryOfEfficiency}/Utils/Logger.cs (95%) rename {JoysOfEfficiency => GloryOfEfficiency}/Utils/Util.cs (99%) rename {JoysOfEfficiency => GloryOfEfficiency}/WhatsNew.md (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/assets/icon_ladder.png (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/assets/icon_monster.png (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/assets/icon_pickaxe.png (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/de.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/default.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/es.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/fr.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/ja.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/ko.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/pt.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/ru.json (100%) rename {JoysOfEfficiency => GloryOfEfficiency}/i18n/zh.json (100%) create mode 100644 GloryOfEfficiency/manifest.json rename {JoysOfEfficiency => GloryOfEfficiency}/packages.config (100%) delete mode 100644 JoysOfEfficiency/manifest.json diff --git a/JoysOfEfficiency.sln b/GloryOfEfficiency.sln similarity index 89% rename from JoysOfEfficiency.sln rename to GloryOfEfficiency.sln index 95b4f6e..1e5eb9b 100644 --- a/JoysOfEfficiency.sln +++ b/GloryOfEfficiency.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34714.143 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JoysOfEfficiency", "JoysOfEfficiency\JoysOfEfficiency.csproj", "{0302444C-4190-4C5D-A873-A1F80267961A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GloryOfEfficiency", "GloryOfEfficiency\GloryOfEfficiency.csproj", "{0302444C-4190-4C5D-A873-A1F80267961A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/JoysOfEfficiency/Automation/AnimalAutomation.cs b/GloryOfEfficiency/Automation/AnimalAutomation.cs similarity index 98% rename from JoysOfEfficiency/Automation/AnimalAutomation.cs rename to GloryOfEfficiency/Automation/AnimalAutomation.cs index 5799ead..b302c03 100644 --- a/JoysOfEfficiency/Automation/AnimalAutomation.cs +++ b/GloryOfEfficiency/Automation/AnimalAutomation.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Buildings; @@ -9,7 +9,7 @@ using StardewValley.Extensions; using StardewValley.Tools; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class AnimalAutomation { diff --git a/JoysOfEfficiency/Automation/AutoFisher.cs b/GloryOfEfficiency/Automation/AutoFisher.cs similarity index 98% rename from JoysOfEfficiency/Automation/AutoFisher.cs rename to GloryOfEfficiency/Automation/AutoFisher.cs index fa1f544..4bf5430 100644 --- a/JoysOfEfficiency/Automation/AutoFisher.cs +++ b/GloryOfEfficiency/Automation/AutoFisher.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.ItemTypeDefinitions; @@ -11,7 +11,7 @@ using StardewValley.Tools; using SVObject = StardewValley.Object; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class AutoFisher { diff --git a/JoysOfEfficiency/Automation/CollectibleCollector.cs b/GloryOfEfficiency/Automation/CollectibleCollector.cs similarity index 97% rename from JoysOfEfficiency/Automation/CollectibleCollector.cs rename to GloryOfEfficiency/Automation/CollectibleCollector.cs index ed2b8c1..b3ab883 100644 --- a/JoysOfEfficiency/Automation/CollectibleCollector.cs +++ b/GloryOfEfficiency/Automation/CollectibleCollector.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.TerrainFeatures; using StardewValley.Tools; using SVObject = StardewValley.Object; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class CollectibleCollector { diff --git a/JoysOfEfficiency/Automation/FarmCleaner.cs b/GloryOfEfficiency/Automation/FarmCleaner.cs similarity index 98% rename from JoysOfEfficiency/Automation/FarmCleaner.cs rename to GloryOfEfficiency/Automation/FarmCleaner.cs index 3bcccc9..17821bf 100644 --- a/JoysOfEfficiency/Automation/FarmCleaner.cs +++ b/GloryOfEfficiency/Automation/FarmCleaner.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Locations; using StardewValley.Tools; using Object = StardewValley.Object; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class FarmCleaner { diff --git a/JoysOfEfficiency/Automation/FenceGateAutomation.cs b/GloryOfEfficiency/Automation/FenceGateAutomation.cs similarity index 98% rename from JoysOfEfficiency/Automation/FenceGateAutomation.cs rename to GloryOfEfficiency/Automation/FenceGateAutomation.cs index 7ee88bb..1f4fb4c 100644 --- a/JoysOfEfficiency/Automation/FenceGateAutomation.cs +++ b/GloryOfEfficiency/Automation/FenceGateAutomation.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal enum FenceType { @@ -58,7 +58,7 @@ private static bool IsPlayerInClose(Fence fence, Farmer player) { Vector2 oVec = fence.TileLocation; Vector2 pVec = player.Tile; - return pVec == oVec || + return pVec == oVec || pVec == oVec + new Vector2(1, 0) || pVec == oVec + new Vector2(-1, 0) || pVec == oVec + new Vector2(0, 1) || pVec == oVec + new Vector2(0, -1); } diff --git a/JoysOfEfficiency/Automation/FlowerColorUnifier.cs b/GloryOfEfficiency/Automation/FlowerColorUnifier.cs similarity index 96% rename from JoysOfEfficiency/Automation/FlowerColorUnifier.cs rename to GloryOfEfficiency/Automation/FlowerColorUnifier.cs index 46206ce..85cf466 100644 --- a/JoysOfEfficiency/Automation/FlowerColorUnifier.cs +++ b/GloryOfEfficiency/Automation/FlowerColorUnifier.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Menus; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Menus; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewValley; using StardewValley.TerrainFeatures; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { using SVObject = StardewValley.Object; @@ -72,7 +72,7 @@ public static void UnifyFlowerColors() } else { - continue; + continue; } } @@ -109,7 +109,7 @@ public static void ToggleFlowerColorUnification() { GameLocation loc = Game1.currentLocation; Vector2 tileLoc = Game1.currentCursorTile; - Dictionary hoeDirts = + Dictionary hoeDirts = loc.terrainFeatures.Pairs .Where(p => p.Value is HoeDirt) .ToDictionary(p => p.Key, p => p.Value as HoeDirt); @@ -165,4 +165,4 @@ private static void RegisterFlowerColor(int whichFlower, Color color) Util.ShowHudMessage(string.Format(Translation.Get("flower.register"), whichFlower)); } } -} \ No newline at end of file +} diff --git a/JoysOfEfficiency/Automation/FoodAutomation.cs b/GloryOfEfficiency/Automation/FoodAutomation.cs similarity index 97% rename from JoysOfEfficiency/Automation/FoodAutomation.cs rename to GloryOfEfficiency/Automation/FoodAutomation.cs index b95e183..a7ec712 100644 --- a/JoysOfEfficiency/Automation/FoodAutomation.cs +++ b/GloryOfEfficiency/Automation/FoodAutomation.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using StardewModdingAPI; using StardewValley; using StardewValley.Tools; @@ -9,7 +9,7 @@ using StardewValley.GameData.Objects; using SVObject = StardewValley.Object; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class FoodAutomation { diff --git a/JoysOfEfficiency/Automation/HarvestAutomation.cs b/GloryOfEfficiency/Automation/HarvestAutomation.cs similarity index 99% rename from JoysOfEfficiency/Automation/HarvestAutomation.cs rename to GloryOfEfficiency/Automation/HarvestAutomation.cs index ffc87ed..b6ef575 100644 --- a/JoysOfEfficiency/Automation/HarvestAutomation.cs +++ b/GloryOfEfficiency/Automation/HarvestAutomation.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Objects; @@ -10,7 +10,7 @@ using StardewValley.Tools; using SVObject = StardewValley.Object; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class HarvestAutomation { diff --git a/JoysOfEfficiency/Automation/InventoryAutomation.cs b/GloryOfEfficiency/Automation/InventoryAutomation.cs similarity index 96% rename from JoysOfEfficiency/Automation/InventoryAutomation.cs rename to GloryOfEfficiency/Automation/InventoryAutomation.cs index 6c55091..86cbe02 100644 --- a/JoysOfEfficiency/Automation/InventoryAutomation.cs +++ b/GloryOfEfficiency/Automation/InventoryAutomation.cs @@ -1,9 +1,9 @@ -using JoysOfEfficiency.Huds; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Huds; +using GloryOfEfficiency.Utils; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class InventoryAutomation { diff --git a/JoysOfEfficiency/Automation/MachineOperator.cs b/GloryOfEfficiency/Automation/MachineOperator.cs similarity index 98% rename from JoysOfEfficiency/Automation/MachineOperator.cs rename to GloryOfEfficiency/Automation/MachineOperator.cs index f496cb7..4585805 100644 --- a/JoysOfEfficiency/Automation/MachineOperator.cs +++ b/GloryOfEfficiency/Automation/MachineOperator.cs @@ -1,6 +1,6 @@ using System.Linq; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Locations; @@ -8,7 +8,7 @@ using SVObject = StardewValley.Object; using static StardewValley.Game1; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class MachineOperator { diff --git a/JoysOfEfficiency/Automation/MailAutomation.cs b/GloryOfEfficiency/Automation/MailAutomation.cs similarity index 96% rename from JoysOfEfficiency/Automation/MailAutomation.cs rename to GloryOfEfficiency/Automation/MailAutomation.cs index fed0ac2..b9ff942 100644 --- a/JoysOfEfficiency/Automation/MailAutomation.cs +++ b/GloryOfEfficiency/Automation/MailAutomation.cs @@ -1,11 +1,11 @@ using System; using System.Linq; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; using StardewValley; using StardewValley.Menus; using StardewValley.Quests; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class MailAutomation { diff --git a/JoysOfEfficiency/Automation/TrashCanScavenger.cs b/GloryOfEfficiency/Automation/TrashCanScavenger.cs similarity index 94% rename from JoysOfEfficiency/Automation/TrashCanScavenger.cs rename to GloryOfEfficiency/Automation/TrashCanScavenger.cs index f23a47b..b1d7c7a 100644 --- a/JoysOfEfficiency/Automation/TrashCanScavenger.cs +++ b/GloryOfEfficiency/Automation/TrashCanScavenger.cs @@ -1,10 +1,10 @@ -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Locations; using xTile.Layers; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class TrashCanScavenger { diff --git a/JoysOfEfficiency/Automation/WateringCanRefiller.cs b/GloryOfEfficiency/Automation/WateringCanRefiller.cs similarity index 87% rename from JoysOfEfficiency/Automation/WateringCanRefiller.cs rename to GloryOfEfficiency/Automation/WateringCanRefiller.cs index 73bea74..00b5feb 100644 --- a/JoysOfEfficiency/Automation/WateringCanRefiller.cs +++ b/GloryOfEfficiency/Automation/WateringCanRefiller.cs @@ -1,9 +1,9 @@ -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using StardewValley; using StardewValley.Tools; -namespace JoysOfEfficiency.Automation +namespace GloryOfEfficiency.Automation { internal class WateringCanRefiller { diff --git a/JoysOfEfficiency/Configs/ConfigCustomAnimalTool.cs b/GloryOfEfficiency/Configs/ConfigCustomAnimalTool.cs similarity index 95% rename from JoysOfEfficiency/Configs/ConfigCustomAnimalTool.cs rename to GloryOfEfficiency/Configs/ConfigCustomAnimalTool.cs index 0b65388..7663d9d 100644 --- a/JoysOfEfficiency/Configs/ConfigCustomAnimalTool.cs +++ b/GloryOfEfficiency/Configs/ConfigCustomAnimalTool.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using StardewValley; using StardewValley.Tools; -namespace JoysOfEfficiency.Configs +namespace GloryOfEfficiency.Configs { class ConfigCustomAnimalTool { diff --git a/JoysOfEfficiency/Configs/CustomAnimalTool.cs b/GloryOfEfficiency/Configs/CustomAnimalTool.cs similarity index 90% rename from JoysOfEfficiency/Configs/CustomAnimalTool.cs rename to GloryOfEfficiency/Configs/CustomAnimalTool.cs index 76067bb..95850aa 100644 --- a/JoysOfEfficiency/Configs/CustomAnimalTool.cs +++ b/GloryOfEfficiency/Configs/CustomAnimalTool.cs @@ -1,4 +1,4 @@ -namespace JoysOfEfficiency.Configs +namespace GloryOfEfficiency.Configs { class CustomAnimalTool { diff --git a/JoysOfEfficiency/Core/Config.cs b/GloryOfEfficiency/Core/Config.cs similarity index 99% rename from JoysOfEfficiency/Core/Config.cs rename to GloryOfEfficiency/Core/Config.cs index 151f6db..9fb47d9 100644 --- a/JoysOfEfficiency/Core/Config.cs +++ b/GloryOfEfficiency/Core/Config.cs @@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Input; using StardewModdingAPI; -namespace JoysOfEfficiency.Core +namespace GloryOfEfficiency.Core { internal class Config { diff --git a/JoysOfEfficiency/Core/ConfigLimitation.cs b/GloryOfEfficiency/Core/ConfigLimitation.cs similarity index 96% rename from JoysOfEfficiency/Core/ConfigLimitation.cs rename to GloryOfEfficiency/Core/ConfigLimitation.cs index 0cb8e14..2700218 100644 --- a/JoysOfEfficiency/Core/ConfigLimitation.cs +++ b/GloryOfEfficiency/Core/ConfigLimitation.cs @@ -1,6 +1,6 @@ -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; -namespace JoysOfEfficiency.Core +namespace GloryOfEfficiency.Core { internal class ConfigLimitation { diff --git a/JoysOfEfficiency/Core/InstanceHolder.cs b/GloryOfEfficiency/Core/InstanceHolder.cs similarity index 95% rename from JoysOfEfficiency/Core/InstanceHolder.cs rename to GloryOfEfficiency/Core/InstanceHolder.cs index 9ca77f5..da6a157 100644 --- a/JoysOfEfficiency/Core/InstanceHolder.cs +++ b/GloryOfEfficiency/Core/InstanceHolder.cs @@ -1,8 +1,8 @@ -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; using StardewModdingAPI; using StardewValley; -namespace JoysOfEfficiency.Core +namespace GloryOfEfficiency.Core { /// /// This class holds mod and config instance and exposes some useful methods. diff --git a/JoysOfEfficiency/Core/ModEntry.cs b/GloryOfEfficiency/Core/ModEntry.cs similarity index 94% rename from JoysOfEfficiency/Core/ModEntry.cs rename to GloryOfEfficiency/Core/ModEntry.cs index 078680f..cc9b3c7 100644 --- a/JoysOfEfficiency/Core/ModEntry.cs +++ b/GloryOfEfficiency/Core/ModEntry.cs @@ -1,16 +1,16 @@ using System.IO; -using JoysOfEfficiency.Automation; -using JoysOfEfficiency.EventHandler; -using JoysOfEfficiency.Harmony; -using JoysOfEfficiency.Huds; -using JoysOfEfficiency.ModCheckers; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Automation; +using GloryOfEfficiency.EventHandler; +using GloryOfEfficiency.Harmony; +using GloryOfEfficiency.Huds; +using GloryOfEfficiency.ModCheckers; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; -namespace JoysOfEfficiency.Core +namespace GloryOfEfficiency.Core { using Player = Farmer; diff --git a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs b/GloryOfEfficiency/EventHandler/ArtifactSpotDigger.cs similarity index 95% rename from JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs rename to GloryOfEfficiency/EventHandler/ArtifactSpotDigger.cs index 9541288..260765c 100644 --- a/JoysOfEfficiency/EventHandler/ArtifactSpotDigger.cs +++ b/GloryOfEfficiency/EventHandler/ArtifactSpotDigger.cs @@ -1,11 +1,11 @@ -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewValley; using StardewValley.TerrainFeatures; using StardewValley.Tools; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class ArtifactSpotDigger { diff --git a/JoysOfEfficiency/EventHandler/EventHolder.cs b/GloryOfEfficiency/EventHandler/EventHolder.cs similarity index 93% rename from JoysOfEfficiency/EventHandler/EventHolder.cs rename to GloryOfEfficiency/EventHandler/EventHolder.cs index 71342a3..13debc7 100644 --- a/JoysOfEfficiency/EventHandler/EventHolder.cs +++ b/GloryOfEfficiency/EventHandler/EventHolder.cs @@ -1,7 +1,7 @@ -using JoysOfEfficiency.Huds; +using GloryOfEfficiency.Huds; using StardewModdingAPI.Events; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class EventHolder { diff --git a/JoysOfEfficiency/EventHandler/GraphicsEvents.cs b/GloryOfEfficiency/EventHandler/GraphicsEvents.cs similarity index 90% rename from JoysOfEfficiency/EventHandler/GraphicsEvents.cs rename to GloryOfEfficiency/EventHandler/GraphicsEvents.cs index 886b812..aa71ed9 100644 --- a/JoysOfEfficiency/EventHandler/GraphicsEvents.cs +++ b/GloryOfEfficiency/EventHandler/GraphicsEvents.cs @@ -1,14 +1,14 @@ -using JoysOfEfficiency.Automation; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Huds; -using JoysOfEfficiency.Misc; +using GloryOfEfficiency.Automation; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Huds; +using GloryOfEfficiency.Misc; using StardewModdingAPI.Events; using StardewValley; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Tools; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class GraphicsEvents { diff --git a/JoysOfEfficiency/EventHandler/InputEvents.cs b/GloryOfEfficiency/EventHandler/InputEvents.cs similarity index 88% rename from JoysOfEfficiency/EventHandler/InputEvents.cs rename to GloryOfEfficiency/EventHandler/InputEvents.cs index ae7d0b6..d2fb592 100644 --- a/JoysOfEfficiency/EventHandler/InputEvents.cs +++ b/GloryOfEfficiency/EventHandler/InputEvents.cs @@ -1,11 +1,11 @@ -using JoysOfEfficiency.Automation; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Menus; +using GloryOfEfficiency.Automation; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Menus; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class InputEvents { diff --git a/JoysOfEfficiency/EventHandler/MenuEvents.cs b/GloryOfEfficiency/EventHandler/MenuEvents.cs similarity index 85% rename from JoysOfEfficiency/EventHandler/MenuEvents.cs rename to GloryOfEfficiency/EventHandler/MenuEvents.cs index a6f5bcf..becae96 100644 --- a/JoysOfEfficiency/EventHandler/MenuEvents.cs +++ b/GloryOfEfficiency/EventHandler/MenuEvents.cs @@ -1,9 +1,9 @@ -using JoysOfEfficiency.Automation; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Automation; +using GloryOfEfficiency.Core; using StardewModdingAPI.Events; using StardewValley.Menus; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class MenuEvents { diff --git a/JoysOfEfficiency/EventHandler/SaveEvents.cs b/GloryOfEfficiency/EventHandler/SaveEvents.cs similarity index 85% rename from JoysOfEfficiency/EventHandler/SaveEvents.cs rename to GloryOfEfficiency/EventHandler/SaveEvents.cs index 267e570..af757da 100644 --- a/JoysOfEfficiency/EventHandler/SaveEvents.cs +++ b/GloryOfEfficiency/EventHandler/SaveEvents.cs @@ -1,10 +1,10 @@ using System; -using JoysOfEfficiency.Automation; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Misc; +using GloryOfEfficiency.Automation; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Misc; using StardewModdingAPI; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class SaveEvents { diff --git a/JoysOfEfficiency/EventHandler/UpdateEvents.cs b/GloryOfEfficiency/EventHandler/UpdateEvents.cs similarity index 96% rename from JoysOfEfficiency/EventHandler/UpdateEvents.cs rename to GloryOfEfficiency/EventHandler/UpdateEvents.cs index fc756f0..a79ffc4 100644 --- a/JoysOfEfficiency/EventHandler/UpdateEvents.cs +++ b/GloryOfEfficiency/EventHandler/UpdateEvents.cs @@ -1,9 +1,9 @@ using System; -using JoysOfEfficiency.Automation; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Huds; -using JoysOfEfficiency.Misc; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Automation; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Huds; +using GloryOfEfficiency.Misc; +using GloryOfEfficiency.Utils; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -11,7 +11,7 @@ using StardewValley.Menus; using StardewValley.Tools; -namespace JoysOfEfficiency.EventHandler +namespace GloryOfEfficiency.EventHandler { internal class UpdateEvents { diff --git a/JoysOfEfficiency/FeaturesAndConfigs.md b/GloryOfEfficiency/FeaturesAndConfigs.md similarity index 100% rename from JoysOfEfficiency/FeaturesAndConfigs.md rename to GloryOfEfficiency/FeaturesAndConfigs.md diff --git a/JoysOfEfficiency/JoysOfEfficiency.csproj b/GloryOfEfficiency/GloryOfEfficiency.csproj similarity index 94% rename from JoysOfEfficiency/JoysOfEfficiency.csproj rename to GloryOfEfficiency/GloryOfEfficiency.csproj index 671c1ef..fb2f67b 100644 --- a/JoysOfEfficiency/JoysOfEfficiency.csproj +++ b/GloryOfEfficiency/GloryOfEfficiency.csproj @@ -5,10 +5,10 @@ net6.0 Library Properties - JoysOfEfficiency - JoysOfEfficiency + GloryOfEfficiency + GloryOfEfficiency 512 - 1.5.0 + 1.0.0 true @@ -56,7 +56,7 @@ PreserveNewest - + diff --git a/JoysOfEfficiency/Harmony/HarmonyPatcher.cs b/GloryOfEfficiency/Harmony/HarmonyPatcher.cs similarity index 87% rename from JoysOfEfficiency/Harmony/HarmonyPatcher.cs rename to GloryOfEfficiency/Harmony/HarmonyPatcher.cs index 0e7d354..78fcade 100644 --- a/JoysOfEfficiency/Harmony/HarmonyPatcher.cs +++ b/GloryOfEfficiency/Harmony/HarmonyPatcher.cs @@ -1,6 +1,6 @@ using HarmonyLib; -namespace JoysOfEfficiency.Harmony +namespace GloryOfEfficiency.Harmony { internal class HarmonyPatcher { diff --git a/JoysOfEfficiency/Huds/FishInformationHud.cs b/GloryOfEfficiency/Huds/FishInformationHud.cs similarity index 98% rename from JoysOfEfficiency/Huds/FishInformationHud.cs rename to GloryOfEfficiency/Huds/FishInformationHud.cs index d3af04b..c06b016 100644 --- a/JoysOfEfficiency/Huds/FishInformationHud.cs +++ b/GloryOfEfficiency/Huds/FishInformationHud.cs @@ -1,6 +1,6 @@ using System; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; @@ -8,7 +8,7 @@ using StardewValley.Menus; using Object = StardewValley.Object; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { internal class FishInformationHud { diff --git a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs b/GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs similarity index 99% rename from JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs rename to GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs index 80bce76..01d37aa 100644 --- a/JoysOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -1,4 +1,4 @@ -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; @@ -16,7 +16,7 @@ using Object = StardewValley.Object; using Rectangle = Microsoft.Xna.Framework.Rectangle; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { public class FishingProbabilitiesBox { @@ -556,8 +556,8 @@ private static int DrawProbBox(Dictionary probabilities) { x_space = 8 + w; y = yOffset + 16; - } - else + } + else y += square + 16; // Track Count @@ -592,7 +592,7 @@ private static Size GetProbBoxSize(Dictionary probabilities) { x_space = 8 + w; y_max = true; - } + } // Index fishCount++; @@ -612,7 +612,7 @@ private static void DrawTackleBox(Dictionary attachments, int x_add xOffset = InstanceHolder.Config.ProbBoxCoordinates.X + x_add; yOffset = InstanceHolder.Config.ProbBoxCoordinates.Y; } - else + else { xOffset = InstanceHolder.Config.TackleBoxCoordinates.X; yOffset = InstanceHolder.Config.TackleBoxCoordinates.Y; @@ -626,7 +626,7 @@ private static void DrawTackleBox(Dictionary attachments, int x_add yOffset = 0; } - //Draw Window for Bait and Bobbers + //Draw Window for Bait and Bobbers IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), xOffset, yOffset, size.Width, size.Height, Color.White, 1f, false, -1f); const int square = (int)(Game1.tileSize / 1.5); int x = xOffset + 8; diff --git a/JoysOfEfficiency/Huds/FpsCounter.cs b/GloryOfEfficiency/Huds/FpsCounter.cs similarity index 92% rename from JoysOfEfficiency/Huds/FpsCounter.cs rename to GloryOfEfficiency/Huds/FpsCounter.cs index eb9e897..6ead4dc 100644 --- a/JoysOfEfficiency/Huds/FpsCounter.cs +++ b/GloryOfEfficiency/Huds/FpsCounter.cs @@ -1,10 +1,10 @@ using System; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using StardewModdingAPI.Events; using StardewValley; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { internal class FpsCounter { diff --git a/JoysOfEfficiency/Huds/GiftInformationTooltip.cs b/GloryOfEfficiency/Huds/GiftInformationTooltip.cs similarity index 97% rename from JoysOfEfficiency/Huds/GiftInformationTooltip.cs rename to GloryOfEfficiency/Huds/GiftInformationTooltip.cs index 7d883b6..960b19c 100644 --- a/JoysOfEfficiency/Huds/GiftInformationTooltip.cs +++ b/GloryOfEfficiency/Huds/GiftInformationTooltip.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewValley; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { public class GiftInformationTooltip { diff --git a/JoysOfEfficiency/Huds/MineHud.cs b/GloryOfEfficiency/Huds/MineHud.cs similarity index 97% rename from JoysOfEfficiency/Huds/MineHud.cs rename to GloryOfEfficiency/Huds/MineHud.cs index 7d3f053..9e29edb 100644 --- a/JoysOfEfficiency/Huds/MineHud.cs +++ b/GloryOfEfficiency/Huds/MineHud.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewValley; using StardewValley.Locations; using StardewValley.Monsters; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { internal class MineHud { diff --git a/JoysOfEfficiency/Huds/MineIcons.cs b/GloryOfEfficiency/Huds/MineIcons.cs similarity index 97% rename from JoysOfEfficiency/Huds/MineIcons.cs rename to GloryOfEfficiency/Huds/MineIcons.cs index 46b5162..6afd0dd 100644 --- a/JoysOfEfficiency/Huds/MineIcons.cs +++ b/GloryOfEfficiency/Huds/MineIcons.cs @@ -1,11 +1,11 @@ -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { public class MineIcons { @@ -23,7 +23,7 @@ public static void Init(IModHelper helper) _iconMonster = helper.ModContent.Load("assets/icon_monster.png"); _iconLadder = helper.ModContent.Load("assets/icon_ladder.png"); int x = 16 + OffsetX; - + _logger.Log($"x:{x}"); } diff --git a/JoysOfEfficiency/Huds/PausedHud.cs b/GloryOfEfficiency/Huds/PausedHud.cs similarity index 90% rename from JoysOfEfficiency/Huds/PausedHud.cs rename to GloryOfEfficiency/Huds/PausedHud.cs index 3cfcd34..45a966b 100644 --- a/JoysOfEfficiency/Huds/PausedHud.cs +++ b/GloryOfEfficiency/Huds/PausedHud.cs @@ -1,11 +1,11 @@ -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; using StardewValley; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { internal class PausedHud { diff --git a/JoysOfEfficiency/Huds/ShippingEstimationInfoBox.cs b/GloryOfEfficiency/Huds/ShippingEstimationInfoBox.cs similarity index 95% rename from JoysOfEfficiency/Huds/ShippingEstimationInfoBox.cs rename to GloryOfEfficiency/Huds/ShippingEstimationInfoBox.cs index 86a9ccc..fca1226 100644 --- a/JoysOfEfficiency/Huds/ShippingEstimationInfoBox.cs +++ b/GloryOfEfficiency/Huds/ShippingEstimationInfoBox.cs @@ -1,14 +1,14 @@ using System; using System.Linq; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.Huds +namespace GloryOfEfficiency.Huds { internal class ShippingEstimationInfoBox { diff --git a/JoysOfEfficiency/Menus/JoeMenu.cs b/GloryOfEfficiency/Menus/JoeMenu.cs similarity index 99% rename from JoysOfEfficiency/Menus/JoeMenu.cs rename to GloryOfEfficiency/Menus/JoeMenu.cs index e20b19f..f5feb17 100644 --- a/JoysOfEfficiency/Menus/JoeMenu.cs +++ b/GloryOfEfficiency/Menus/JoeMenu.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.OptionsElements; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.OptionsElements; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; @@ -9,7 +9,7 @@ using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.Menus +namespace GloryOfEfficiency.Menus { internal class JoeMenu : IClickableMenu { diff --git a/JoysOfEfficiency/Menus/RegisterFlowerMenu.cs b/GloryOfEfficiency/Menus/RegisterFlowerMenu.cs similarity index 97% rename from JoysOfEfficiency/Menus/RegisterFlowerMenu.cs rename to GloryOfEfficiency/Menus/RegisterFlowerMenu.cs index a5a169b..7fb8bef 100644 --- a/JoysOfEfficiency/Menus/RegisterFlowerMenu.cs +++ b/GloryOfEfficiency/Menus/RegisterFlowerMenu.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.OptionsElements; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.OptionsElements; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.Menus +namespace GloryOfEfficiency.Menus { internal class RegisterFlowerMenu : IClickableMenu { @@ -74,7 +74,7 @@ public override void receiveLeftClick(int x, int y, bool playSound = true) } y -= element.bounds.Height + MARGIN_COMPONENTS; } - + } public override void leftClickHeld(int x, int y) diff --git a/JoysOfEfficiency/Misc/IdlePause.cs b/GloryOfEfficiency/Misc/IdlePause.cs similarity index 92% rename from JoysOfEfficiency/Misc/IdlePause.cs rename to GloryOfEfficiency/Misc/IdlePause.cs index cdd82bb..0037aee 100644 --- a/JoysOfEfficiency/Misc/IdlePause.cs +++ b/GloryOfEfficiency/Misc/IdlePause.cs @@ -1,9 +1,9 @@ -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Huds; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Huds; +using GloryOfEfficiency.Utils; using StardewValley; -namespace JoysOfEfficiency.Misc +namespace GloryOfEfficiency.Misc { internal class IdlePause { diff --git a/JoysOfEfficiency/ModCheckers/ModChecker.cs b/GloryOfEfficiency/ModCheckers/ModChecker.cs similarity index 87% rename from JoysOfEfficiency/ModCheckers/ModChecker.cs rename to GloryOfEfficiency/ModCheckers/ModChecker.cs index fa46bf0..a4f4e5b 100644 --- a/JoysOfEfficiency/ModCheckers/ModChecker.cs +++ b/GloryOfEfficiency/ModCheckers/ModChecker.cs @@ -1,6 +1,6 @@ using StardewModdingAPI; -namespace JoysOfEfficiency.ModCheckers +namespace GloryOfEfficiency.ModCheckers { public class ModChecker { diff --git a/JoysOfEfficiency/OptionsElements/ButtonWithLabel.cs b/GloryOfEfficiency/OptionsElements/ButtonWithLabel.cs similarity index 94% rename from JoysOfEfficiency/OptionsElements/ButtonWithLabel.cs rename to GloryOfEfficiency/OptionsElements/ButtonWithLabel.cs index e8ef225..d860822 100644 --- a/JoysOfEfficiency/OptionsElements/ButtonWithLabel.cs +++ b/GloryOfEfficiency/OptionsElements/ButtonWithLabel.cs @@ -1,11 +1,11 @@ using System; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class ButtonWithLabel : OptionsElement { @@ -15,7 +15,7 @@ internal class ButtonWithLabel : OptionsElement private readonly Func _isDisabled; public ButtonWithLabel(string label, int which, - Action onButtonPressed = null, Func isDisabled = null) + Action onButtonPressed = null, Func isDisabled = null) : base(label, -1, -1, 9 * Game1.pixelZoom, 9 * Game1.pixelZoom, which) { this.label = InstanceHolder.Translation.Get($"options.{label}"); @@ -26,7 +26,7 @@ public ButtonWithLabel(string label, int which, public override void receiveLeftClick(int x, int y) { base.receiveLeftClick(x, y); - + if (x >= _buttonRect.Left && x <= _buttonRect.Right) { _onButtonPressed(whichOption); diff --git a/JoysOfEfficiency/OptionsElements/ColorBox.cs b/GloryOfEfficiency/OptionsElements/ColorBox.cs similarity index 95% rename from JoysOfEfficiency/OptionsElements/ColorBox.cs rename to GloryOfEfficiency/OptionsElements/ColorBox.cs index 5f3545e..d2a2ce2 100644 --- a/JoysOfEfficiency/OptionsElements/ColorBox.cs +++ b/GloryOfEfficiency/OptionsElements/ColorBox.cs @@ -1,9 +1,9 @@ -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class ColorBox : OptionsElement { diff --git a/JoysOfEfficiency/OptionsElements/EmptyLabel.cs b/GloryOfEfficiency/OptionsElements/EmptyLabel.cs similarity index 86% rename from JoysOfEfficiency/OptionsElements/EmptyLabel.cs rename to GloryOfEfficiency/OptionsElements/EmptyLabel.cs index fbb4094..7d63a86 100644 --- a/JoysOfEfficiency/OptionsElements/EmptyLabel.cs +++ b/GloryOfEfficiency/OptionsElements/EmptyLabel.cs @@ -1,7 +1,7 @@ using Microsoft.Xna.Framework.Graphics; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class EmptyLabel : LabelComponent { diff --git a/JoysOfEfficiency/OptionsElements/LabelComponent.cs b/GloryOfEfficiency/OptionsElements/LabelComponent.cs similarity index 92% rename from JoysOfEfficiency/OptionsElements/LabelComponent.cs rename to GloryOfEfficiency/OptionsElements/LabelComponent.cs index a5adf58..6558db1 100644 --- a/JoysOfEfficiency/OptionsElements/LabelComponent.cs +++ b/GloryOfEfficiency/OptionsElements/LabelComponent.cs @@ -3,7 +3,7 @@ using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class LabelComponent : OptionsElement { diff --git a/JoysOfEfficiency/OptionsElements/MenuTab.cs b/GloryOfEfficiency/OptionsElements/MenuTab.cs similarity index 91% rename from JoysOfEfficiency/OptionsElements/MenuTab.cs rename to GloryOfEfficiency/OptionsElements/MenuTab.cs index 14270be..dc868dd 100644 --- a/JoysOfEfficiency/OptionsElements/MenuTab.cs +++ b/GloryOfEfficiency/OptionsElements/MenuTab.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class MenuTab { diff --git a/JoysOfEfficiency/OptionsElements/ModifiedCheckBox.cs b/GloryOfEfficiency/OptionsElements/ModifiedCheckBox.cs similarity index 95% rename from JoysOfEfficiency/OptionsElements/ModifiedCheckBox.cs rename to GloryOfEfficiency/OptionsElements/ModifiedCheckBox.cs index f0f33b4..7e579c7 100644 --- a/JoysOfEfficiency/OptionsElements/ModifiedCheckBox.cs +++ b/GloryOfEfficiency/OptionsElements/ModifiedCheckBox.cs @@ -1,11 +1,11 @@ using System; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class ModifiedCheckBox : OptionsElementWithLabel { diff --git a/JoysOfEfficiency/OptionsElements/ModifiedClickListener.cs b/GloryOfEfficiency/OptionsElements/ModifiedClickListener.cs similarity index 97% rename from JoysOfEfficiency/OptionsElements/ModifiedClickListener.cs rename to GloryOfEfficiency/OptionsElements/ModifiedClickListener.cs index 8b01b79..c5cd5a5 100644 --- a/JoysOfEfficiency/OptionsElements/ModifiedClickListener.cs +++ b/GloryOfEfficiency/OptionsElements/ModifiedClickListener.cs @@ -1,6 +1,6 @@ using System; -using JoysOfEfficiency.Core; -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Core; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; @@ -8,7 +8,7 @@ using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class ModifiedClickListener : OptionsElement { diff --git a/JoysOfEfficiency/OptionsElements/ModifiedInputListener.cs b/GloryOfEfficiency/OptionsElements/ModifiedInputListener.cs similarity index 98% rename from JoysOfEfficiency/OptionsElements/ModifiedInputListener.cs rename to GloryOfEfficiency/OptionsElements/ModifiedInputListener.cs index 7d793bf..9bc5b34 100644 --- a/JoysOfEfficiency/OptionsElements/ModifiedInputListener.cs +++ b/GloryOfEfficiency/OptionsElements/ModifiedInputListener.cs @@ -1,5 +1,5 @@ using System; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; @@ -7,7 +7,7 @@ using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class ModifiedInputListener : OptionsElement { diff --git a/JoysOfEfficiency/OptionsElements/ModifiedSlider.cs b/GloryOfEfficiency/OptionsElements/ModifiedSlider.cs similarity index 97% rename from JoysOfEfficiency/OptionsElements/ModifiedSlider.cs rename to GloryOfEfficiency/OptionsElements/ModifiedSlider.cs index 3e0b5ee..08c433e 100644 --- a/JoysOfEfficiency/OptionsElements/ModifiedSlider.cs +++ b/GloryOfEfficiency/OptionsElements/ModifiedSlider.cs @@ -1,11 +1,11 @@ using System; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { internal class ModifiedSlider : OptionsElementWithLabel { diff --git a/JoysOfEfficiency/OptionsElements/OptionsElementWithLabel.cs b/GloryOfEfficiency/OptionsElements/OptionsElementWithLabel.cs similarity index 89% rename from JoysOfEfficiency/OptionsElements/OptionsElementWithLabel.cs rename to GloryOfEfficiency/OptionsElements/OptionsElementWithLabel.cs index cbc77cb..7521bb1 100644 --- a/JoysOfEfficiency/OptionsElements/OptionsElementWithLabel.cs +++ b/GloryOfEfficiency/OptionsElements/OptionsElementWithLabel.cs @@ -1,8 +1,8 @@ -using JoysOfEfficiency.Utils; +using GloryOfEfficiency.Utils; using Microsoft.Xna.Framework.Graphics; using StardewValley.Menus; -namespace JoysOfEfficiency.OptionsElements +namespace GloryOfEfficiency.OptionsElements { public abstract class OptionsElementWithLabel : OptionsElement { diff --git a/JoysOfEfficiency/Properties/AssemblyInfo.cs b/GloryOfEfficiency/Properties/AssemblyInfo.cs similarity index 88% rename from JoysOfEfficiency/Properties/AssemblyInfo.cs rename to GloryOfEfficiency/Properties/AssemblyInfo.cs index 0017fc6..a68bebe 100644 --- a/JoysOfEfficiency/Properties/AssemblyInfo.cs +++ b/GloryOfEfficiency/Properties/AssemblyInfo.cs @@ -4,12 +4,12 @@ // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 // アセンブリに関連付けられている情報を変更するには、 // これらの属性値を変更してください。 -[assembly: AssemblyTitle("JoysOfEfficiency")] +[assembly: AssemblyTitle("GloryOfEfficiency")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("JoysOfEfficiency")] -[assembly: AssemblyCopyright("Copyright yakminepunyo© 2018")] +[assembly: AssemblyProduct("GloryOfEfficiency")] +[assembly: AssemblyCopyright("Copyright yakminepunyo© 2018, Copyright Hackswell© 2024")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/JoysOfEfficiency/Properties/Resources.Designer.cs b/GloryOfEfficiency/Properties/Resources.Designer.cs similarity index 96% rename from JoysOfEfficiency/Properties/Resources.Designer.cs rename to GloryOfEfficiency/Properties/Resources.Designer.cs index a1a6e95..51c4cf4 100644 --- a/JoysOfEfficiency/Properties/Resources.Designer.cs +++ b/GloryOfEfficiency/Properties/Resources.Designer.cs @@ -16,7 +16,7 @@ using System.Resources; using System.Runtime.CompilerServices; -namespace JoysOfEfficiency.Properties { +namespace GloryOfEfficiency.Properties { /// /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 /// @@ -44,7 +44,7 @@ internal Resources() { internal static ResourceManager ResourceManager { get { if (ReferenceEquals(resourceMan, null)) { - ResourceManager temp = new ResourceManager("JoysOfEfficiency.Properties.Resources", typeof(Resources).Assembly); + ResourceManager temp = new ResourceManager("GloryOfEfficiency.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; diff --git a/JoysOfEfficiency/Properties/Resources.resx b/GloryOfEfficiency/Properties/Resources.resx similarity index 100% rename from JoysOfEfficiency/Properties/Resources.resx rename to GloryOfEfficiency/Properties/Resources.resx diff --git a/JoysOfEfficiency/Utils/ConfigHolder.cs b/GloryOfEfficiency/Utils/ConfigHolder.cs similarity index 96% rename from JoysOfEfficiency/Utils/ConfigHolder.cs rename to GloryOfEfficiency/Utils/ConfigHolder.cs index 57027e0..369cae7 100644 --- a/JoysOfEfficiency/Utils/ConfigHolder.cs +++ b/GloryOfEfficiency/Utils/ConfigHolder.cs @@ -1,7 +1,7 @@ using System.IO; using System.Text.Json; -namespace JoysOfEfficiency.Utils +namespace GloryOfEfficiency.Utils { public abstract class ConfigHolder { diff --git a/JoysOfEfficiency/Utils/CustomAnimalConfigHolder.cs b/GloryOfEfficiency/Utils/CustomAnimalConfigHolder.cs similarity index 82% rename from JoysOfEfficiency/Utils/CustomAnimalConfigHolder.cs rename to GloryOfEfficiency/Utils/CustomAnimalConfigHolder.cs index 69711ad..02fc390 100644 --- a/JoysOfEfficiency/Utils/CustomAnimalConfigHolder.cs +++ b/GloryOfEfficiency/Utils/CustomAnimalConfigHolder.cs @@ -1,6 +1,6 @@ -using JoysOfEfficiency.Configs; +using GloryOfEfficiency.Configs; -namespace JoysOfEfficiency.Utils +namespace GloryOfEfficiency.Utils { internal class CustomAnimalConfigHolder : ConfigHolder { diff --git a/JoysOfEfficiency/Utils/Logger.cs b/GloryOfEfficiency/Utils/Logger.cs similarity index 95% rename from JoysOfEfficiency/Utils/Logger.cs rename to GloryOfEfficiency/Utils/Logger.cs index 7db76cc..8ff64fc 100644 --- a/JoysOfEfficiency/Utils/Logger.cs +++ b/GloryOfEfficiency/Utils/Logger.cs @@ -1,6 +1,6 @@ using StardewModdingAPI; -namespace JoysOfEfficiency.Utils +namespace GloryOfEfficiency.Utils { public class Logger { diff --git a/JoysOfEfficiency/Utils/Util.cs b/GloryOfEfficiency/Utils/Util.cs similarity index 99% rename from JoysOfEfficiency/Utils/Util.cs rename to GloryOfEfficiency/Utils/Util.cs index be1dcb1..47db312 100644 --- a/JoysOfEfficiency/Utils/Util.cs +++ b/GloryOfEfficiency/Utils/Util.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using JoysOfEfficiency.Core; +using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; @@ -13,7 +13,7 @@ using static StardewValley.Game1; using Object = StardewValley.Object; -namespace JoysOfEfficiency.Utils +namespace GloryOfEfficiency.Utils { using Player = Farmer; using SVObject = Object; diff --git a/JoysOfEfficiency/WhatsNew.md b/GloryOfEfficiency/WhatsNew.md similarity index 100% rename from JoysOfEfficiency/WhatsNew.md rename to GloryOfEfficiency/WhatsNew.md diff --git a/JoysOfEfficiency/assets/icon_ladder.png b/GloryOfEfficiency/assets/icon_ladder.png similarity index 100% rename from JoysOfEfficiency/assets/icon_ladder.png rename to GloryOfEfficiency/assets/icon_ladder.png diff --git a/JoysOfEfficiency/assets/icon_monster.png b/GloryOfEfficiency/assets/icon_monster.png similarity index 100% rename from JoysOfEfficiency/assets/icon_monster.png rename to GloryOfEfficiency/assets/icon_monster.png diff --git a/JoysOfEfficiency/assets/icon_pickaxe.png b/GloryOfEfficiency/assets/icon_pickaxe.png similarity index 100% rename from JoysOfEfficiency/assets/icon_pickaxe.png rename to GloryOfEfficiency/assets/icon_pickaxe.png diff --git a/JoysOfEfficiency/i18n/de.json b/GloryOfEfficiency/i18n/de.json similarity index 100% rename from JoysOfEfficiency/i18n/de.json rename to GloryOfEfficiency/i18n/de.json diff --git a/JoysOfEfficiency/i18n/default.json b/GloryOfEfficiency/i18n/default.json similarity index 100% rename from JoysOfEfficiency/i18n/default.json rename to GloryOfEfficiency/i18n/default.json diff --git a/JoysOfEfficiency/i18n/es.json b/GloryOfEfficiency/i18n/es.json similarity index 100% rename from JoysOfEfficiency/i18n/es.json rename to GloryOfEfficiency/i18n/es.json diff --git a/JoysOfEfficiency/i18n/fr.json b/GloryOfEfficiency/i18n/fr.json similarity index 100% rename from JoysOfEfficiency/i18n/fr.json rename to GloryOfEfficiency/i18n/fr.json diff --git a/JoysOfEfficiency/i18n/ja.json b/GloryOfEfficiency/i18n/ja.json similarity index 100% rename from JoysOfEfficiency/i18n/ja.json rename to GloryOfEfficiency/i18n/ja.json diff --git a/JoysOfEfficiency/i18n/ko.json b/GloryOfEfficiency/i18n/ko.json similarity index 100% rename from JoysOfEfficiency/i18n/ko.json rename to GloryOfEfficiency/i18n/ko.json diff --git a/JoysOfEfficiency/i18n/pt.json b/GloryOfEfficiency/i18n/pt.json similarity index 100% rename from JoysOfEfficiency/i18n/pt.json rename to GloryOfEfficiency/i18n/pt.json diff --git a/JoysOfEfficiency/i18n/ru.json b/GloryOfEfficiency/i18n/ru.json similarity index 100% rename from JoysOfEfficiency/i18n/ru.json rename to GloryOfEfficiency/i18n/ru.json diff --git a/JoysOfEfficiency/i18n/zh.json b/GloryOfEfficiency/i18n/zh.json similarity index 100% rename from JoysOfEfficiency/i18n/zh.json rename to GloryOfEfficiency/i18n/zh.json diff --git a/GloryOfEfficiency/manifest.json b/GloryOfEfficiency/manifest.json new file mode 100644 index 0000000..292b2c4 --- /dev/null +++ b/GloryOfEfficiency/manifest.json @@ -0,0 +1,10 @@ +{ + "Author": "hackswell", + "Description": "Adds many useful functions to make gameplay more efficient. Forked from pomepome/JoysOfEfficiency on GitHub", + "EntryDll": "GloryOfEfficiency.dll", + "MinimumApiVersion": "4.0", + "Name": "GloryOfEfficiency", + "UniqueID": "hackswell.GloryOfEfficiency", + "UpdateKeys": [ "Nexus:1234567" ], + "Version": "1.0.0" +} diff --git a/JoysOfEfficiency/packages.config b/GloryOfEfficiency/packages.config similarity index 100% rename from JoysOfEfficiency/packages.config rename to GloryOfEfficiency/packages.config diff --git a/JoysOfEfficiency/manifest.json b/JoysOfEfficiency/manifest.json deleted file mode 100644 index 3c69ff1..0000000 --- a/JoysOfEfficiency/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Author": "punyo", - "Description": "Adds many useful functions to make gameplay more efficient", - "EntryDll": "JoysOfEfficiency.dll", - "MinimumApiVersion": "4.0", - "Name": "JoysOfEfficiency", - "UniqueID": "punyo.JoysOfEfficiency", - "UpdateKeys": [ "Nexus:2162" ], - "Version": "1.5.0-unofficial.7-Hackswell" -} diff --git a/LICENSE b/LICENSE index 52edd6b..ab42d4f 100644 --- a/LICENSE +++ b/LICENSE @@ -653,6 +653,7 @@ Also add information on how to contact you by electronic and paper mail. notice like this when it starts in an interactive mode: JoysOfEfficiency Copyright (C) 2018 pomepome + GloryOfEfficiency Copyright (C) 2024 Hackswell [Forked from JoysOfEfficiency above] This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -671,4 +672,4 @@ into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. \ No newline at end of file +. From 95e55edd82347128d07203d116948d9452719272 Mon Sep 17 00:00:00 2001 From: Sandman534 <45305344+Sandman534@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:25:24 -0700 Subject: [PATCH 29/29] Probility Fixes --- GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs b/GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs index 01d37aa..863d977 100644 --- a/GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs +++ b/GloryOfEfficiency/Huds/FishingProbabilitiesBox.cs @@ -1,6 +1,7 @@ using GloryOfEfficiency.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using Netcode; using StardewValley; using StardewValley.GameData; using StardewValley.GameData.Locations; @@ -29,7 +30,7 @@ public static void UpdateProbabilities(FishingRod rod) { if (rod.isFishing) { - if (_isFirstTimeOfFishing) + if (_isFirstTimeOfFishing && InstanceHolder.Config.FishingProbabilitiesInfo) { // Only run the probablies once when line is cast _isFirstTimeOfFishing = false; @@ -48,8 +49,10 @@ public static void UpdateProbabilities(FishingRod rod) // Populate Fish and Tackle _fishingDictionary = GetFishes(location, vector, clearWaterDistance + (flag ? 1 : 0), Game1.player, rod, InstanceHolder.Config.MorePreciseProbabilities ? InstanceHolder.Config.TrialOfExamine : 1); - _attachmentDictionary = GetAttachments(rod); } + + if (InstanceHolder.Config.FishingTackleInfo) + _attachmentDictionary = GetAttachments(rod); } // Clear out lists when not fishing @@ -419,7 +422,7 @@ private static bool IsGarbage(string item) var objectData = Game1.objectData[itemID]; // Fish items that are not fish - if (objectData != null && objectData.ContextTags.Contains("fish_nonfish") && !objectData.ContextTags.Contains("counts_as_fish_catch")) + if (objectData != null && objectData.ContextTags != null && objectData.ContextTags.Contains("fish_nonfish") && !objectData.ContextTags.Contains("counts_as_fish_catch")) return true; // JoJa Garbage