Skip to content

Commit

Permalink
overhaul Junimo hut options to provide more flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Pathoschild committed Oct 10, 2022
1 parent 364c2d1 commit 06ee523
Show file tree
Hide file tree
Showing 18 changed files with 360 additions and 221 deletions.
20 changes: 15 additions & 5 deletions Automate/Framework/AutomationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,21 @@ public AutomationFactory(Func<ModConfig> config, IMonitor monitor, IReflectionHe

case JunimoHut hut:
{
var config = this.Config();
bool betterJunimosCompat = config.ModCompatibility.BetterJunimos && this.IsBetterJunimosLoaded;
bool allowSeedInput = betterJunimosCompat && config.ModCompatibility.BetterJunimosTransferSeedsToJunimoHuts;
bool allowFertilizerInput = betterJunimosCompat && config.ModCompatibility.BetterJunimosTransferSeedsToJunimoHuts;
return new JunimoHutMachine(hut, location, allowSeedInput: allowSeedInput, allowFertilizerInput: allowFertilizerInput, ignoreSeedOutput: betterJunimosCompat, ignoreFertilizerOutput: betterJunimosCompat, pullGemstonesFromJunimoHuts: config.PullGemstonesFromJunimoHuts);
ModConfig config = this.Config();

JunimoHutBehavior gemBehavior = config.JunimoHutBehaviorForGemStones;
if (gemBehavior is JunimoHutBehavior.AutoDetect)
gemBehavior = JunimoHutBehavior.Ignore;

JunimoHutBehavior fertilizerBehavior = config.JunimoHutBehaviorForFertilizer;
if (fertilizerBehavior is JunimoHutBehavior.AutoDetect)
fertilizerBehavior = this.IsBetterJunimosLoaded ? JunimoHutBehavior.Ignore : JunimoHutBehavior.MoveIntoChests;

JunimoHutBehavior seedBehavior = config.JunimoHutBehaviorForFertilizer;
if (seedBehavior is JunimoHutBehavior.AutoDetect)
seedBehavior = this.IsBetterJunimosLoaded ? JunimoHutBehavior.Ignore : JunimoHutBehavior.MoveIntoChests;

return new JunimoHutMachine(hut, location, gemBehavior, fertilizerBehavior, seedBehavior);
}

case Mill mill:
Expand Down
84 changes: 54 additions & 30 deletions Automate/Framework/GenericModConfigMenuIntegrationForAutomate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ public void Register()
get: config => config.Enabled,
set: (config, value) => config.Enabled = value
)
.AddCheckbox(
name: I18n.Config_JunimoHutsOutputGems_Name,
tooltip: I18n.Config_JunimoHutsOutputGems_Desc,
get: config => config.PullGemstonesFromJunimoHuts,
set: (config, value) => config.PullGemstonesFromJunimoHuts = value
)
.AddNumberField(
name: I18n.Config_AutomationInterval_Name,
tooltip: I18n.Config_AutomationInterval_Desc,
Expand All @@ -76,34 +70,12 @@ public void Register()
tooltip: I18n.Config_ToggleOverlayKey_Desc,
get: config => config.Controls.ToggleOverlay,
set: (config, value) => config.Controls.ToggleOverlay = value
);

// mod compatibility
menu
.AddSectionTitle(I18n.Config_Title_ModCompatibility)
.AddCheckbox(
name: I18n.Config_BetterJunimos_Name,
tooltip: I18n.Config_BetterJunimos_Desc,
get: config => config.ModCompatibility.BetterJunimos,
set: (config, value) => config.ModCompatibility.BetterJunimos = value
)
.AddCheckbox(
name: I18n.Config_BetterJunimosTransferSeedsToJunimoHuts_Name,
tooltip: I18n.Config_BetterJunimosTransferSeedsToJunimoHuts_Desc,
get: config => config.ModCompatibility.BetterJunimosTransferSeedsToJunimoHuts,
set: (config, value) => config.ModCompatibility.BetterJunimosTransferSeedsToJunimoHuts = value
)
.AddCheckbox(
name: I18n.Config_BetterJunimosTransferFertilizersToJunimoHuts_Name,
tooltip: I18n.Config_BetterJunimosTransferFertilizersToJunimoHuts_Desc,
get: config => config.ModCompatibility.BetterJunimosTransferFertilizersToJunimoHuts,
set: (config, value) => config.ModCompatibility.BetterJunimosTransferFertilizersToJunimoHuts = value
)
.AddCheckbox(
name: I18n.Config_WarnForMissingBridgeMod_Name,
tooltip: I18n.Config_WarnForMissingBridgeMod_Desc,
get: config => config.ModCompatibility.WarnForMissingBridgeMod,
set: (config, value) => config.ModCompatibility.WarnForMissingBridgeMod = value
get: config => config.WarnForMissingBridgeMod,
set: (config, value) => config.WarnForMissingBridgeMod = value
);

// connectors
Expand All @@ -126,6 +98,30 @@ public void Register()
set: (config, value) => this.SetCustomConnectors(config, value.Split(',').Select(p => p.Trim()))
);

// Junimo huts
menu.AddSectionTitle(I18n.Config_Title_JunimoHuts);
this.AddJunimoHutBehaviorDropdown(
menu,
name: I18n.Config_JunimoHutGems_Name,
tooltip: I18n.Config_JunimoHutGems_Desc,
get: config => config.JunimoHutBehaviorForGemStones,
set: (config, value) => config.JunimoHutBehaviorForGemStones = value
);
this.AddJunimoHutBehaviorDropdown(
menu,
name: I18n.Config_JunimoHutFertilizer_Name,
tooltip: I18n.Config_JunimoHutFertilizer_Desc,
get: config => config.JunimoHutBehaviorForFertilizer,
set: (config, value) => config.JunimoHutBehaviorForFertilizer = value
);
this.AddJunimoHutBehaviorDropdown(
menu,
name: I18n.Config_JunimoHutSeeds_Name,
tooltip: I18n.Config_JunimoHutSeeds_Desc,
get: config => config.JunimoHutBehaviorForSeeds,
set: (config, value) => config.JunimoHutBehaviorForSeeds = value
);

// machine overrides
menu.AddSectionTitle(I18n.Config_Title_MachineOverrides);
foreach (var entry in this.Data.DefaultMachineOverrides)
Expand All @@ -144,6 +140,34 @@ public void Register()
/*********
** Private methods
*********/
/****
** Junimo huts
****/
/// <summary>Add a dropdown to configure Junimo hut behavior for an item type.</summary>
/// <param name="menu">The config menu to extend.</param>
/// <param name="name">The label text to show in the form.</param>
/// <param name="tooltip">The tooltip text shown when the cursor hovers on the field.</param>
/// <param name="get">Get the current value from the mod config.</param>
/// <param name="set">Set a new value in the mod config.</param>
private void AddJunimoHutBehaviorDropdown(GenericModConfigMenuIntegration<ModConfig> menu, Func<string> name, Func<string> tooltip, Func<ModConfig, JunimoHutBehavior> get, Action<ModConfig, JunimoHutBehavior> set)
{
menu.AddDropdown(
name: name,
tooltip: tooltip,
get: config => get(config).ToString(),
set: (config, value) => set(config, Enum.Parse<JunimoHutBehavior>(value)),
allowedValues: Enum.GetNames<JunimoHutBehavior>(),
formatAllowedValue: value => value switch
{
nameof(JunimoHutBehavior.AutoDetect) => I18n.Config_JunimoHuts_AutoDetect(),
nameof(JunimoHutBehavior.Ignore) => I18n.Config_JunimoHuts_Ignore(),
nameof(JunimoHutBehavior.MoveIntoChests) => I18n.Config_JunimoHuts_MoveIntoChests(),
nameof(JunimoHutBehavior.MoveIntoHut) => I18n.Config_JunimoHuts_MoveIntoHuts(),
_ => "???" // should never happen
}
);
}

/****
** Connectors
****/
Expand Down
110 changes: 73 additions & 37 deletions Automate/Framework/Machines/Buildings/JunimoHutMachine.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Linq;
using Pathoschild.Stardew.Automate.Framework.Models;
using StardewValley;
using StardewValley.Buildings;
using StardewValley.Locations;
using StardewValley.Objects;
using SObject = StardewValley.Object;

Expand All @@ -13,20 +13,20 @@ internal class JunimoHutMachine : BaseMachineForBuilding<JunimoHut>
/*********
** Fields
*********/
/// <summary>Whether seeds should be treated as Junimo hut inputs.<summary>
private readonly bool AllowSeedInput;
/// <summary>How to handle gem stones in the hut or connected chests.</summary>
private readonly JunimoHutBehavior GemBehavior;

/// <summary>Whether fertilizer should be treated as Junimo hut inputs.<summary>
private readonly bool AllowFertilizerInput;
/// <summary>How to handle fertilizer in the hut or connected chests.</summary>
private readonly JunimoHutBehavior FertilizerBehavior;

/// <summary>Whether seeds should be ignored when selecting output.</summary>
private readonly bool IgnoreSeedOutput;
/// <summary>How to handle seeds in the hut or connected chests.</summary>
private readonly JunimoHutBehavior SeedBehavior;

/// <summary>Whether fertilizer should be ignored when selecting output.</summary>
private readonly bool IgnoreFertilizerOutput;
/// <summary>Whether the Junimo hut can automate input.</summary>
private readonly bool HasInput;

/// <summary>Whether to pull gemstones out of Junimo huts.</summary>
public bool PullGemstonesFromJunimoHuts { get; set; }
/// <summary>Whether any items are configured to be skipped when outputting.</summary>
private readonly bool HasIgnoredOutput;

/// <summary>The Junimo hut's output chest.</summary>
private Chest Output => this.Machine.output.Value;
Expand All @@ -38,31 +38,37 @@ internal class JunimoHutMachine : BaseMachineForBuilding<JunimoHut>
/// <summary>Construct an instance.</summary>
/// <param name="hut">The underlying Junimo hut.</param>
/// <param name="location">The location which contains the machine.</param>
/// <param name="allowSeedInput">Whether seeds are allowed as an input.</param>
/// <param name="allowFertilizerInput">Whether fertilizers are allowed as an input.</param>
/// <param name="ignoreSeedOutput">Whether seeds should be ignored when selecting output.</param>
/// <param name="ignoreFertilizerOutput">Whether fertilizer should be ignored when selecting output.</param>
/// <param name="pullGemstonesFromJunimoHuts">Whether to pull gemstones out of Junimo huts.</param>
public JunimoHutMachine(JunimoHut hut, GameLocation location, bool allowSeedInput, bool allowFertilizerInput, bool ignoreSeedOutput, bool ignoreFertilizerOutput, bool pullGemstonesFromJunimoHuts)
/// <param name="gemBehavior">How to handle gem stones in the hut or connected chests.</param>
/// <param name="fertilizerBehavior">How to handle fertilizer in the hut or connected chests.</param>
/// <param name="seedBehavior">How to handle seeds in the hut or connected chests.</param>
public JunimoHutMachine(JunimoHut hut, GameLocation location, JunimoHutBehavior gemBehavior, JunimoHutBehavior fertilizerBehavior, JunimoHutBehavior seedBehavior)
: base(hut, location, BaseMachine.GetTileAreaFor(hut))
{
this.AllowSeedInput = allowSeedInput;
this.AllowFertilizerInput = allowFertilizerInput;
this.IgnoreSeedOutput = ignoreSeedOutput;
this.IgnoreFertilizerOutput = ignoreFertilizerOutput;
this.PullGemstonesFromJunimoHuts = pullGemstonesFromJunimoHuts;
this.GemBehavior = gemBehavior;
this.FertilizerBehavior = fertilizerBehavior;
this.SeedBehavior = seedBehavior;

this.HasInput =
gemBehavior is JunimoHutBehavior.MoveIntoHut
|| fertilizerBehavior is JunimoHutBehavior.MoveIntoHut
|| seedBehavior is JunimoHutBehavior.MoveIntoHut;
this.HasIgnoredOutput =
gemBehavior is not JunimoHutBehavior.MoveIntoChests
|| fertilizerBehavior is not JunimoHutBehavior.MoveIntoChests
|| seedBehavior is not JunimoHutBehavior.MoveIntoChests;
}

/// <summary>Get the machine's processing state.</summary>
public override MachineState GetState()
{
if (this.Machine.isUnderConstruction())
return MachineState.Disabled;
if (this.AllowSeedInput || this.AllowFertilizerInput)
return MachineState.Empty;

return this.GetNextOutput() != null
? MachineState.Done
if (this.GetNextOutput() != null)
return MachineState.Done;

return this.HasInput
? MachineState.Empty
: MachineState.Processing;
}

Expand All @@ -77,11 +83,34 @@ public override MachineState GetState()
/// <returns>Returns whether the machine started processing an item.</returns>
public override bool SetInput(IStorage input)
{
if (!this.AllowFertilizerInput && !this.AllowSeedInput)
if (!this.HasInput)
return false;

// get next item
ITrackedStack? tracker = input.GetItems().FirstOrDefault(p => p.Sample is SObject obj && ((this.AllowSeedInput && (obj.Category == SObject.SeedsCategory)) || (this.AllowFertilizerInput && (obj.Category == SObject.fertilizerCategory))));
ITrackedStack? tracker = null;
foreach (ITrackedStack stack in input.GetItems())
{
if (stack.Sample is not SObject obj)
continue;

switch (obj.Category)
{
case SObject.SeedsCategory when this.SeedBehavior == JunimoHutBehavior.MoveIntoHut:
tracker = stack;
break;

case SObject.fertilizerCategory when this.FertilizerBehavior == JunimoHutBehavior.MoveIntoHut:
tracker = stack;
break;

case (SObject.GemCategory or SObject.mineralsCategory) when this.GemBehavior == JunimoHutBehavior.MoveIntoHut:
tracker = stack;
break;
}

if (tracker is not null)
break;
}
if (tracker == null)
return false;

Expand All @@ -108,15 +137,22 @@ private void OnOutputTaken(Item item)
{
foreach (Item item in this.Output.items.Where(p => p != null))
{
// ignore gems which change Junimo colors (see JunimoHut:getGemColor)
if (!this.PullGemstonesFromJunimoHuts && item.Category is SObject.GemCategory or SObject.mineralsCategory)
continue;

// ignore items used by another mod
if (this.IgnoreSeedOutput && item.Category == SObject.SeedsCategory)
continue;
if (this.IgnoreFertilizerOutput && item.Category == SObject.fertilizerCategory)
continue;
if (this.HasIgnoredOutput)
{
bool ignore = false;

switch (item.Category)
{
case SObject.SeedsCategory when this.SeedBehavior is not JunimoHutBehavior.MoveIntoChests:
case SObject.fertilizerCategory when this.FertilizerBehavior is not JunimoHutBehavior.MoveIntoChests:
case (SObject.GemCategory or SObject.mineralsCategory) when this.GemBehavior is not JunimoHutBehavior.MoveIntoChests:
ignore = true;
break;
}

if (ignore)
continue;
}

return item;
}
Expand Down
18 changes: 18 additions & 0 deletions Automate/Framework/Models/JunimoHutBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Pathoschild.Stardew.Automate.Framework.Models
{
/// <summary>Indicates how Junimo huts should be automated for a specific item type.</summary>
internal enum JunimoHutBehavior
{
/// <summary>Apply the default logic based on the player's installed mods (e.g. leave seeds in the hut if Better Junimos is installed).</summary>
AutoDetect,

/// <summary>Ignore items of this type, so they're not transferred either way.</summary>
Ignore,

/// <summary>Move any items of this type from the Junimo Hut into connected chests.</summary>
MoveIntoChests,

/// <summary>Move any items of this type from connected chests into the Junimo Hut.</summary>
MoveIntoHut
}
}
21 changes: 0 additions & 21 deletions Automate/Framework/Models/ModCompatibilityConfig.cs

This file was deleted.

Loading

0 comments on commit 06ee523

Please sign in to comment.