diff options
Diffstat (limited to 'src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs')
-rw-r--r-- | src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs | 340 |
1 files changed, 203 insertions, 137 deletions
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs index fc631826..0648aa2b 100644 --- a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs @@ -1,7 +1,11 @@ +using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; using Microsoft.Xna.Framework; using StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData; using StardewValley; +using StardewValley.Menus; using StardewValley.Objects; using StardewValley.Tools; using SObject = StardewValley.Object; @@ -22,172 +26,234 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework ** Public methods *********/ /// <summary>Get all spawnable items.</summary> + [SuppressMessage("ReSharper", "AccessToModifiedClosure", Justification = "TryCreate invokes the lambda immediately.")] public IEnumerable<SearchableItem> GetAll() { - // get tools - yield return new SearchableItem(ItemType.Tool, ToolFactory.axe, ToolFactory.getToolFromDescription(ToolFactory.axe, 0)); - yield return new SearchableItem(ItemType.Tool, ToolFactory.hoe, ToolFactory.getToolFromDescription(ToolFactory.hoe, 0)); - yield return new SearchableItem(ItemType.Tool, ToolFactory.pickAxe, ToolFactory.getToolFromDescription(ToolFactory.pickAxe, 0)); - yield return new SearchableItem(ItemType.Tool, ToolFactory.wateringCan, ToolFactory.getToolFromDescription(ToolFactory.wateringCan, 0)); - yield return new SearchableItem(ItemType.Tool, ToolFactory.fishingRod, ToolFactory.getToolFromDescription(ToolFactory.fishingRod, 0)); - yield return new SearchableItem(ItemType.Tool, this.CustomIDOffset, new MilkPail()); // these don't have any sort of ID, so we'll just assign some arbitrary ones - yield return new SearchableItem(ItemType.Tool, this.CustomIDOffset + 1, new Shears()); - yield return new SearchableItem(ItemType.Tool, this.CustomIDOffset + 2, new Pan()); - yield return new SearchableItem(ItemType.Tool, this.CustomIDOffset + 3, new Wand()); - - // wallpapers - for (int id = 0; id < 112; id++) - yield return new SearchableItem(ItemType.Wallpaper, id, new Wallpaper(id) { Category = SObject.furnitureCategory }); - - // flooring - for (int id = 0; id < 40; id++) - yield return new SearchableItem(ItemType.Flooring, id, new Wallpaper(id, isFloor: true) { Category = SObject.furnitureCategory }); - - // equipment - foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Boots").Keys) - yield return new SearchableItem(ItemType.Boots, id, new Boots(id)); - foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\hats").Keys) - yield return new SearchableItem(ItemType.Hat, id, new Hat(id)); - foreach (int id in Game1.objectInformation.Keys) + IEnumerable<SearchableItem> GetAllRaw() { - if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) - yield return new SearchableItem(ItemType.Ring, id, new Ring(id)); - } + // get tools + for (int quality = Tool.stone; quality <= Tool.iridium; quality++) + { + yield return this.TryCreate(ItemType.Tool, ToolFactory.axe, () => ToolFactory.getToolFromDescription(ToolFactory.axe, quality)); + yield return this.TryCreate(ItemType.Tool, ToolFactory.hoe, () => ToolFactory.getToolFromDescription(ToolFactory.hoe, quality)); + yield return this.TryCreate(ItemType.Tool, ToolFactory.pickAxe, () => ToolFactory.getToolFromDescription(ToolFactory.pickAxe, quality)); + yield return this.TryCreate(ItemType.Tool, ToolFactory.wateringCan, () => ToolFactory.getToolFromDescription(ToolFactory.wateringCan, quality)); + if (quality != Tool.iridium) + yield return this.TryCreate(ItemType.Tool, ToolFactory.fishingRod, () => ToolFactory.getToolFromDescription(ToolFactory.fishingRod, quality)); + } + yield return this.TryCreate(ItemType.Tool, this.CustomIDOffset, () => new MilkPail()); // these don't have any sort of ID, so we'll just assign some arbitrary ones + yield return this.TryCreate(ItemType.Tool, this.CustomIDOffset + 1, () => new Shears()); + yield return this.TryCreate(ItemType.Tool, this.CustomIDOffset + 2, () => new Pan()); + yield return this.TryCreate(ItemType.Tool, this.CustomIDOffset + 3, () => new Wand()); - // weapons - foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\weapons").Keys) - { - Item weapon = (id >= 32 && id <= 34) - ? (Item)new Slingshot(id) - : new MeleeWeapon(id); - yield return new SearchableItem(ItemType.Weapon, id, weapon); - } + // wallpapers + for (int id = 0; id < 112; id++) + yield return this.TryCreate(ItemType.Wallpaper, id, () => new Wallpaper(id) { Category = SObject.furnitureCategory }); - // furniture - foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Furniture").Keys) - { - if (id == 1466 || id == 1468) - yield return new SearchableItem(ItemType.Furniture, id, new TV(id, Vector2.Zero)); - else - yield return new SearchableItem(ItemType.Furniture, id, new Furniture(id, Vector2.Zero)); - } + // flooring + for (int id = 0; id < 40; id++) + yield return this.TryCreate(ItemType.Flooring, id, () => new Wallpaper(id, isFloor: true) { Category = SObject.furnitureCategory }); - // craftables - foreach (int id in Game1.bigCraftablesInformation.Keys) - yield return new SearchableItem(ItemType.BigCraftable, id, new SObject(Vector2.Zero, id)); + // equipment + foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Boots").Keys) + yield return this.TryCreate(ItemType.Boots, id, () => new Boots(id)); + foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\hats").Keys) + yield return this.TryCreate(ItemType.Hat, id, () => new Hat(id)); + foreach (int id in Game1.objectInformation.Keys) + { + if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) + yield return this.TryCreate(ItemType.Ring, id, () => new Ring(id)); + } - // secret notes - foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\SecretNotes").Keys) - { - SObject note = new SObject(79, 1); - note.name = $"{note.name} #{id}"; - yield return new SearchableItem(ItemType.Object, this.CustomIDOffset + id, note); - } + // weapons + foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\weapons").Keys) + { + yield return this.TryCreate(ItemType.Weapon, id, () => (id >= 32 && id <= 34) + ? (Item)new Slingshot(id) + : new MeleeWeapon(id) + ); + } - // objects - foreach (int id in Game1.objectInformation.Keys) - { - if (id == 79) - continue; // secret note handled above - if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) - continue; // handled separated + // furniture + foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Furniture").Keys) + { + if (id == 1466 || id == 1468) + yield return this.TryCreate(ItemType.Furniture, id, () => new TV(id, Vector2.Zero)); + else + yield return this.TryCreate(ItemType.Furniture, id, () => new Furniture(id, Vector2.Zero)); + } - SObject item = new SObject(id, 1); - yield return new SearchableItem(ItemType.Object, id, item); + // craftables + foreach (int id in Game1.bigCraftablesInformation.Keys) + yield return this.TryCreate(ItemType.BigCraftable, id, () => new SObject(Vector2.Zero, id)); - // fruit products - if (item.Category == SObject.FruitsCategory) + // secret notes + foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\SecretNotes").Keys) { - // wine - SObject wine = new SObject(348, 1) - { - Name = $"{item.Name} Wine", - Price = item.Price * 3 - }; - wine.preserve.Value = SObject.PreserveType.Wine; - wine.preservedParentSheetIndex.Value = item.ParentSheetIndex; - yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 2 + id, wine); - - // jelly - SObject jelly = new SObject(344, 1) + yield return this.TryCreate(ItemType.Object, this.CustomIDOffset + id, () => { - Name = $"{item.Name} Jelly", - Price = 50 + item.Price * 2 - }; - jelly.preserve.Value = SObject.PreserveType.Jelly; - jelly.preservedParentSheetIndex.Value = item.ParentSheetIndex; - yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 3 + id, jelly); + SObject note = new SObject(79, 1); + note.name = $"{note.name} #{id}"; + return note; + }); } - // vegetable products - else if (item.Category == SObject.VegetableCategory) + // objects + foreach (int id in Game1.objectInformation.Keys) { - // juice - SObject juice = new SObject(350, 1) - { - Name = $"{item.Name} Juice", - Price = (int)(item.Price * 2.25d) - }; - juice.preserve.Value = SObject.PreserveType.Juice; - juice.preservedParentSheetIndex.Value = item.ParentSheetIndex; - yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 4 + id, juice); - - // pickled - SObject pickled = new SObject(342, 1) + if (id == 79) + continue; // secret note handled above + if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) + continue; // handled separated + + // spawn main item + SObject item; { - Name = $"Pickled {item.Name}", - Price = 50 + item.Price * 2 - }; - pickled.preserve.Value = SObject.PreserveType.Pickle; - pickled.preservedParentSheetIndex.Value = item.ParentSheetIndex; - yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 5 + id, pickled); - } + SearchableItem main = this.TryCreate(ItemType.Object, id, () => id == 812 + ? new ColoredObject(id, 1, Color.White) + : new SObject(id, 1) + ); + yield return main; + item = main?.Item as SObject; + } + if (item == null) + continue; - // flower honey - else if (item.Category == SObject.flowersCategory) - { - // get honey type - SObject.HoneyType? type = null; - switch (item.ParentSheetIndex) + // fruit products + if (item.Category == SObject.FruitsCategory) { - case 376: - type = SObject.HoneyType.Poppy; - break; - case 591: - type = SObject.HoneyType.Tulip; - break; - case 593: - type = SObject.HoneyType.SummerSpangle; - break; - case 595: - type = SObject.HoneyType.FairyRose; - break; - case 597: - type = SObject.HoneyType.BlueJazz; - break; - case 421: // sunflower standing in for all other flowers - type = SObject.HoneyType.Wild; - break; + // wine + yield return this.TryCreate(ItemType.Object, this.CustomIDOffset * 2 + id, () => + { + SObject wine = new SObject(348, 1) + { + Name = $"{item.Name} Wine", + Price = item.Price * 3 + }; + wine.preserve.Value = SObject.PreserveType.Wine; + wine.preservedParentSheetIndex.Value = item.ParentSheetIndex; + return wine; + }); + + // jelly + yield return this.TryCreate(ItemType.Object, this.CustomIDOffset * 3 + id, () => + { + SObject jelly = new SObject(344, 1) + { + Name = $"{item.Name} Jelly", + Price = 50 + item.Price * 2 + }; + jelly.preserve.Value = SObject.PreserveType.Jelly; + jelly.preservedParentSheetIndex.Value = item.ParentSheetIndex; + return jelly; + }); } - // yield honey - if (type != null) + // vegetable products + else if (item.Category == SObject.VegetableCategory) { - SObject honey = new SObject(Vector2.Zero, 340, item.Name + " Honey", false, true, false, false) + // juice + yield return this.TryCreate(ItemType.Object, this.CustomIDOffset * 4 + id, () => + { + SObject juice = new SObject(350, 1) + { + Name = $"{item.Name} Juice", + Price = (int)(item.Price * 2.25d) + }; + juice.preserve.Value = SObject.PreserveType.Juice; + juice.preservedParentSheetIndex.Value = item.ParentSheetIndex; + return juice; + }); + + // pickled + yield return this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () => { - Name = "Wild Honey" - }; - honey.honeyType.Value = type; + SObject pickled = new SObject(342, 1) + { + Name = $"Pickled {item.Name}", + Price = 50 + item.Price * 2 + }; + pickled.preserve.Value = SObject.PreserveType.Pickle; + pickled.preservedParentSheetIndex.Value = item.ParentSheetIndex; + return pickled; + }); + } - if (type != SObject.HoneyType.Wild) + // flower honey + else if (item.Category == SObject.flowersCategory) + { + yield return this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () => { - honey.Name = $"{item.Name} Honey"; + SObject honey = new SObject(Vector2.Zero, 340, $"{item.Name} Honey", false, true, false, false) + { + Name = $"{item.Name} Honey", + preservedParentSheetIndex = { item.ParentSheetIndex } + }; honey.Price += item.Price * 2; + return honey; + }); + } + + // roe and aged roe (derived from FishPond.GetFishProduce) + else if (id == 812) + { + foreach (var pair in Game1.objectInformation) + { + // get input + SObject input = new SObject(pair.Key, 1); + if (input.Category != SObject.FishCategory) + continue; + Color color = TailoringMenu.GetDyeColor(input) ?? Color.Orange; + + // yield roe + SObject roe = new ColoredObject(812, 1, color) + { + name = $"{input.Name} Roe", + preserve = { Value = SObject.PreserveType.Roe }, + preservedParentSheetIndex = { Value = input.ParentSheetIndex } + }; + roe.Price += input.Price / 2; + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 6 + 1, roe); + + // aged roe + if (pair.Key != 698) // aged sturgeon roe is caviar, which is a separate item + { + ColoredObject agedRoe = new ColoredObject(447, 1, color) + { + name = $"Aged {input.Name} Roe", + Category = -27, + preserve = { Value = SObject.PreserveType.AgedRoe }, + preservedParentSheetIndex = { Value = input.ParentSheetIndex }, + Price = roe.Price * 2 + }; + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 6 + 1, agedRoe); + } } - yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 5 + id, honey); } } } + + return GetAllRaw().Where(p => p != null); + } + + + /********* + ** Private methods + *********/ + /// <summary>Create a searchable item if valid.</summary> + /// <param name="type">The item type.</param> + /// <param name="id">The unique ID (if different from the item's parent sheet index).</param> + /// <param name="createItem">Create an item instance.</param> + private SearchableItem TryCreate(ItemType type, int id, Func<Item> createItem) + { + try + { + return new SearchableItem(type, id, createItem()); + } + catch + { + return null; // if some item data is invalid, just don't include it + } } } } |