diff --git a/BetterJunimos/Abilities/Base/VisitGreenhouseAbility.cs b/BetterJunimos/Abilities/Base/VisitGreenhouseAbility.cs index 809f8e8..2bcf7ea 100644 --- a/BetterJunimos/Abilities/Base/VisitGreenhouseAbility.cs +++ b/BetterJunimos/Abilities/Base/VisitGreenhouseAbility.cs @@ -15,35 +15,40 @@ public string AbilityName() { return "VisitGreenhouse"; } + public GameLocation Greenhouse { get; set; } + public bool IsActionAvailable(GameLocation location, Vector2 pos, Guid guid) { if (!BetterJunimos.Config.JunimoImprovements.CanWorkInGreenhouse) return false; - if (!location.IsFarm) return false; + //if (!location.IsFarm) return false; + var hut = Util.GetHutFromId(guid); + var (x, y) = pos; + var up = new Vector2(x, y + 1); + var right = new Vector2(x + 1, y); + var down = new Vector2(x, y - 1); + var left = new Vector2(x - 1, y); - var greenhouse = Game1.getLocationFromName("Greenhouse"); + Vector2[] positions = {up, right, down, left}; + var greenhouses = positions.Select(nextPos => JunimoGreenhouse.GreenhouseBuildingAtPos(location, nextPos)); + if (!greenhouses.Any(greenhouseBuilding => greenhouseBuilding is not null)) return false; + var greenhouse = greenhouses.FirstOrDefault(greenhouseBuilding => greenhouseBuilding is not null); + //BetterJunimos.SMonitor.Log("Greenhouse found", LogLevel.Debug); if (greenhouse.characters.Count(npc => npc is JunimoHarvester) > Util.Progression.MaxJunimosUnlocked / 2) { // greenhouse already kinda full + // BetterJunimos.SMonitor.Log("Greenhouse full", LogLevel.Debug); return false; } - var hut = Util.GetHutFromId(guid); if (!Util.Abilities.lastKnownCropLocations.TryGetValue((hut, greenhouse), out var lkc)) { - if (!Patches.PatchSearchAroundHut.SearchGreenhouseGrid(Util.GetHutFromId(guid), guid)) { + if (!Patches.PatchSearchAroundHut.SearchGreenhouseGrid(Util.GetHutFromId(guid), guid, greenhouse)) { // no work to be done in greenhouse - // BetterJunimos.SMonitor.Log("VisitGreenhouse IsActionAvailable: no work", LogLevel.Debug); + //BetterJunimos.SMonitor.Log("VisitGreenhouse IsActionAvailable: no work", LogLevel.Debug); return false; } } - var (x, y) = pos; - var up = new Vector2(x, y + 1); - var right = new Vector2(x + 1, y); - var down = new Vector2(x, y - 1); - var left = new Vector2(x - 1, y); - - Vector2[] positions = {up, right, down, left}; - if (!positions.Select(nextPos => JunimoGreenhouse.GreenhouseBuildingAtPos(location, nextPos)) - .Any(greenhouseBuilding => greenhouseBuilding is not null)) return false; - // BetterJunimos.SMonitor.Log("VisitGreenhouse IsActionAvailable: available", LogLevel.Debug); + Greenhouse = greenhouse; + + //BetterJunimos.SMonitor.Log("VisitGreenhouse IsActionAvailable: available", LogLevel.Debug); return true; } @@ -64,14 +69,16 @@ public bool PerformAction(GameLocation location, Vector2 pos, JunimoHarvester ju } // spawn a new Junimo in greenhouse - var hut = Util.GetHutFromId(guid); - var greenhouse = Game1.getLocationFromName("Greenhouse"); - - var spawnAt = new Vector2(10 * 64 + 32, 21 * 64 + 32); - // var spawnAt = new Vector2(14 * 64 + 32, 32 * 64 + 32); - var rand = new Random(); + //BetterJunimos.SMonitor.Log($"VisitGreenhouse #{junimo.home is null} {guid}: PerformAction: doing", LogLevel.Debug); + var hut = junimo.home; + var greenhouse = Greenhouse; + var door = Patches.PatchPathfindDoWork.GreenhouseDoor(junimo, greenhouse); + //BetterJunimos.SMonitor.Log($"Door at {door.X}, {door.Y}", LogLevel.Debug); + //var spawnAt = new Vector2(door.X, door.Y); + var spawnAt = new Vector2((float) door.X, (float) door.Y - 1) * 64f + new Vector2(0.0f, 32f); + //var spawnAt = new Vector2(14 * 64 + 32, 32 * 64 + 32); - var junimoNumber = rand.Next(4, 100); + var junimoNumber = Game1.random.Next(4, 100); Util.SpawnJunimoAtPosition(greenhouse, spawnAt, hut, junimoNumber); // BetterJunimos.SMonitor.Log( // $"VisitGreenhouse PerformAction: #{junimoNumber} spawned in {greenhouse.Name} at {spawnAt.X} {spawnAt.Y}", diff --git a/BetterJunimos/BetterJunimos.cs b/BetterJunimos/BetterJunimos.cs index 0bcee37..6f50b85 100644 --- a/BetterJunimos/BetterJunimos.cs +++ b/BetterJunimos/BetterJunimos.cs @@ -111,6 +111,8 @@ private void DoHarmonyRegistration() { replacements.Add("tryToHarvestHere", junimoType, typeof(PatchTryToHarvestHere)); replacements.Add("update", junimoType, typeof(PatchJunimoShake)); replacements.Add("pokeToHarvest", junimoType, typeof(PatchPokeToHarvest)); + replacements.Add("get_home", junimoType, typeof(PatchGet_home)); + replacements.Add("set_home", junimoType, typeof(PatchSet_home)); // improve pathfinding replacements.Add("pathfindToRandomSpotAroundHut", junimoType, typeof(PatchPathfindToRandomSpotAroundHut)); diff --git a/BetterJunimos/BetterJunimos.csproj b/BetterJunimos/BetterJunimos.csproj index 1e69c09..e6b5c7a 100644 --- a/BetterJunimos/BetterJunimos.csproj +++ b/BetterJunimos/BetterJunimos.csproj @@ -3,7 +3,7 @@ BetterJunimos BetterJunimos - 3.0.1 + 3.0.4 latest net6.0 true diff --git a/BetterJunimos/Patches/JunimoHarvesterPatches.cs b/BetterJunimos/Patches/JunimoHarvesterPatches.cs index 154a82e..c2ef2a9 100644 --- a/BetterJunimos/Patches/JunimoHarvesterPatches.cs +++ b/BetterJunimos/Patches/JunimoHarvesterPatches.cs @@ -37,11 +37,9 @@ public static bool Prefix(JunimoHarvester __instance, ref PathNode currentNode, public class PatchTryToHarvestHere { public static bool Prefix(JunimoHarvester __instance, ref int ___harvestTimer, ref NetGuid ___netHome) { if (!Context.IsMainPlayer) return true; - if (__instance.home is null) { - //BetterJunimos.SMonitor.Log($"No hut assigned"); - return false; - } - var id = ___netHome.Value; + var hut = Util.GetHutFromId(__instance.HomeId); + if (hut is null) return false; + var id = __instance.HomeId; var pos = __instance.Tile; // if (__instance.currentLocation.IsGreenhouse) { @@ -50,6 +48,11 @@ public static bool Prefix(JunimoHarvester __instance, ref int ___harvestTimer, r int time; var junimoAbility = Util.Abilities.IdentifyJunimoAbility(__instance.currentLocation, pos, id); + // if (__instance.currentLocation.IsGreenhouse) + // { + // BetterJunimos.SMonitor.Log($"PatchTryToHarvestHere , Is greenhouse but {__instance.controller.pathToEndPoint != null} | {junimoAbility}", LogLevel.Debug); + + // } if (junimoAbility != null) { // if (__instance.currentLocation.IsGreenhouse) { // BetterJunimos.SMonitor.Log( @@ -110,7 +113,7 @@ public static void Postfix(JunimoHarvester __instance, ref int ___harvestTimer) // Expand radius of random pathfinding public class PatchPathfindToRandomSpotAroundHut { public static void Postfix(JunimoHarvester __instance) { - var hut = __instance.home; + var hut = Util.GetHutFromId(__instance.HomeId); if (hut is null) return; var radius = Util.CurrentWorkingRadius; @@ -167,8 +170,8 @@ private static Point EndPointInGreenhouse(JunimoHarvester jh) { var gw = jh.currentLocation.map.Layers[0].LayerWidth; var gh = jh.currentLocation.map.Layers[0].LayerHeight; return new Vector2( - 1 + Game1.random.Next(gw - 2), - 1 + Game1.random.Next(gh - 2) + gw/2 + Game1.random.Next(-(gw/2 + 2), gh/2 - 2), + gh/2 + Game1.random.Next(-(gw/2 + 2), gh/2 - 2) ).ToPoint(); } @@ -180,6 +183,22 @@ private static Point EndPointInFarm(JunimoHut hut, int radius) { } } + [HarmonyPriority(Priority.Low)] + public class PatchGet_home { + public static void Postfix(ref JunimoHut __result, ref NetGuid ___netHome) + { + __result = Util.GetHutFromId(___netHome.Value); + } + } + + [HarmonyPriority(Priority.Low)] + public class PatchSet_home { + public static void Postfix(JunimoHut value, ref NetGuid ___netHome) + { + ___netHome.Value = Util.GetHutIdFromHut(value); + } + } + // pathfindToNewCrop - completely replace // Remove the max distance boundary [HarmonyPriority(Priority.Low)] @@ -187,8 +206,12 @@ public class PatchPathfindDoWork { public static bool Prefix(JunimoHarvester __instance, ref NetEvent1Field ___netAnimationEvent) { if (!Context.IsMainPlayer) return true; - - var hut = __instance.home; + // if (__instance.currentLocation.IsGreenhouse) + // { + // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork, Is greenhouse but {__instance.HomeId}", LogLevel.Debug); + + // } + var hut = Util.GetHutFromId(__instance.HomeId); if (hut is null) return true; var quittingTime = Util.Progression.CanWorkInEvenings ? 2400 : 1900; @@ -202,8 +225,14 @@ public static bool Prefix(JunimoHarvester __instance, if (__instance.controller != null) return false; - if (__instance.currentLocation is Farm) + if (__instance.currentLocation.NameOrUniqueName == hut.GetParentLocation().NameOrUniqueName) + { __instance.returnToJunimoHut(__instance.currentLocation); + } + if (__instance.currentLocation.IsGreenhouse) + { + returnToGreenhouseDoor(__instance, __instance.currentLocation); + } else { // can't walk back to the hut from here, just despawn __instance.junimoReachedHut(__instance, __instance.currentLocation); @@ -213,7 +242,7 @@ public static bool Prefix(JunimoHarvester __instance, // Prevent working when not paid else if (BetterJunimos.Config.JunimoPayment.WorkForWages && !Util.Payments.WereJunimosPaidToday) { - if (Game1.random.NextDouble() < 0.02 && __instance.currentLocation.IsFarm) { + if (Game1.random.NextDouble() < 0.02) { __instance.pathfindToRandomSpotAroundHut(); } else { @@ -227,7 +256,11 @@ public static bool Prefix(JunimoHarvester __instance, // TODO: fix for greenhouse // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork: {__instance.whichJunimoFromThisHut} hut noHarvest {hut.noHarvest.Value}", LogLevel.Debug); - + // if (__instance.currentLocation.IsGreenhouse) + // { + // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork v2, Is greenhouse but {hut.noHarvest.Value}", LogLevel.Debug); + + // } __instance.pathfindToRandomSpotAroundHut(); } @@ -253,16 +286,24 @@ __instance.currentLocation is not null && Math.Abs(__instance.controller.pathToEndPoint.Last().X - hut.tileX.Value - 1) > radius || Math.Abs(__instance.controller.pathToEndPoint.Last().Y - hut.tileY.Value - 1) > radius ); - + if (__instance.controller.pathToEndPoint != null && !outsideRadius) { // Junimo has somewhere to be, let it happen - + // if (__instance.currentLocation.IsGreenhouse) + // { + // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork v3, Is greenhouse but {__instance.controller.pathToEndPoint != null} | {outsideRadius}", LogLevel.Debug); + + // } // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork: {__instance.whichJunimoFromThisHut} has more work", LogLevel.Debug); ___netAnimationEvent.Fire(0); } else { // Junimo has no path, or path endpoint is outside the hut radius - + // if (__instance.currentLocation.IsGreenhouse) + // { + // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork v4, Is greenhouse but {__instance.controller.pathToEndPoint != null} | {outsideRadius}", LogLevel.Debug); + + // } Util.Abilities.lastKnownCropLocations.TryGetValue((hut, __instance.currentLocation), out var lkc); // BetterJunimos.SMonitor.Log($"PatchPathfindDoWork: {__instance.whichJunimoFromThisHut} needs work", LogLevel.Debug); @@ -331,7 +372,13 @@ private static void returnToGreenhouseDoor(JunimoHarvester junimo, GameLocation junimo.collidesWithOtherCharacters.Value = false; if (Game1.IsMasterGame) { - junimo.controller = new PathFindController(junimo, location, GreenhouseDoor(location), 1, + var door = GreenhouseDoor(junimo, location); + if (door == Point.Zero) + { + junimo.junimoReachedHut(junimo, junimo.currentLocation); + return; + } + junimo.controller = new PathFindController(junimo, location, door, 1, junimo.junimoReachedHut); if (junimo.controller.pathToEndPoint == null || junimo.controller.pathToEndPoint.Count == 0) { // BetterJunimos.SMonitor.Log( @@ -351,13 +398,14 @@ private static void returnToGreenhouseDoor(JunimoHarvester junimo, GameLocation location.playSound("junimoMeep1"); } - private static Point GreenhouseDoor(GameLocation location) { - foreach (var warp in location.warps.Where(warp => warp.TargetName == "Farm")) + public static Point GreenhouseDoor(JunimoHarvester junimo, GameLocation location) { + //TryFind warp to hutlocation + var warp = location.warps.FirstOrDefault(warp => warp.TargetName == junimo.home.GetParentLocation().NameOrUniqueName); + if (warp != null) { - return new Point(warp.X, warp.Y); + return new Point(warp.X, warp.Y - 1); } - - return new Point(10, 23); + return Point.Zero; } } diff --git a/BetterJunimos/Patches/JunimoHutPatches.cs b/BetterJunimos/Patches/JunimoHutPatches.cs index e3957f9..1c5a6ff 100644 --- a/BetterJunimos/Patches/JunimoHutPatches.cs +++ b/BetterJunimos/Patches/JunimoHutPatches.cs @@ -48,13 +48,18 @@ private static bool SearchAroundHut(JunimoHut hut) { if (BetterJunimos.Config.JunimoImprovements.CanWorkInGreenhouse) { var ghb = Util.Greenhouse.GreenhouseBuildingNearHut(id); var gh = Game1.getLocationFromName("Greenhouse"); + if (ghb != null) + { + // BetterJunimos.SMonitor.Log($"SearchAroundHut: Greenhouse find on location {hut.GetParentLocation().NameOrUniqueName}", LogLevel.Debug); + gh = ghb; + } if (!Util.Greenhouse.HutHasGreenhouse(id)) { // BetterJunimos.SMonitor.Log($"PatchSearchAroundHut: hut has no greenhouse", LogLevel.Debug); return foundWork; } // SearchGreenhouseGrid manages hut.lastKnownCropLocation (a hack!) and Util.Abilities.lastKnownCropLocations - foundWork |= SearchGreenhouseGrid(hut, id); + foundWork |= SearchGreenhouseGrid(hut, id, gh); Util.Abilities.lastKnownCropLocations.TryGetValue((hut, gh), out var lkc); // BetterJunimos.SMonitor.Log($"PatchSearchAroundHut: greenhouse lkc {lkc.X} {lkc.Y}", LogLevel.Trace); @@ -73,10 +78,13 @@ private static bool SearchAroundHut(JunimoHut hut) { /// JunimoHut to search /// GUID of hut to search /// True if there's any work to do - internal static bool SearchGreenhouseGrid(JunimoHut hut, Guid hut_guid) + internal static bool SearchGreenhouseGrid(JunimoHut hut, Guid hut_guid, GameLocation gl = null) { var gh = Game1.getLocationFromName("Greenhouse"); - + if (gl != null) + { + gh = gl; + } // BetterJunimos.SMonitor.Log($"SearchAroundHut: searching {gh.Name}", LogLevel.Trace); for (var x = 0; x < gh.map.Layers[0].LayerWidth; x++) { diff --git a/BetterJunimos/Utils/JunimoGreenhouse.cs b/BetterJunimos/Utils/JunimoGreenhouse.cs index 9c942b0..ef6285f 100644 --- a/BetterJunimos/Utils/JunimoGreenhouse.cs +++ b/BetterJunimos/Utils/JunimoGreenhouse.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewValley; @@ -22,22 +23,28 @@ public bool HutHasGreenhouse(Guid id) { return GreenhouseBuildingNearHut(id) is not null; } - internal static GreenhouseBuilding GreenhouseBuildingAtPos(GameLocation location, Vector2 tile) { + internal static GameLocation GreenhouseBuildingAtPos(GameLocation location, Vector2 tile) { if (!location.IsBuildableLocation()) return null; foreach (var building in location.buildings) { + if (building.HasIndoors() && (building.GetIndoors()?.IsGreenhouse ?? false)) + { + if(building.occupiesTile(tile)) + return building.GetIndoors(); + + } if (building is not GreenhouseBuilding greenhouseBuilding) continue; if (greenhouseBuilding.occupiesTile(tile)) { - return greenhouseBuilding; + return greenhouseBuilding.GetIndoors(); } } return null; } - public GreenhouseBuilding GreenhouseBuildingNearHut(Guid id) { + public GameLocation GreenhouseBuildingNearHut(Guid id) { var hut = Util.GetHutFromId(id); var radius = Util.CurrentWorkingRadius; - var farm = Game1.getFarm(); + var farm = hut.GetParentLocation(); for (var x = hut.tileX.Value + 1 - radius; x < hut.tileX.Value + 2 + radius; ++x) { for (var y = hut.tileY.Value + 1 - radius; y < hut.tileY.Value + 2 + radius; ++y) { diff --git a/BetterJunimos/Utils/Util.cs b/BetterJunimos/Utils/Util.cs index 1aba874..59cc81b 100644 --- a/BetterJunimos/Utils/Util.cs +++ b/BetterJunimos/Utils/Util.cs @@ -59,7 +59,7 @@ public static JunimoHut GetHutFromId(Guid id) { } } - BetterJunimos.SMonitor.Log($"Could not get hut from id ${id}", LogLevel.Error); + //BetterJunimos.SMonitor.Log($"Could not get hut from id ${id}", LogLevel.Error); return null; } @@ -87,7 +87,7 @@ public static void RemoveItemFromChest(Chest chest, Item item, int count = 1) { public static void SpawnJunimoAtHut(JunimoHut hut) { // I don't know why we're multiplying by 64 here var pos = new Vector2((float) hut.tileX.Value + 1, (float) hut.tileY.Value + 1) * 64f + new Vector2(0.0f, 32f); - SpawnJunimoAtPosition(Game1.player.currentLocation, pos, hut, hut.getUnusedJunimoNumber()); + SpawnJunimoAtPosition(hut.GetParentLocation(), pos, hut, hut.getUnusedJunimoNumber()); } public static void SpawnJunimoAtPosition(GameLocation location, Vector2 pos, JunimoHut hut, int junimoNumber) { @@ -128,6 +128,7 @@ public static void SpawnJunimoAtPosition(GameLocation location, Vector2 pos, Jun junimoHarvester.isPrismatic.Value = isPrismatic; //Added by Mizzion, Fixes the Prismatic Junimos. location.characters.Add(junimoHarvester); hut.myJunimos.Add(junimoHarvester); + junimoHarvester.HomeId = Util.GetHutIdFromHut(hut); if (Game1.isRaining) { var alpha = Reflection.GetField(junimoHarvester, "alpha"); diff --git a/BetterJunimos/manifest.json b/BetterJunimos/manifest.json index 78b9e74..f3ba2fd 100644 --- a/BetterJunimos/manifest.json +++ b/BetterJunimos/manifest.json @@ -1,11 +1,11 @@ { "Name": "Better Junimos", "Author": "ceruleandeep", - "Version": "2.0.8", + "Version": "3.0.4", "Description": "Allow your Junimos (from Junimo huts) to automatically plant seeds, fertilize, and so much more!", "UniqueID": "hawkfalcon.BetterJunimos", "EntryDll": "BetterJunimos.dll", - "MinimumApiVersion": "3.2.0", + "MinimumApiVersion": "4.0.0", "UpdateKeys": [ "Nexus:2221" ],