Skip to content

Commit

Permalink
Merge pull request #63 from Miguel-Thewolf/modded_greenhouse
Browse files Browse the repository at this point in the history
Modded greenhouse
  • Loading branch information
hawkfalcon authored Jul 5, 2024
2 parents 04ea462 + ef8b4fc commit 77b5453
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 56 deletions.
51 changes: 29 additions & 22 deletions BetterJunimos/Abilities/Base/VisitGreenhouseAbility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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}",
Expand Down
2 changes: 2 additions & 0 deletions BetterJunimos/BetterJunimos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion BetterJunimos/BetterJunimos.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<AssemblyName>BetterJunimos</AssemblyName>
<RootNamespace>BetterJunimos</RootNamespace>
<Version>3.0.1</Version>
<Version>3.0.4</Version>
<LangVersion>latest</LangVersion>
<TargetFramework>net6.0</TargetFramework>
<EnableHarmony>true</EnableHarmony>
Expand Down
92 changes: 70 additions & 22 deletions BetterJunimos/Patches/JunimoHarvesterPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

Expand All @@ -180,15 +183,35 @@ 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)]
public class PatchPathfindDoWork {
public static bool Prefix(JunimoHarvester __instance,
ref NetEvent1Field<int, NetInt> ___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;
Expand All @@ -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);
Expand All @@ -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 {
Expand All @@ -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();
}

Expand All @@ -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);
Expand Down Expand Up @@ -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(
Expand All @@ -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;
}
}

Expand Down
14 changes: 11 additions & 3 deletions BetterJunimos/Patches/JunimoHutPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -73,10 +78,13 @@ private static bool SearchAroundHut(JunimoHut hut) {
/// <param name="hut">JunimoHut to search</param>
/// <param name="hut_guid">GUID of hut to search</param>
/// <returns>True if there's any work to do</returns>
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++)
{
Expand Down
15 changes: 11 additions & 4 deletions BetterJunimos/Utils/JunimoGreenhouse.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading;
using Microsoft.Xna.Framework;
using StardewModdingAPI;
using StardewValley;
Expand All @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions BetterJunimos/Utils/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<float>(junimoHarvester, "alpha");
Expand Down
Loading

0 comments on commit 77b5453

Please sign in to comment.