Пример #1
0
        public static void performToolAction(byte toolIndex, byte toolUpgradeLevel, short xTile, short yTile, string locationName, byte facingDirection, short seed, long who)
        {
            Tool         toolFromDescription = ToolFactory.getToolFromDescription(toolIndex, (int)toolUpgradeLevel);
            GameLocation locationFromName    = Game1.getLocationFromName(locationName);

            Game1.otherFarmers[who].CurrentTool = toolFromDescription;
            Game1.recentMultiplayerRandom       = new Random((int)seed);
            if (locationFromName == null)
            {
                if (toolFromDescription is MeleeWeapon)
                {
                    Game1.otherFarmers[who].faceDirection((int)facingDirection);
                    (toolFromDescription as MeleeWeapon).DoDamage(Game1.currentLocation, (int)xTile, (int)yTile, Game1.otherFarmers[who].facingDirection, 1, Game1.otherFarmers[who]);
                }
                else
                {
                    toolFromDescription.DoFunction(Game1.currentLocation, (int)xTile, (int)yTile, 1, Game1.otherFarmers[who]);
                }
            }
            else if (toolFromDescription is MeleeWeapon)
            {
                Game1.otherFarmers[who].faceDirection((int)facingDirection);
                (toolFromDescription as MeleeWeapon).DoDamage(locationFromName, (int)xTile, (int)yTile, Game1.otherFarmers[who].facingDirection, 1, Game1.otherFarmers[who]);
            }
            else
            {
                toolFromDescription.DoFunction(locationFromName, (int)xTile, (int)yTile, 1, Game1.otherFarmers[who]);
            }
            if (Game1.IsServer)
            {
                MultiplayerUtility.broadcastToolAction(toolFromDescription, (int)xTile, (int)yTile, locationName, facingDirection, seed, who);
            }
        }
Пример #2
0
        /// <summary>
        /// Generate every item known to man, or at least those we're interested
        /// in using for categorization.
        /// </summary>
        ///
        /// <remarks>
        /// Substantially based on code from Pathoschild's LookupAnything mod.
        /// </remarks>
        ///
        /// <returns>A collection of all of the item entries.</returns>
        private IEnumerable <Item> DiscoverItems()
        {
            // upgradable tools
            yield return(ToolFactory.getToolFromDescription(ToolFactory.axe, Tool.stone));

            yield return(ToolFactory.getToolFromDescription(ToolFactory.hoe, Tool.stone));

            yield return(ToolFactory.getToolFromDescription(ToolFactory.pickAxe, Tool.stone));

            yield return(ToolFactory.getToolFromDescription(ToolFactory.wateringCan, Tool.stone));

            yield return(ToolFactory.getToolFromDescription(ToolFactory.fishingRod, Tool.stone));

            // other tools
            yield return(new MilkPail());

            yield return(new Shears());

            yield return(new Pan());

            yield return(new MagnifyingGlass());

            yield return(new Wand());

            // equipment
            foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\Boots").Keys)
            {
                yield return(new Boots(id));
            }

            foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\hats").Keys)
            {
                yield return(new Hat(id));
            }

            for (int id = Ring.ringLowerIndexRange; id <= Ring.ringUpperIndexRange; id++)
            {
                yield return(new Ring(id));
            }

            // weapons
            foreach (var item in ItemHelper.GetWeapons())
            {
                yield return(item);
            }

            // objects
            foreach (int id in Game1.objectInformation.Keys)
            {
                if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange)
                {
                    continue; // handled separated
                }
                yield return(new StardewObject(id, 1));
            }
        }
Пример #3
0
        public Item GetOne()
        {
            switch (ItemType)
            {
            case ItemType.Boots:
                return(new Boots(ObjectIndex));

            case ItemType.Furniture:
                return(new Furniture(ObjectIndex, Vector2.Zero));

            case ItemType.Hat:
                return(new Hat(ObjectIndex));

            case ItemType.Fish:
            case ItemType.Object:
            case ItemType.BigCraftable:
                return(new Object(ObjectIndex, 1));

            case ItemType.Ring:
                return(new Ring(ObjectIndex));

            case ItemType.Tool:
                return(ToolFactory.getToolFromDescription((byte)ObjectIndex, Tool.stone));

            case ItemType.Wallpaper:
                return(new Wallpaper(ObjectIndex));

            case ItemType.Flooring:
                return(new Wallpaper(ObjectIndex, true));

            case ItemType.Weapon:
                return(new MeleeWeapon(ObjectIndex));

            case ItemType.Gate:
                return(new Fence(Vector2.Zero, ObjectIndex, true));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #4
0
        protected ItemKey CreateItemKey(Item item)
        {
            switch (item)
            {
            // Tool family overrides
            case Axe _:
                return(ToolFactory.getToolFromDescription(ToolFactory.axe, 0).ToItemKey());

            case Pickaxe _:
                return(ToolFactory.getToolFromDescription(ToolFactory.pickAxe, 0).ToItemKey());

            case Hoe _:
                return(ToolFactory.getToolFromDescription(ToolFactory.hoe, 0).ToItemKey());

            case WateringCan _:
                return(ToolFactory.getToolFromDescription(ToolFactory.wateringCan, 0).ToItemKey());

            case FishingRod _:
                return(ToolFactory.getToolFromDescription(ToolFactory.fishingRod, 0).ToItemKey());

            default:
                return(item.ToItemKey());
            }
        }
Пример #5
0
        public IEnumerable <SearchableItem> GetAll()
        {
            IEnumerable <SearchableItem> GetAllRaw()
            {
                // 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()));

                // wallpapers
                for (int id = 0; id < 112; id++)
                {
                    yield return(this.TryCreate(ItemType.Wallpaper, id, () => new Wallpaper(id)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                // flooring
                for (int id = 0; id < 40; id++)
                {
                    yield return(this.TryCreate(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(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)));
                    }
                }

                // 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)
                                                ));
                }

                // 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)));
                    }
                }

                // craftables
                foreach (int id in Game1.bigCraftablesInformation.Keys)
                {
                    yield return(this.TryCreate(ItemType.BigCraftable, id, () => new SObject(Vector2.Zero, id)));
                }

                // secret notes
                foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\SecretNotes").Keys)
                {
                    yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset + id, () =>
                    {
                        SObject note = new SObject(79, 1);
                        note.name = $"{note.name} #{id}";
                        return note;
                    }));
                }

                // 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
                    }
                    // spawn main item
                    SObject item;
                    {
                        SearchableItem main = this.TryCreate(ItemType.Object, id, () => new SObject(id, 1));
                        yield return(main);

                        item = main?.Item as SObject;
                    }
                    if (item == null)
                    {
                        continue;
                    }

                    // fruit products
                    if (item.Category == SObject.FruitsCategory)
                    {
                        // 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;
                        }));
                    }

                    // vegetable products
                    else if (item.Category == SObject.VegetableCategory)
                    {
                        // 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, () =>
                        {
                            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;
                        }));
                    }

                    // flower honey
                    else if (item.Category == SObject.flowersCategory)
                    {
                        yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () =>
                        {
                            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;
                        }));
                    }
                }
            }

            return(GetAllRaw().Where(p => p != null));
        }
Пример #6
0
        public IEnumerable <SearchableItem> GetAll()
        {
            //
            //
            // Be careful about closure variable capture here!
            //
            // SearchableItem stores the Func<Item> to create new instances later. Loop variables passed into the
            // function will be captured, so every func in the loop will use the value from the last iteration. Use the
            // TryCreate(type, id, entity => item) form to avoid the issue, or create a local variable to pass in.
            //
            //


            IEnumerable <SearchableItem> GetAllRaw()
            {
                // get tools
                for (int q = Tool.stone; q <= Tool.iridium; q++)
                {
                    int quality = q;

                    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()));

                // clothing
                {
                    // items
                    HashSet <int> clothingIds = new HashSet <int>();
                    foreach (int id in Game1.clothingInformation.Keys)
                    {
                        if (id < 0)
                        {
                            continue; // placeholder data for character customization clothing below
                        }
                        clothingIds.Add(id);
                        yield return(this.TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID)));
                    }

                    // character customization shirts (some shirts in this range have no data, but game has special logic to handle them)
                    for (int id = 1000; id <= 1111; id++)
                    {
                        if (!clothingIds.Contains(id))
                        {
                            yield return(this.TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID)));
                        }
                    }
                }

                // wallpapers
                for (int id = 0; id < 112; id++)
                {
                    yield return(this.TryCreate(ItemType.Wallpaper, id, p => new Wallpaper(p.ID)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                // flooring
                for (int id = 0; id < 56; id++)
                {
                    yield return(this.TryCreate(ItemType.Flooring, id, p => new Wallpaper(p.ID, isFloor: true)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                // equipment
                foreach (int id in this.TryLoad <int, string>("Data\\Boots").Keys)
                {
                    yield return(this.TryCreate(ItemType.Boots, id, p => new Boots(p.ID)));
                }
                foreach (int id in this.TryLoad <int, string>("Data\\hats").Keys)
                {
                    yield return(this.TryCreate(ItemType.Hat, id, p => new Hat(p.ID)));
                }

                // weapons
                foreach (int id in this.TryLoad <int, string>("Data\\weapons").Keys)
                {
                    yield return(this.TryCreate(ItemType.Weapon, id, p => (p.ID >= 32 && p.ID <= 34)
                        ? (Item) new Slingshot(p.ID)
                        : new MeleeWeapon(p.ID)
                                                ));
                }

                // furniture
                foreach (int id in this.TryLoad <int, string>("Data\\Furniture").Keys)
                {
                    yield return(this.TryCreate(ItemType.Furniture, id, p => Furniture.GetFurnitureInstance(p.ID)));
                }

                // craftables
                foreach (int id in Game1.bigCraftablesInformation.Keys)
                {
                    yield return(this.TryCreate(ItemType.BigCraftable, id, p => new SObject(Vector2.Zero, p.ID)));
                }

                // objects
                foreach (int id in Game1.objectInformation.Keys)
                {
                    string[] fields = Game1.objectInformation[id]?.Split('/');

                    // secret notes
                    if (id == 79)
                    {
                        foreach (int secretNoteId in this.TryLoad <int, string>("Data\\SecretNotes").Keys)
                        {
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset + secretNoteId, _ =>
                            {
                                SObject note = new SObject(79, 1);
                                note.name = $"{note.name} #{secretNoteId}";
                                return note;
                            }));
                        }
                    }

                    // ring
                    else if (id != 801 && fields?.Length >= 4 && fields[3] == "Ring") // 801 = wedding ring, which isn't an equippable ring
                    {
                        yield return(this.TryCreate(ItemType.Ring, id, p => new Ring(p.ID)));
                    }

                    // item
                    else
                    {
                        // spawn main item
                        SObject item = null;
                        yield return(this.TryCreate(ItemType.Object, id, p =>
                        {
                            return item = (p.ID == 812 // roe
                                ? new ColoredObject(p.ID, 1, Color.White)
                                : new SObject(p.ID, 1)
                                           );
                        }));

                        if (item == null)
                        {
                            continue;
                        }

                        // flavored items
                        switch (item.Category)
                        {
                        // fruit products
                        case SObject.FruitsCategory:
                            // wine
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 2 + item.ParentSheetIndex, _ => new SObject(348, 1)
                            {
                                Name = $"{item.Name} Wine",
                                Price = item.Price * 3,
                                preserve = { SObject.PreserveType.Wine },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            // jelly
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 3 + item.ParentSheetIndex, _ => new SObject(344, 1)
                            {
                                Name = $"{item.Name} Jelly",
                                Price = 50 + item.Price * 2,
                                preserve = { SObject.PreserveType.Jelly },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            break;

                        // vegetable products
                        case SObject.VegetableCategory:
                            // juice
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 4 + item.ParentSheetIndex, _ => new SObject(350, 1)
                            {
                                Name = $"{item.Name} Juice",
                                Price = (int)(item.Price * 2.25d),
                                preserve = { SObject.PreserveType.Juice },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            // pickled
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + item.ParentSheetIndex, _ => new SObject(342, 1)
                            {
                                Name = $"Pickled {item.Name}",
                                Price = 50 + item.Price * 2,
                                preserve = { SObject.PreserveType.Pickle },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            break;

                        // flower honey
                        case SObject.flowersCategory:
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + item.ParentSheetIndex, _ =>
                            {
                                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;
                            }));

                            break;

                        // roe and aged roe (derived from FishPond.GetFishProduce)
                        case SObject.sellAtFishShopCategory when item.ParentSheetIndex == 812:
                        {
                            this.GetRoeContextTagLookups(out HashSet <string> simpleTags, out List <List <string> > complexTags);

                            foreach (var pair in Game1.objectInformation)
                            {
                                // get input
                                SObject input     = this.TryCreate(ItemType.Object, pair.Key, p => new SObject(p.ID, 1))?.Item as SObject;
                                var     inputTags = input?.GetContextTags();
                                if (inputTags?.Any() != true)
                                {
                                    continue;
                                }

                                // check if roe-producing fish
                                if (!inputTags.Any(tag => simpleTags.Contains(tag)) && !complexTags.Any(set => set.All(tag => input.HasContextTag(tag))))
                                {
                                    continue;
                                }

                                // yield roe
                                SObject roe   = null;
                                Color   color = this.GetRoeColor(input);
                                yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 7 + item.ParentSheetIndex, _ =>
                                    {
                                        roe = new ColoredObject(812, 1, color)
                                        {
                                            name = $"{input.Name} Roe",
                                            preserve = { Value = SObject.PreserveType.Roe },
                                            preservedParentSheetIndex = { Value = input.ParentSheetIndex }
                                        };
                                        roe.Price += input.Price / 2;
                                        return roe;
                                    }));

                                // aged roe
                                if (roe != null && pair.Key != 698)         // aged sturgeon roe is caviar, which is a separate item
                                {
                                    yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 7 + item.ParentSheetIndex, _ => 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
                                        }));
                                }
                            }
                        }
                        break;
                        }
                    }
                }
            }

            return(GetAllRaw().Where(p => p != null));
        }
Пример #7
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get all spawnable items.</summary>
        public IEnumerable <SearchableItem> 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 <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)
            {
                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 <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));
            }

            // 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)));
                }
            }

            // fish
            foreach (int id in Game1.content.Load <Dictionary <int, string> >("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)));
            }

            // 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));
            }

            // 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
                }
                SObject item = new SObject(id, 1);
                yield return(new SearchableItem(ItemType.Object, id, item));

                // fruit products
                if (item.category == SObject.FruitsCategory)
                {
                    // 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)
                    {
                        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));
                }

                // vegetable products
                else if (item.category == SObject.VegetableCategory)
                {
                    // 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)
                    {
                        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));
                }

                // 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"
                        };
                        honey.honeyType.Value = 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));
                    }
                }
            }
        }
Пример #8
0
        public IEnumerable <SearchableItem> GetAll()
        {
            IEnumerable <SearchableItem> GetAllRaw()
            {
                // 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()));

                // clothing
                foreach (int id in Game1.clothingInformation.Keys)
                {
                    yield return(this.TryCreate(ItemType.Clothing, id, () => new Clothing(id)));
                }

                // wallpapers
                for (int id = 0; id < 112; id++)
                {
                    yield return(this.TryCreate(ItemType.Wallpaper, id, () => new Wallpaper(id)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                // flooring
                for (int id = 0; id < 56; id++)
                {
                    yield return(this.TryCreate(ItemType.Flooring, id, () => new Wallpaper(id, isFloor: true)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                // equipment
                foreach (int id in this.TryLoad <int, string>("Data\\Boots").Keys)
                {
                    yield return(this.TryCreate(ItemType.Boots, id, () => new Boots(id)));
                }
                foreach (int id in this.TryLoad <int, string>("Data\\hats").Keys)
                {
                    yield return(this.TryCreate(ItemType.Hat, id, () => new Hat(id)));
                }

                // weapons
                foreach (int id in this.TryLoad <int, string>("Data\\weapons").Keys)
                {
                    yield return(this.TryCreate(ItemType.Weapon, id, () => (id >= 32 && id <= 34)
                        ? (Item) new Slingshot(id)
                        : new MeleeWeapon(id)
                                                ));
                }

                // furniture
                foreach (int id in this.TryLoad <int, string>("Data\\Furniture").Keys)
                {
                    if (id == 1466 || id == 1468 || id == 1680)
                    {
                        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)));
                    }
                }

                // craftables
                foreach (int id in Game1.bigCraftablesInformation.Keys)
                {
                    yield return(this.TryCreate(ItemType.BigCraftable, id, () => new SObject(Vector2.Zero, id)));
                }

                // objects
                foreach (int id in Game1.objectInformation.Keys)
                {
                    string[] fields = Game1.objectInformation[id]?.Split('/');

                    // secret notes
                    if (id == 79)
                    {
                        foreach (int secretNoteId in this.TryLoad <int, string>("Data\\SecretNotes").Keys)
                        {
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset + secretNoteId, () =>
                            {
                                SObject note = new SObject(79, 1);
                                note.name = $"{note.name} #{secretNoteId}";
                                return note;
                            }));
                        }
                    }

                    // ring
                    else if (id != 801 && fields?.Length >= 4 && fields[3] == "Ring") // 801 = wedding ring, which isn't an equippable ring
                    {
                        yield return(this.TryCreate(ItemType.Ring, id, () => new Ring(id)));
                    }

                    // item
                    else
                    {
                        // spawn main item
                        SObject item = null;
                        yield return(this.TryCreate(ItemType.Object, id, () =>
                        {
                            return item = (id == 812 // roe
                                ? new ColoredObject(id, 1, Color.White)
                                : new SObject(id, 1)
                                           );
                        }));

                        if (item == null)
                        {
                            continue;
                        }

                        // flavored items
                        switch (item.Category)
                        {
                        // fruit products
                        case SObject.FruitsCategory:
                            // wine
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 2 + id, () => new SObject(348, 1)
                            {
                                Name = $"{item.Name} Wine",
                                Price = item.Price * 3,
                                preserve = { SObject.PreserveType.Wine },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            // jelly
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 3 + id, () => new SObject(344, 1)
                            {
                                Name = $"{item.Name} Jelly",
                                Price = 50 + item.Price * 2,
                                preserve = { SObject.PreserveType.Jelly },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            break;

                        // vegetable products
                        case SObject.VegetableCategory:
                            // juice
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 4 + id, () => new SObject(350, 1)
                            {
                                Name = $"{item.Name} Juice",
                                Price = (int)(item.Price * 2.25d),
                                preserve = { SObject.PreserveType.Juice },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            // pickled
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () => new SObject(342, 1)
                            {
                                Name = $"Pickled {item.Name}",
                                Price = 50 + item.Price * 2,
                                preserve = { SObject.PreserveType.Pickle },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            break;

                        // flower honey
                        case SObject.flowersCategory:
                            yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () =>
                            {
                                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;
                            }));

                            break;

                        // roe and aged roe (derived from FishPond.GetFishProduce)
                        case SObject.sellAtFishShopCategory when id == 812:
                            foreach (var pair in Game1.objectInformation)
                            {
                                // get input
                                SObject input = this.TryCreate(ItemType.Object, -1, () => new SObject(pair.Key, 1))?.Item as SObject;
                                if (input == null || input.Category != SObject.FishCategory)
                                {
                                    continue;
                                }
                                Color color = this.GetRoeColor(input);

                                // yield roe
                                SObject roe = null;
                                yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 7 + id, () =>
                                {
                                    roe = new ColoredObject(812, 1, color)
                                    {
                                        name = $"{input.Name} Roe",
                                        preserve = { Value = SObject.PreserveType.Roe },
                                        preservedParentSheetIndex = { Value = input.ParentSheetIndex }
                                    };
                                    roe.Price += input.Price / 2;
                                    return roe;
                                }));

                                // aged roe
                                if (roe != null && pair.Key != 698)     // aged sturgeon roe is caviar, which is a separate item
                                {
                                    yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 7 + id, () => 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
                                    }));
                                }
                            }
                            break;
                        }
                    }
                }
            }

            return(GetAllRaw().Where(p => p != null));
        }
Пример #9
0
        private static void LoadItems()
        {
            ItemMenu.ItemsLoaded = true;
            ItemMenu.ItemList    = new List <Item>
            {
                ToolFactory.getToolFromDescription(0, 0),
                ToolFactory.getToolFromDescription(0, 1),
                ToolFactory.getToolFromDescription(0, 2),
                ToolFactory.getToolFromDescription(0, 3),
                ToolFactory.getToolFromDescription(0, 4),
                ToolFactory.getToolFromDescription(1, 0),
                ToolFactory.getToolFromDescription(1, 1),
                ToolFactory.getToolFromDescription(1, 2),
                ToolFactory.getToolFromDescription(1, 3),
                ToolFactory.getToolFromDescription(1, 4),
                ToolFactory.getToolFromDescription(2, 0),
                ToolFactory.getToolFromDescription(2, 1),
                ToolFactory.getToolFromDescription(2, 2),
                ToolFactory.getToolFromDescription(2, 3),
                ToolFactory.getToolFromDescription(3, 0),
                ToolFactory.getToolFromDescription(3, 1),
                ToolFactory.getToolFromDescription(3, 2),
                ToolFactory.getToolFromDescription(3, 3),
                ToolFactory.getToolFromDescription(3, 4),
                ToolFactory.getToolFromDescription(4, 0),
                ToolFactory.getToolFromDescription(4, 1),
                ToolFactory.getToolFromDescription(4, 2),
                ToolFactory.getToolFromDescription(4, 3),
                ToolFactory.getToolFromDescription(4, 4),
                new MilkPail(),
                new Shears(),
                new Pan()
            };

            foreach (KeyValuePair <string, string> o in CraftingRecipe.craftingRecipes)
            {
                CraftingRecipe rec  = new CraftingRecipe(o.Key, false);
                Item           item = rec.createItem();
                if (item != null)
                {
                    ItemMenu.ItemList.Add(item);
                }
            }

            for (int i = 0; i < 112; i++)
            {
                ItemMenu.ItemList.Add(new Wallpaper(i)
                {
                    category = -24
                });
            }

            for (int i = 0; i < 40; i++)
            {
                ItemMenu.ItemList.Add(new Wallpaper(i, true)
                {
                    category = -24
                });
            }

            foreach (KeyValuePair <int, string> o in Game1.content.Load <Dictionary <int, string> >("Data\\Boots"))
            {
                Item item = new Boots(o.Key);
                ItemMenu.ItemList.Add(item);
            }

            foreach (KeyValuePair <int, string> o in Game1.content.Load <Dictionary <int, string> >("Data\\hats"))
            {
                Item item = new Hat(o.Key);
                ItemMenu.ItemList.Add(item);
            }

            foreach (KeyValuePair <int, string> o in Game1.content.Load <Dictionary <int, string> >("Data\\Furniture"))
            {
                Item item = new Furniture(o.Key, Vector2.Zero);

                if (o.Key == 1466 || o.Key == 1468)
                {
                    item = new TV(o.Key, Vector2.Zero);
                }
                ItemMenu.ItemList.Add(item);
            }

            foreach (KeyValuePair <int, string> o in Game1.content.Load <Dictionary <int, string> >("Data\\weapons"))
            {
                Item item = new MeleeWeapon(o.Key);

                if (o.Key >= 32 && o.Key <= 34)
                {
                    item = new Slingshot(o.Key);
                }

                ItemMenu.ItemList.Add(item);
            }

            foreach (KeyValuePair <int, string> o in Game1.content.Load <Dictionary <int, string> >("Data\\Fish"))
            {
                Item item = new SObject(o.Key, 999);
                item.category = -4;
                ItemMenu.ItemList.Add(item);
            }

            foreach (KeyValuePair <int, string> o in Game1.bigCraftablesInformation)
            {
                if (ItemMenu.HasItem(o.Key, o.Value.Split('/')[0]))
                {
                    continue;
                }

                ItemMenu.ItemList.Add(new SObject(Vector2.Zero, o.Key));
            }

            foreach (KeyValuePair <int, string> o in Game1.objectInformation)
            {
                if (ItemMenu.HasItem(o.Key, o.Value.Split('/')[0]))
                {
                    continue;
                }

                string[] info = o.Value.Split('/');
                if (info.Length >= 3)
                {
                    if (info[3].StartsWith("Ring"))
                    {
                        ItemMenu.ItemList.Add(new Ring(o.Key));
                        continue;
                    }
                    SObject item = new SObject(o.Key, 1);
                    ItemMenu.ItemList.Add(item);

                    if (item.category == -79)
                    {
                        ItemMenu.ItemList.Add(new SObject(Vector2.Zero, 348, item.Name + " Wine", false, true, false, false)
                        {
                            name  = item.Name + " Wine",
                            price = item.price * 3
                        });
                    }
                    if (item.category == -75)
                    {
                        ItemMenu.ItemList.Add(new SObject(Vector2.Zero, 350, item.Name + " Juice", false, true, false, false)
                        {
                            name  = item.Name + " Juice",
                            price = (int)(item.price * 2.25d)
                        });
                    }

                    if (item.category == -79)
                    {
                        ItemMenu.ItemList.Add(new SObject(Vector2.Zero, 344, item.Name + " Jelly", false, true, false, false)
                        {
                            name  = item.Name + " Jelly",
                            price = 50 + item.Price * 2
                        });
                    }
                    if (item.category == -75)
                    {
                        ItemMenu.ItemList.Add(new SObject(Vector2.Zero, 342, "Pickled " + item.Name, false, true, false, false)
                        {
                            name  = "Pickled " + item.Name,
                            price = 50 + item.Price * 2
                        });
                    }
                }
            }
        }
Пример #10
0
        public IEnumerable <SearchableItem> GetAll(ItemType[]?itemTypes = null, bool includeVariants = true)
        {
            //
            //
            // Be careful about closure variable capture here!
            //
            // SearchableItem stores the Func<Item> to create new instances later. Loop variables passed into the
            // function will be captured, so every func in the loop will use the value from the last iteration. Use the
            // TryCreate(type, id, entity => item) form to avoid the issue, or create a local variable to pass in.
            //
            //

            IEnumerable <SearchableItem?> GetAllRaw()
            {
                HashSet <ItemType>?types = itemTypes?.Any() == true ? new HashSet <ItemType>(itemTypes) : null;

                bool ShouldGet(ItemType type) => types == null || types.Contains(type);

                // get tools
                if (ShouldGet(ItemType.Tool))
                {
                    for (int q = Tool.stone; q <= Tool.iridium; q++)
                    {
                        int quality = q;

                        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()));
                }

                // clothing
                if (ShouldGet(ItemType.Clothing))
                {
                    foreach (int id in this.GetShirtIds())
                    {
                        yield return(this.TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID)));
                    }
                }

                // wallpapers
                if (ShouldGet(ItemType.Wallpaper))
                {
                    for (int id = 0; id < 112; id++)
                    {
                        yield return(this.TryCreate(ItemType.Wallpaper, id, p => new Wallpaper(p.ID)
                        {
                            Category = SObject.furnitureCategory
                        }));
                    }
                }

                // flooring
                if (ShouldGet(ItemType.Flooring))
                {
                    for (int id = 0; id < 56; id++)
                    {
                        yield return(this.TryCreate(ItemType.Flooring, id, p => new Wallpaper(p.ID, isFloor: true)
                        {
                            Category = SObject.furnitureCategory
                        }));
                    }
                }

                // equipment
                if (ShouldGet(ItemType.Boots))
                {
                    foreach (int id in this.TryLoad <int, string>("Data\\Boots").Keys)
                    {
                        yield return(this.TryCreate(ItemType.Boots, id, p => new Boots(p.ID)));
                    }
                }
                if (ShouldGet(ItemType.Hat))
                {
                    foreach (int id in this.TryLoad <int, string>("Data\\hats").Keys)
                    {
                        yield return(this.TryCreate(ItemType.Hat, id, p => new Hat(p.ID)));
                    }
                }

                // weapons
                if (ShouldGet(ItemType.Weapon))
                {
                    foreach (int id in this.TryLoad <int, string>("Data\\weapons").Keys)
                    {
                        yield return(this.TryCreate(ItemType.Weapon, id, p => p.ID is >= 32 and <= 34
                            ? new Slingshot(p.ID)
                            : new MeleeWeapon(p.ID)
                                                    ));
                    }
                }

                // furniture
                if (ShouldGet(ItemType.Furniture))
                {
                    foreach (int id in this.TryLoad <int, string>("Data\\Furniture").Keys)
                    {
                        yield return(this.TryCreate(ItemType.Furniture, id, p => Furniture.GetFurnitureInstance(p.ID)));
                    }
                }

                // craftables
                if (ShouldGet(ItemType.BigCraftable))
                {
                    foreach (int id in Game1.bigCraftablesInformation.Keys)
                    {
                        yield return(this.TryCreate(ItemType.BigCraftable, id, p => new SObject(Vector2.Zero, p.ID)));
                    }
                }

                // objects
                if (ShouldGet(ItemType.Object) || ShouldGet(ItemType.Ring))
                {
                    foreach (int id in Game1.objectInformation.Keys)
                    {
                        string[]? fields = Game1.objectInformation[id]?.Split('/');

                        // ring
                        if (id != 801 && fields?.Length >= 4 && fields[3] == "Ring") // 801 = wedding ring, which isn't an equippable ring
                        {
                            if (ShouldGet(ItemType.Ring))
                            {
                                yield return(this.TryCreate(ItemType.Ring, id, p => new Ring(p.ID)));
                            }
                        }

                        // journal scrap
                        else if (id == 842)
                        {
                            if (ShouldGet(ItemType.Object))
                            {
                                foreach (SearchableItem?journalScrap in this.GetSecretNotes(isJournalScrap: true))
                                {
                                    yield return(journalScrap);
                                }
                            }
                        }

                        // secret notes
                        else if (id == 79)
                        {
                            if (ShouldGet(ItemType.Object))
                            {
                                foreach (SearchableItem?secretNote in this.GetSecretNotes(isJournalScrap: false))
                                {
                                    yield return(secretNote);
                                }
                            }
                        }

                        // object
                        else if (ShouldGet(ItemType.Object))
                        {
                            // spawn main item
                            SObject?item = null;
                            yield return(this.TryCreate(ItemType.Object, id, p =>
                            {
                                return item = (p.ID == 812 // roe
                                    ? new ColoredObject(p.ID, 1, Color.White)
                                    : new SObject(p.ID, 1)
                                               );
                            }));

                            if (item == null)
                            {
                                continue;
                            }

                            // flavored items
                            if (includeVariants)
                            {
                                foreach (SearchableItem?variant in this.GetFlavoredObjectVariants(item))
                                {
                                    yield return(variant);
                                }
                            }
                        }
                    }
                }
            }

            return(
                from item in GetAllRaw()
                where item != null
                select item
                );
        }
Пример #11
0
        private static IEnumerable <(string key, IItemFactory itemFactory)> GetItemFactories(
            IAssetProvider assetProvider
            )
        {
            foreach (var quality in Enumerable.Range(Tool.stone, Tool.iridium - Tool.stone + 1))
            {
                // Axe
                var axeKey     = NamespacedKey.SdvTool(ToolTypes.Axe, quality).Key;
                var axeFactory = new SimpleItemFactory(
                    ItemTypes.Tool,
                    () => ToolFactory.getToolFromDescription(ToolFactory.axe, quality)
                    );
                yield return(axeKey, axeFactory);

                // Hoe
                var hoeKey     = NamespacedKey.SdvTool(ToolTypes.Hoe, quality).Key;
                var hoeFactory = new SimpleItemFactory(
                    ItemTypes.Tool,
                    () => ToolFactory.getToolFromDescription(ToolFactory.hoe, quality)
                    );
                yield return(hoeKey, hoeFactory);

                // Pickaxe
                var pickKey     = NamespacedKey.SdvTool(ToolTypes.Pickaxe, quality).Key;
                var pickFactory = new SimpleItemFactory(
                    ItemTypes.Tool,
                    () => ToolFactory.getToolFromDescription(ToolFactory.pickAxe, quality)
                    );
                yield return(pickKey, pickFactory);

                // Watering can
                var canKey     = NamespacedKey.SdvTool(ToolTypes.WateringCan, quality).Key;
                var canFactory = new SimpleItemFactory(
                    ItemTypes.Tool,
                    () => ToolFactory.getToolFromDescription(ToolFactory.wateringCan, quality)
                    );
                yield return(canKey, canFactory);

                // Fishing rod
                if (quality < Tool.iridium)
                {
                    var rodKey     = NamespacedKey.SdvTool(ToolTypes.FishingRod, quality).Key;
                    var rodFactory = new SimpleItemFactory(
                        ItemTypes.Tool,
                        () => ToolFactory.getToolFromDescription(ToolFactory.fishingRod, quality)
                        );
                    yield return(rodKey, rodFactory);
                }
            }

            yield return(NamespacedKey.SdvTool(ToolTypes.MilkPail).Key,
                         new SimpleItemFactory(ItemTypes.Tool, () => new MilkPail()));

            yield return(NamespacedKey.SdvTool(ToolTypes.Shears).Key,
                         new SimpleItemFactory(ItemTypes.Tool, () => new Shears()));

            yield return(NamespacedKey.SdvTool(ToolTypes.Pan).Key,
                         new SimpleItemFactory(ItemTypes.Tool, () => new Pan()));

            yield return(NamespacedKey.SdvTool(ToolTypes.Wand).Key,
                         new SimpleItemFactory(ItemTypes.Tool, () => new Wand()));

            // Clothing
            // TODO: dynamic clothing?
            var clothingInformation = assetProvider.Load <Dictionary <int, string> >(@"Data\ClothingInformation");
            var clothingIds         = clothingInformation.Keys.ToHashSet();

            foreach (var id in clothingIds)
            {
                var key         = NamespacedKey.SdvClothing(id).Key;
                var itemFactory = new SimpleItemFactory(ItemTypes.Clothing, () => new Clothing(id));
                yield return(key, itemFactory);
            }

            // Wallpapers
            foreach (var id in Enumerable.Range(0, 112))
            {
                var key         = NamespacedKey.SdvWallpaper(id).Key;
                var itemFactory = new SimpleItemFactory(ItemTypes.Wallpaper, () => new Wallpaper(id));
                yield return(key, itemFactory);
            }

            // Flooring
            foreach (var id in Enumerable.Range(0, 56))
            {
                var key         = NamespacedKey.SdvFlooring(id).Key;
                var itemFactory = new SimpleItemFactory(ItemTypes.Flooring, () => new Wallpaper(id, true));
                yield return(key, itemFactory);
            }

            // Boots
            var boots = assetProvider.Load <Dictionary <int, string> >(@"Data\Boots");

            foreach (var id in boots.Keys)
            {
                var key         = NamespacedKey.SdvBoots(id).Key;
                var itemFactory = new SimpleItemFactory(ItemTypes.Boots, () => new Boots(id));
                yield return(key, itemFactory);
            }

            // Hats
            var hats = assetProvider.Load <Dictionary <int, string> >(@"Data\hats");

            foreach (var id in hats.Keys)
            {
                var key         = NamespacedKey.SdvHat(id).Key;
                var itemFactory = new SimpleItemFactory(ItemTypes.Hat, () => new Hat(id));
                yield return(key, itemFactory);
            }

            // Weapons
            var weapons = assetProvider.Load <Dictionary <int, string> >(@"Data\weapons");

            foreach (var id in weapons.Keys)
            {
                var key         = NamespacedKey.SdvWeapon(id).Key;
                var itemFactory = id switch
                {
Пример #12
0
        public IEnumerable <SearchableItem> GetAll()
        {
            IEnumerable <SearchableItem> GetAllRaw()
            {
                for (var q = Tool.stone; q <= Tool.iridium; q++)
                {
                    var quality = q;

                    yield return(TryCreate(ItemType.Tool, ToolFactory.axe,
                                           _ => ToolFactory.getToolFromDescription(ToolFactory.axe, quality)));

                    yield return(TryCreate(ItemType.Tool, ToolFactory.hoe,
                                           _ => ToolFactory.getToolFromDescription(ToolFactory.hoe, quality)));

                    yield return(TryCreate(ItemType.Tool, ToolFactory.pickAxe,
                                           _ => ToolFactory.getToolFromDescription(ToolFactory.pickAxe, quality)));

                    yield return(TryCreate(ItemType.Tool, ToolFactory.wateringCan,
                                           _ => ToolFactory.getToolFromDescription(ToolFactory.wateringCan, quality)));

                    if (quality != Tool.iridium)
                    {
                        yield return(TryCreate(ItemType.Tool, ToolFactory.fishingRod,
                                               _ => ToolFactory.getToolFromDescription(ToolFactory.fishingRod, quality)));
                    }
                }

                // these don't have any sort of ID, so we'll just assign some arbitrary ones
                yield return(TryCreate(ItemType.Tool, CustomIDOffset, _ => new MilkPail()));

                yield return(TryCreate(ItemType.Tool, CustomIDOffset + 1, _ => new Shears()));

                yield return(TryCreate(ItemType.Tool, CustomIDOffset + 2, _ => new Pan()));

                yield return(TryCreate(ItemType.Tool, CustomIDOffset + 3, _ => new Wand()));

                {
                    var clothingIds = new HashSet <int>();
                    foreach (var id in Game1.clothingInformation.Keys)
                    {
                        if (id < 0)
                        {
                            continue;
                        }

                        clothingIds.Add(id);
                        yield return(TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID)));
                    }

                    for (var id = 1000; id <= 1111; id++)
                    {
                        if (!clothingIds.Contains(id))
                        {
                            yield return(TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID)));
                        }
                    }
                }

                for (var id = 0; id < 112; id++)
                {
                    yield return(TryCreate(ItemType.Wallpaper, id,
                                           p => new Wallpaper(p.ID)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                for (var id = 0; id < 56; id++)
                {
                    yield return(TryCreate(ItemType.Flooring, id,
                                           p => new Wallpaper(p.ID, true)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                foreach (var id in TryLoad <int, string>("Data\\Boots").Keys)
                {
                    yield return(TryCreate(ItemType.Boots, id, p => new Boots(p.ID)));
                }

                foreach (var id in TryLoad <int, string>("Data\\hats").Keys)
                {
                    yield return(TryCreate(ItemType.Hat, id, p => new Hat(p.ID)));
                }


                foreach (var id in TryLoad <int, string>("Data\\weapons").Keys)
                {
                    yield return(TryCreate(ItemType.Weapon, id, p => p.ID >= 32 && p.ID <= 34
                        ? (Item) new Slingshot(p.ID)
                        : new MeleeWeapon(p.ID)
                                           ));
                }

                foreach (var id in TryLoad <int, string>("Data\\Furniture").Keys)
                {
                    yield return(TryCreate(ItemType.Furniture, id, p => Furniture.GetFurnitureInstance(p.ID)));
                }

                foreach (var id in Game1.bigCraftablesInformation.Keys)
                {
                    yield return(TryCreate(ItemType.BigCraftable, id, p => new SObject(Vector2.Zero, p.ID)));
                }

                foreach (var id in Game1.objectInformation.Keys)
                {
                    var fields = Game1.objectInformation[id]?.Split('/');

                    if (id == 79)
                    {
                        foreach (var secretNoteId in TryLoad <int, string>("Data\\SecretNotes").Keys)
                        {
                            yield return(TryCreate(ItemType.Object, CustomIDOffset + secretNoteId, _ =>
                            {
                                var note = new SObject(79, 1);
                                note.name = $"{note.name} #{secretNoteId}";
                                return note;
                            }));
                        }
                    }

                    else if (id != 801 && fields?.Length >= 4 && fields[3] == "Ring")
                    {
                        yield return(TryCreate(ItemType.Ring, id, p => new Ring(p.ID)));
                    }

                    else
                    {
                        SObject item = null;
                        yield return(TryCreate(ItemType.Object, id, p =>
                        {
                            return item = p.ID == 812 // roe
                                ? new ColoredObject(p.ID, 1, Color.White)
                                : new SObject(p.ID, 1);
                        }));

                        if (item == null)
                        {
                            continue;
                        }

                        switch (item.Category)
                        {
                        case SObject.FruitsCategory:
                            yield return(TryCreate(ItemType.Object, CustomIDOffset * 2 + item.ParentSheetIndex, _ =>
                                                   new SObject(348, 1)
                            {
                                Name = $"{item.Name} Wine",
                                Price = item.Price * 3,
                                preserve = { SObject.PreserveType.Wine },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            yield return(TryCreate(ItemType.Object, CustomIDOffset * 3 + item.ParentSheetIndex, _ =>
                                                   new SObject(344, 1)
                            {
                                Name = $"{item.Name} Jelly",
                                Price = 50 + item.Price * 2,
                                preserve = { SObject.PreserveType.Jelly },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            break;

                        case SObject.VegetableCategory:
                            yield return(TryCreate(ItemType.Object, CustomIDOffset * 4 + item.ParentSheetIndex, _ =>
                                                   new SObject(350, 1)
                            {
                                Name = $"{item.Name} Juice",
                                Price = (int)(item.Price * 2.25d),
                                preserve = { SObject.PreserveType.Juice },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            yield return(TryCreate(ItemType.Object, CustomIDOffset * 5 + item.ParentSheetIndex, _ =>
                                                   new SObject(342, 1)
                            {
                                Name = $"Pickled {item.Name}",
                                Price = 50 + item.Price * 2,
                                preserve = { SObject.PreserveType.Pickle },
                                preservedParentSheetIndex = { item.ParentSheetIndex }
                            }));

                            break;

                        case SObject.flowersCategory:
                            yield return(TryCreate(ItemType.Object, CustomIDOffset * 5 + item.ParentSheetIndex, _ =>
                            {
                                var 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;
                            }));

                            break;

                        case SObject.sellAtFishShopCategory when item.ParentSheetIndex == 812:
                        {
                            GetRoeContextTagLookups(out var simpleTags,
                                                    out var complexTags);

                            foreach (var pair in Game1.objectInformation)
                            {
                                var input =
                                    TryCreate(ItemType.Object, pair.Key, p => new SObject(p.ID, 1))
                                    ?.Item as SObject;
                                var inputTags = input?.GetContextTags();
                                if (inputTags?.Any() != true)
                                {
                                    continue;
                                }

                                if (!inputTags.Any(tag => simpleTags.Contains(tag)) &&
                                    !complexTags.Any(set => set.All(tag => input.HasContextTag(tag))))
                                {
                                    continue;
                                }

                                SObject roe   = null;
                                var     color = GetRoeColor(input);
                                yield return(TryCreate(ItemType.Object, CustomIDOffset * 7 + item.ParentSheetIndex,
                                                       _ =>
                                    {
                                        roe = new ColoredObject(812, 1, color)
                                        {
                                            name = $"{input.Name} Roe",
                                            preserve = { Value = SObject.PreserveType.Roe },
                                            preservedParentSheetIndex = { Value = input.ParentSheetIndex }
                                        };
                                        roe.Price += input.Price / 2;
                                        return roe;
                                    }));

                                if (roe != null && pair.Key != 698)
                                {
                                    yield return(TryCreate(ItemType.Object,
                                                           CustomIDOffset * 7 + item.ParentSheetIndex, _ =>
                                                           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
                                        }));
                                }
                            }
                        }
                        break;
                        }
                    }
                }
            }

            return(GetAllRaw().Where(p => p != null));
        }
Пример #13
0
        /// <summary>
        /// Generate every item known to man, or at least those we're interested
        /// in using for categorization.
        /// </summary>
        /// <remarks>
        /// Substantially based on code from Pathoschild's LookupAnything mod.
        /// </remarks>
        /// <returns>A collection of all of the item entries.</returns>
        private IEnumerable <DiscoveredItem> DiscoverItems()
        {
            // get tools
            yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.axe,
                                            ToolFactory.getToolFromDescription(ToolFactory.axe, Tool.stone)));

            yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.hoe,
                                            ToolFactory.getToolFromDescription(ToolFactory.hoe, Tool.stone)));

            yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.pickAxe,
                                            ToolFactory.getToolFromDescription(ToolFactory.pickAxe, Tool.stone)));

            yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.wateringCan,
                                            ToolFactory.getToolFromDescription(ToolFactory.wateringCan, Tool.stone)));

            yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.fishingRod,
                                            ToolFactory.getToolFromDescription(ToolFactory.fishingRod, Tool.stone)));

            yield return
                (new DiscoveredItem(ItemType.Tool, CustomIDOffset,
                                    new MilkPail())); // these don't have any sort of ID, so we'll just assign some arbitrary ones

            yield return(new DiscoveredItem(ItemType.Tool, CustomIDOffset + 1, new Shears()));

            yield return(new DiscoveredItem(ItemType.Tool, CustomIDOffset + 2, new Pan()));

            // equipment
            foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\Boots").Keys)
            {
                yield return(new DiscoveredItem(ItemType.Boots, id, new Boots(id)));
            }
            foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\hats").Keys)
            {
                yield return(new DiscoveredItem(ItemType.Hat, id, new Hat(id)));
            }
            foreach (int id in Game1.objectInformation.Keys)
            {
                if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange)
                {
                    yield return(new DiscoveredItem(ItemType.Ring, id, new Ring(id)));
                }
            }

            // 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 DiscoveredItem(ItemType.Weapon, id, weapon));
            }

            // furniture

            /*foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Furniture").Keys)
             * {
             *  if (id == 1466 || id == 1468)
             *      yield return new DiscoveredItem(ItemType.Furniture, id, new TV(id, Vector2.Zero));
             *  else
             *      yield return new DiscoveredItem(ItemType.Furniture, id, new Furniture(id, Vector2.Zero));
             * }*/

            // craftables

            /*foreach (int id in Game1.bigCraftablesInformation.Keys)
             *  yield return new DiscoveredItem(ItemType.BigCraftable, id, new StardewObject(Vector2.Zero, id));*/

            // objects
            foreach (int id in Game1.objectInformation.Keys)
            {
                if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange)
                {
                    continue; // handled separated
                }
                StardewObject item = new StardewObject(id, 1);
                yield return(new DiscoveredItem(ItemType.Object, id, item));
            }
        }
Пример #14
0
        public IEnumerable <SearchableItem> GetAll()
        {
            IEnumerable <SearchableItem> GetAllRaw()
            {
                // 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()));

                // clothing
                foreach (int id in Game1.clothingInformation.Keys)
                {
                    yield return(this.TryCreate(ItemType.Clothing, id, () => new Clothing(id)));
                }

                // wallpapers
                for (int id = 0; id < 112; id++)
                {
                    yield return(this.TryCreate(ItemType.Wallpaper, id, () => new Wallpaper(id)
                    {
                        Category = SObject.furnitureCategory
                    }));
                }

                // flooring
                for (int id = 0; id < 40; id++)
                {
                    yield return(this.TryCreate(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(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)));
                    }
                }

                // 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(this.TryCreate(ItemType.Weapon, id, () => weapon));
                }

                // 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)));
                    }
                }

                // craftables
                foreach (int id in Game1.bigCraftablesInformation.Keys)
                {
                    yield return(this.TryCreate(ItemType.BigCraftable, id, () => new SObject(Vector2.Zero, 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(this.TryCreate(ItemType.Object, this.CustomIDOffset + id, () => note));
                }

                // 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
                    }
                    // spawn main item
                    SObject item = id == 812
                        ? new ColoredObject(id, 1, Color.White)
                        : new SObject(id, 1);
                    yield return(this.TryCreate(ItemType.Object, id, () => item));

                    // fruit products
                    if (item.Category == SObject.FruitsCategory)
                    {
                        // 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(this.TryCreate(ItemType.Object, this.CustomIDOffset * 2 + id, () => wine));

                        // jelly
                        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;
                        yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 3 + id, () => jelly));
                    }

                    // vegetable products
                    else if (item.Category == SObject.VegetableCategory)
                    {
                        // 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(this.TryCreate(ItemType.Object, this.CustomIDOffset * 4 + id, () => juice));

                        // pickled
                        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;
                        yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () => pickled));
                    }

                    // flower honey
                    else if (item.Category == SObject.flowersCategory)
                    {
                        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;
                        yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 6 + id, () => 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(this.TryCreate(ItemType.Object, this.CustomIDOffset * 6 + 1, () => roe));

                            // aged roe
                            if (pair.Key != 698) // aged sturgeon roe is caviar, which is a separate item
                            {
                                yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 6 + 1, () =>
                                                            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
                                }
                                                            ));
                            }
                        }
                    }
                }
            }

            return(GetAllRaw().Where(p => p != null));
        }