diff --git a/docs/release-notes.md b/docs/release-notes.md index fa2ec91b..42519b1f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,6 +1,10 @@ ← [README](README.md) # Release notes +## Upcoming release +* For players: + * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. + ## 3.12.8 Released 18 October 2021 for Stardew Valley 1.5.4. diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs new file mode 100644 index 00000000..0bebd2b7 --- /dev/null +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.Linq; +using StardewValley; + +namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player +{ + /// A command which changes the player's farm type. + internal class SetFarmTypeCommand : ConsoleCommand + { + /********* + ** Fields + *********/ + /// The vanilla farm type IDs. + private static readonly ISet VanillaFarmTypes = new HashSet( + Enumerable.Range(0, Farm.layout_max + 1) + ); + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public SetFarmTypeCommand() + : base("set_farm_type", $"Sets the current player's farm type.\n\nUsage: set_farm_type \n- farm type: one of {string.Join(", ", SetFarmTypeCommand.VanillaFarmTypes.Select(id => $"{id} ({SetFarmTypeCommand.GetFarmLabel(id)})"))}.") { } + + /// Handle the command. + /// Writes messages to the console and log file. + /// The command name. + /// The command arguments. + public override void Handle(IMonitor monitor, string command, ArgumentParser args) + { + // validation checks + if (!Context.IsWorldReady) + { + monitor.Log("You must load a save to use this command.", LogLevel.Error); + return; + } + + // parse argument + if (!args.TryGetInt(0, "farm type", out int farmType, min: 0, max: Farm.layout_max)) + return; + + // handle + if (Game1.whichFarm == farmType) + { + monitor.Log($"Your current farm is already set to {farmType} ({SetFarmTypeCommand.GetFarmLabel(farmType)}).", LogLevel.Info); + return; + } + + this.SetFarmType(farmType); + monitor.Log($"Your current farm has been converted to {farmType} ({SetFarmTypeCommand.GetFarmLabel(farmType)}).", LogLevel.Warn); + monitor.Log("Saving and reloading is recommended to make sure everything is updated for the change.", LogLevel.Warn); + } + + + /********* + ** Private methods + *********/ + /// Change the farm type to the given value. + /// The farm type ID. + private void SetFarmType(int type) + { + Game1.whichFarm = type; + + Farm farm = Game1.getFarm(); + farm.mapPath.Value = $@"Maps\{Farm.getMapNameFromTypeInt(Game1.whichFarm)}"; + farm.reloadMap(); + } + + /// Get the display name for a vanilla farm type. + /// The farm type. + private static string GetFarmLabel(int type) + { + string translationKey = type switch + { + Farm.default_layout => "Character_FarmStandard", + Farm.riverlands_layout => "Character_FarmFishing", + Farm.forest_layout => "Character_FarmForaging", + Farm.mountains_layout => "Character_FarmMining", + Farm.combat_layout => "Character_FarmCombat", + Farm.fourCorners_layout => "Character_FarmFourCorners", + Farm.beach_layout => "Character_FarmBeach", + _ => null + }; + + return translationKey != null + ? Game1.content.LoadString(@$"Strings\UI:{translationKey}").Split('_')[0] + : type.ToString(); + } + } +}