diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
commit | 60b41195778af33fd609eab66d9ae3f1d1165e8f (patch) | |
tree | 7128b906d40e94c56c34ed6058f27bc31c31a08b /src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs | |
parent | b9bc1a6d17cafa0a97b46ffecda432cfc2f23b51 (diff) | |
parent | 52cf953f685c65b2b6814e375ec9a5ffa03c440a (diff) | |
download | SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.gz SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.bz2 SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs')
-rw-r--r-- | src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs index a6f42b98..37f4719e 100644 --- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs @@ -15,14 +15,16 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player /// <summary>Provides methods for searching and constructing items.</summary> private readonly ItemRepository Items = new ItemRepository(); + /// <summary>The type names recognised by this command.</summary> + private readonly string[] ValidTypes = Enum.GetNames(typeof(ItemType)).Concat(new[] { "Name" }).ToArray(); + /********* ** Public methods *********/ /// <summary>Construct an instance.</summary> public AddCommand() - : base("player_add", AddCommand.GetDescription()) - { } + : base("player_add", AddCommand.GetDescription()) { } /// <summary>Handle the command.</summary> /// <param name="monitor">Writes messages to the console and log file.</param> @@ -30,35 +32,34 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player /// <param name="args">The command arguments.</param> public override void Handle(IMonitor monitor, string command, ArgumentParser args) { - // read arguments - if (!args.TryGet(0, "item type", out string rawType, oneOf: Enum.GetNames(typeof(ItemType)))) + // validate + if (!Context.IsWorldReady) + { + monitor.Log("You need to load a save to use this command.", LogLevel.Error); return; - if (!args.TryGetInt(1, "item ID", out int id, min: 0)) + } + + // read arguments + if (!args.TryGet(0, "item type", out string type, oneOf: this.ValidTypes)) return; if (!args.TryGetInt(2, "count", out int count, min: 1, required: false)) count = 1; if (!args.TryGetInt(3, "quality", out int quality, min: Object.lowQuality, max: Object.bestQuality, required: false)) quality = Object.lowQuality; - ItemType type = (ItemType)Enum.Parse(typeof(ItemType), rawType, ignoreCase: true); // find matching item - SearchableItem match = this.Items.GetAll().FirstOrDefault(p => p.Type == type && p.ID == id); + SearchableItem match = Enum.TryParse(type, true, out ItemType itemType) + ? this.FindItemByID(monitor, args, itemType) + : this.FindItemByName(monitor, args); if (match == null) - { - monitor.Log($"There's no {type} item with ID {id}.", LogLevel.Error); return; - } // apply count match.Item.Stack = count; // apply quality if (match.Item is Object obj) -#if STARDEW_VALLEY_1_3 obj.Quality = quality; -#else - obj.quality = quality; -#endif else if (match.Item is Tool tool) tool.UpgradeLevel = quality; @@ -67,9 +68,60 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player monitor.Log($"OK, added {match.Name} ({match.Type} #{match.ID}) to your inventory.", LogLevel.Info); } + /********* ** Private methods *********/ + /// <summary>Get a matching item by its ID.</summary> + /// <param name="monitor">Writes messages to the console and log file.</param> + /// <param name="args">The command arguments.</param> + /// <param name="type">The item type.</param> + private SearchableItem FindItemByID(IMonitor monitor, ArgumentParser args, ItemType type) + { + // read arguments + if (!args.TryGetInt(1, "item ID", out int id, min: 0)) + return null; + + // find matching item + SearchableItem item = this.Items.GetAll().FirstOrDefault(p => p.Type == type && p.ID == id); + if (item == null) + monitor.Log($"There's no {type} item with ID {id}.", LogLevel.Error); + return item; + } + + /// <summary>Get a matching item by its name.</summary> + /// <param name="monitor">Writes messages to the console and log file.</param> + /// <param name="args">The command arguments.</param> + private SearchableItem FindItemByName(IMonitor monitor, ArgumentParser args) + { + // read arguments + if (!args.TryGet(1, "item name", out string name)) + return null; + + // find matching items + SearchableItem[] matches = this.Items.GetAll().Where(p => p.NameContains(name)).ToArray(); + if (!matches.Any()) + { + monitor.Log($"There's no item with name '{name}'. You can use the 'list_items [name]' command to search for items.", LogLevel.Error); + return null; + } + + // handle single exact match + SearchableItem[] exactMatches = matches.Where(p => p.NameEquivalentTo(name)).ToArray(); + if (exactMatches.Length == 1) + return exactMatches[0]; + + // handle ambiguous results + string options = this.GetTableString( + data: matches, + header: new[] { "type", "name", "command" }, + getRow: item => new[] { item.Type.ToString(), item.DisplayName, $"player_add {item.Type} {item.ID}" } + ); + monitor.Log($"There's no item with name '{name}'. Do you mean one of these?\n\n{options}", LogLevel.Info); + return null; + } + + /// <summary>Get the command description.</summary> private static string GetDescription() { string[] typeValues = Enum.GetNames(typeof(ItemType)); @@ -81,8 +133,14 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player + "- count (optional): how many of the item to give.\n" + $"- quality (optional): one of {Object.lowQuality} (normal), {Object.medQuality} (silver), {Object.highQuality} (gold), or {Object.bestQuality} (iridium).\n" + "\n" - + "This example adds the galaxy sword to your inventory:\n" - + " player_add weapon 4"; + + "Usage: player_add name \"<name>\" [count] [quality]\n" + + "- name: the item name to search (use the 'list_items' command to see a list). This will add the item immediately if it's an exact match, else show a table of matching items.\n" + + "- count (optional): how many of the item to give.\n" + + $"- quality (optional): one of {Object.lowQuality} (normal), {Object.medQuality} (silver), {Object.highQuality} (gold), or {Object.bestQuality} (iridium).\n" + + "\n" + + "These examples both add the galaxy sword to your inventory:\n" + + " player_add weapon 4\n" + + " player_add name \"Galaxy Sword\""; } } } |