From 5d5f7192dc49546610df13147f4e076eb199efc1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 2 Jul 2017 17:21:28 -0400 Subject: add item repository which returns all spawnable items in the game (#302) Based on code I wrote for CJB Item Spawner. --- src/TrainerMod/Framework/ItemData/ItemType.cs | 28 +++- .../Framework/ItemData/SearchableItem.cs | 41 +++++ src/TrainerMod/Framework/ItemRepository.cs | 179 +++++++++++++++++++++ src/TrainerMod/TrainerMod.csproj | 2 + 4 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 src/TrainerMod/Framework/ItemData/SearchableItem.cs create mode 100644 src/TrainerMod/Framework/ItemRepository.cs (limited to 'src') diff --git a/src/TrainerMod/Framework/ItemData/ItemType.cs b/src/TrainerMod/Framework/ItemData/ItemType.cs index f93160a2..423455e9 100644 --- a/src/TrainerMod/Framework/ItemData/ItemType.cs +++ b/src/TrainerMod/Framework/ItemData/ItemType.cs @@ -3,13 +3,37 @@ /// An item type that can be searched and added to the player through the console. internal enum ItemType { + /// A big craftable object in + BigCraftable, + + /// A item. + Boots, + + /// A fish item. + Fish, + + /// A flooring item. + Flooring, + + /// A item. + Furniture, + + /// A item. + Hat, + /// Any object in (except rings). Object, - /// A ring in . + /// A item. Ring, - /// A weapon from Data\weapons. + /// A tool. + Tool, + + /// A wall item. + Wallpaper, + + /// A or item. Weapon } } diff --git a/src/TrainerMod/Framework/ItemData/SearchableItem.cs b/src/TrainerMod/Framework/ItemData/SearchableItem.cs new file mode 100644 index 00000000..146da1a8 --- /dev/null +++ b/src/TrainerMod/Framework/ItemData/SearchableItem.cs @@ -0,0 +1,41 @@ +using StardewValley; + +namespace TrainerMod.Framework.ItemData +{ + /// A game item with metadata. + internal class SearchableItem + { + /********* + ** Accessors + *********/ + /// The item type. + public ItemType Type { get; } + + /// The item instance. + public Item Item { get; } + + /// The item's unique ID for its type. + public int ID { get; } + + /// The item's default name. + public string Name => this.Item.Name; + + /// The item's display name for the current language. + public string DisplayName => this.Item.DisplayName; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The item type. + /// The unique ID (if different from the item's parent sheet index). + /// The item instance. + public SearchableItem(ItemType type, int id, Item item) + { + this.Type = type; + this.ID = id; + this.Item = item; + } + } +} diff --git a/src/TrainerMod/Framework/ItemRepository.cs b/src/TrainerMod/Framework/ItemRepository.cs new file mode 100644 index 00000000..96d3159e --- /dev/null +++ b/src/TrainerMod/Framework/ItemRepository.cs @@ -0,0 +1,179 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using StardewValley; +using StardewValley.Objects; +using StardewValley.Tools; +using TrainerMod.Framework.ItemData; +using SObject = StardewValley.Object; + +namespace TrainerMod.Framework +{ + /// Provides methods for searching and constructing items. + internal class ItemRepository + { + /********* + ** Properties + *********/ + /// The custom ID offset for items don't have a unique ID in the game. + private readonly int CustomIDOffset = 1000; + + + /********* + ** Public methods + *********/ + /// Get all spawnable items. + public IEnumerable GetAll() + { + // get tools + for (int quality = Tool.stone; quality <= Tool.iridium; quality++) + { + yield return new SearchableItem(ItemType.Tool, ToolFactory.axe, ToolFactory.getToolFromDescription(ToolFactory.axe, quality)); + yield return new SearchableItem(ItemType.Tool, ToolFactory.hoe, ToolFactory.getToolFromDescription(ToolFactory.hoe, quality)); + yield return new SearchableItem(ItemType.Tool, ToolFactory.pickAxe, ToolFactory.getToolFromDescription(ToolFactory.pickAxe, quality)); + yield return new SearchableItem(ItemType.Tool, ToolFactory.wateringCan, ToolFactory.getToolFromDescription(ToolFactory.wateringCan, quality)); + if (quality != Tool.iridium) + yield return new SearchableItem(ItemType.Tool, ToolFactory.fishingRod, ToolFactory.getToolFromDescription(ToolFactory.fishingRod, quality)); + } + 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()); + + // wallpapers + for (int id = 0; id < 112; id++) + yield return new SearchableItem(ItemType.Wallpaper, id, new Wallpaper(id)); + + // flooring + for (int id = 0; id < 40; id++) + yield return new SearchableItem(ItemType.Flooring, id, new Wallpaper(id, isFloor: true)); + + // equipment + foreach (int id in Game1.content.Load>("Data\\Boots").Keys) + yield return new SearchableItem(ItemType.Boots, id, new Boots(id)); + foreach (int id in Game1.content.Load>("Data\\hats").Keys) + yield return new SearchableItem(ItemType.Hat, id, new Hat(id)); + foreach (int id in Game1.objectInformation.Keys) + { + if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) + yield return new SearchableItem(ItemType.Ring, id, new Ring(id)); + } + + // weapons + foreach (int id in Game1.content.Load>("Data\\weapons").Keys) + { + Item weapon = (id >= 32 && id <= 34) + ? (Item)new Slingshot(id) + : new MeleeWeapon(id); + yield return new SearchableItem(ItemType.Weapon, id, weapon); + } + + // furniture + foreach (int id in Game1.content.Load>("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)); + } + + // fish + foreach (int id in Game1.content.Load>("Data\\Fish").Keys) + yield return new SearchableItem(ItemType.Fish, id, new SObject(id, 999)); + + // craftables + foreach (int id in Game1.bigCraftablesInformation.Keys) + yield return new SearchableItem(ItemType.BigCraftable, id, new SObject(Vector2.Zero, id)); + + // objects + foreach (int id in Game1.objectInformation.Keys) + { + if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) + continue; // handled separated + + SObject item = new SObject(id, 1); + yield return new SearchableItem(ItemType.Object, id, item); + + // fruit products + if (item.category == SObject.FruitsCategory) + { + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset + id, new SObject(348, 1) + { + name = $"{item.Name} Wine", + price = item.price * 3, + preserve = SObject.PreserveType.Wine, + preservedParentSheetIndex = item.parentSheetIndex + }); + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 2 + id, new SObject(344, 1) + { + name = $"{item.Name} Jelly", + price = 50 + item.Price * 2, + preserve = SObject.PreserveType.Jelly, + preservedParentSheetIndex = item.parentSheetIndex + }); + } + + // vegetable products + else if (item.category == SObject.VegetableCategory) + { + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 3 + id, new SObject(350, 1) + { + name = $"{item.Name} Juice", + price = (int)(item.price * 2.25d), + preserve = SObject.PreserveType.Juice, + preservedParentSheetIndex = item.parentSheetIndex + }); + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 4 + id, new SObject(342, 1) + { + name = $"Pickled {item.Name}", + price = 50 + item.Price * 2, + preserve = SObject.PreserveType.Pickle, + preservedParentSheetIndex = item.parentSheetIndex + }); + } + + // flower honey + else if (item.category == SObject.flowersCategory) + { + // get honey type + SObject.HoneyType? type = null; + switch (item.parentSheetIndex) + { + 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; + } + + // yield honey + if (type != null) + { + SObject honey = new SObject(Vector2.Zero, 340, item.Name + " Honey", false, true, false, false) + { + name = "Wild Honey", + honeyType = type + }; + if (type != SObject.HoneyType.Wild) + { + honey.name = $"{item.Name} Honey"; + honey.price += item.price * 2; + } + yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 5 + id, honey); + } + } + } + } + } +} diff --git a/src/TrainerMod/TrainerMod.csproj b/src/TrainerMod/TrainerMod.csproj index ee17f970..18abf42f 100644 --- a/src/TrainerMod/TrainerMod.csproj +++ b/src/TrainerMod/TrainerMod.csproj @@ -88,6 +88,8 @@ + + -- cgit