summaryrefslogtreecommitdiff
path: root/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-08-01 11:07:29 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-08-01 11:07:29 -0400
commit60b41195778af33fd609eab66d9ae3f1d1165e8f (patch)
tree7128b906d40e94c56c34ed6058f27bc31c31a08b /src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs
parentb9bc1a6d17cafa0a97b46ffecda432cfc2f23b51 (diff)
parent52cf953f685c65b2b6814e375ec9a5ffa03c440a (diff)
downloadSMAPI-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.cs90
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\"";
}
}
}