Ejemplo n.º 1
0
        private ColoredObject getSerializable()
        {
            ColoredObject co = (ColoredObject)base.getOne();

            co.IsSpawnedObject = IsSpawnedObject;
            co.CanBeGrabbed    = CanBeGrabbed;
            return(co);
        }
Ejemplo n.º 2
0
 void ToTile_Reset()
 {
     if (toTile != null && toTile != fromTile)
     {
         ColoredObject.End(toTile.gameObject);
         toTile = null;
     }
 }
Ejemplo n.º 3
0
 public DarkSquareService(IServiceContainer wObj, VirtualWorld VW, int squareSize) : base(wObj, VW)
 {
     if (VW.render != null && squareSize != 0)
     {
         VW.render.ShaderProgramList.TryGetValue("solidProgram", out sp);
         rObj = new ColoredObject(VertexFactory.CreateSolidSquare(squareSize, 1, Color4.Black), sp.Id);
         VW.render.DrawServices.Add(nameService.name, this);
     }
 }
Ejemplo n.º 4
0
 public DarkEllipseService(IServiceContainer wObj, VirtualWorld VW, int circleRadiusX, int circleRadiusY, int np) : base(wObj, VW)
 {
     this.np = np;
     if (VW.render != null && circleRadiusX != 0)
     {
         VW.render.ShaderProgramList.TryGetValue("solidProgram", out sp);
         rObj = new ColoredObject(VertexFactory.CreateSolidEllipse(circleRadiusX, circleRadiusY, np, new float[] { 0, 0 }, 1, Color4.Black), sp.Id);
         VW.render.DrawServices.Add(nameService.name, this);
     }
 }
Ejemplo n.º 5
0
    private void OnCollisionEnter(Collision other)
    {
        ColoredObject coloredObject = other.gameObject.GetComponent <ColoredObject>();

        if (coloredObject)
        {
            coloredObject.HitWithBullet(gameObject.transform.position);
        }
        Destroy(gameObject);
    }
Ejemplo n.º 6
0
        void GhostTile_Create()
        {
            ghostTileInstance = fromTile.Duplicate();
            ghostTileInstance.gameObject.isStatic = false;
            ColoredObject.Start(ghostTileInstance.gameObject, ghostGradient);

            var cols = ghostTileInstance.GetComponentsInChildren <Collider>();

            foreach (var col in cols)
            {
                col.enabled = false;
            }
            GhostTile_Update();
        }
        public static ColoredCropWithDecay copyFrom(ColoredObject replacement)
        {
            ColoredCropWithDecay obj1 = new ColoredCropWithDecay((int)replacement.parentSheetIndex, replacement.Stack, (Color)replacement.color)
            {
                Quality                 = replacement.quality,
                Price                   = replacement.price,
                HasBeenInInventory      = replacement.HasBeenInInventory,
                HasBeenPickedUpByFarmer = replacement.hasBeenPickedUpByFarmer,
                SpecialVariable         = replacement.SpecialVariable
            };

            obj1.preserve.Set(replacement.preserve.Value);
            obj1.preservedParentSheetIndex.Set(replacement.preservedParentSheetIndex.Value);
            obj1.Name = replacement.Name;
            return(obj1);
        }
Ejemplo n.º 8
0
        void FromTile_Select(IsoTile tile)
        {
            if (tile != null && tile.coordinates._xyz.y > iBaseFloor && fromTile != tile)
            {
                toTile = fromTile = tile;
                exceptionList.Add(fromTile);
                GhostTile_Create();
                ColoredObject.Start(fromTile.gameObject, selectedGradient);
                fTileHeight = fromTile.GetBounds_SideOnly().size.y;
            }

            if (fromTile != null && lastMousePos != Input.mousePosition)
            {
                ToTile_Set();
            }
        }
        /// <summary>
        /// Create an output from a given output config.
        /// The name is not properly calculated on the creation, should call LoadOutputName for that.
        /// </summary>
        /// <param name="outputConfig">The output config</param>
        /// <param name="input">The input used</param>
        /// <param name="random">The random object that should be used if necessary</param>
        /// <returns>The created output</returns>
        public static Object CreateOutput(OutputConfig outputConfig, Object input, Random random)
        {
            Object output;

            if (outputConfig.OutputIndex == 93 || outputConfig.OutputIndex == 94)
            {
                output = new Torch(Vector2.Zero, outputConfig.OutputStack, outputConfig.OutputIndex);
            }
            else if (outputConfig.OutputColorConfig is ColoredObjectConfig coloredObjectConfig)
            {
                switch (coloredObjectConfig.Type)
                {
                case ColorType.ObjectColor when input is ColoredObject coloredObject:
                    output = new ColoredObject(outputConfig.OutputIndex, outputConfig.OutputStack, coloredObject.color.Value);
                    break;

                case ColorType.ObjectDyeColor when TailoringMenu.GetDyeColor(input) is Color color:
                    output = new ColoredObject(outputConfig.OutputIndex, outputConfig.OutputStack, color);

                    break;

                case ColorType.DefinedColor:
                default:
                    output = new ColoredObject(outputConfig.OutputIndex, outputConfig.OutputStack, new Color(coloredObjectConfig.Red, coloredObjectConfig.Green, coloredObjectConfig.Blue));
                    break;
                }
            }
            else
            {
                output = new Object(Vector2.Zero, outputConfig.OutputIndex, null, false, true, false, false);
            }

            if (outputConfig.InputPriceBased)
            {
                output.Price = (int)(outputConfig.OutputPriceIncrement + (input?.Price ?? 0) * outputConfig.OutputPriceMultiplier);
            }
            else
            {
                output.Price = (int)(outputConfig.OutputPriceIncrement + (output?.Price ?? 0) * outputConfig.OutputPriceMultiplier);
            }

            output.Quality = outputConfig.KeepInputQuality ? input?.Quality ?? 0 : outputConfig.OutputQuality;

            output.Stack = GetOutputStack(outputConfig, input, random);

            return(output);
        }
Ejemplo n.º 10
0
        void ToTile_Set()
        {
            var newTarget = TouchUtility.GetTile_ScreenPos(Cam, Input.mousePosition, exceptionList);

            newTarget = FindTopTile(newTarget);

            if (newTarget != toTile)
            {
                ToTile_Reset();
                toTile = newTarget;
                if (toTile != null && toTile != fromTile)
                {
                    ColoredObject.Start(toTile.gameObject, destinationGradient);
                }
            }

            GhostTile_Update();
        }
Ejemplo n.º 11
0
        void FromTile_UnSelectTile()
        {
            bool unSelect = false;

            switch (eventType)
            {
            case TouchUtility.EventType.Mouse:
                unSelect = Input.GetMouseButtonUp(0);
                break;

            case TouchUtility.EventType.Touch:
                unSelect = Input.touchCount == 0;
                break;
            }

            if (unSelect)
            {
                if (fromTile != null)
                {
                    ColoredObject.End(fromTile.gameObject);
                }

                if (fromTile != toTile)
                {
                    FromTile_Move();
                }

                if (ghostTileInstance != null)
                {
                    exceptionList.Remove(ghostTileInstance);
                    Destroy(ghostTileInstance.gameObject);
                    ghostTileInstance = null;
                }

                ToTile_Reset();
                exceptionList.Clear();
                toTile = fromTile = null;
            }
        }
Ejemplo n.º 12
0
        private Rectangle GetColoredItemSourceRectangle(ColoredObject @object)
        {
            var index = @object.ParentSheetIndex;

            if (index < 0)
            {
                return(new(322, 498, 12, 12));
            }

            if ([email protected])
            {
                index++;
            }
            if (@object.bigCraftable.Value)
            {
                return(SObject.getSourceRectForBigCraftable(index));
            }
            else
            {
                return(Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, index, 16, 16));
            }
        }
Ejemplo n.º 13
0
        private void HarvestIntoGrabber(HoeDirt dirt, Vector2 tile, GameLocation location, Chest grabberContents)
        {
            Crop   crop = dirt.crop;
            Object harvest;

            if (crop is null || crop.dead || crop.forageCrop)
            {
                return;
            }

            if (!Config.DoHarvestFlowers)
            {
                switch (crop.indexOfHarvest.Value)
                {
                case 421: return;     // sunflower

                case 593: return;     // summer spangle

                case 595: return;     // fairy rose

                case 591: return;     // tulip

                case 597: return;     // blue jazz

                case 376: return;     // poppy
                }
            }

            if (crop.currentPhase.Value >= crop.phaseDays.Count - 1 && (!crop.fullyGrown.Value || crop.dayOfCurrentPhase.Value <= 0))
            {
                int harvest_amount           = 1; // num1
                int quality                  = 0; // num2
                int fertilizer_quality_boost = 0; // num3
                if (crop.indexOfHarvest.Value == 0)
                {
                    return;
                }
                System.Random random = new System.Random((int)tile.X * 7 + (int)tile.Y * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame);
                switch ((dirt.fertilizer.Value))
                {
                case 368:
                    fertilizer_quality_boost = 1;
                    break;

                case 369:
                    fertilizer_quality_boost = 2;
                    break;
                }
                // num4
                double gold_chance = 0.2 * (Game1.player.FarmingLevel / 10.0) + 0.2 * fertilizer_quality_boost * ((Game1.player.FarmingLevel + 2.0) / 12.0) + 0.01;
                // num5
                double silver_chance = System.Math.Min(0.75, gold_chance * 2.0);
                if (random.NextDouble() < gold_chance)
                {
                    quality = 2;
                }
                else if (random.NextDouble() < silver_chance)
                {
                    quality = 1;
                }
                if ((crop.minHarvest.Value) > 1 || (crop.maxHarvest.Value) > 1)
                {
                    harvest_amount = random.Next(
                        crop.minHarvest.Value,
                        System.Math.Min(
                            crop.minHarvest.Value + 1,
                            crop.maxHarvest.Value + 1 + Game1.player.FarmingLevel / crop.maxHarvestIncreasePerFarmingLevel.Value));
                }
                if (crop.chanceForExtraCrops.Value > 0.0)
                {
                    while (random.NextDouble() < System.Math.Min(0.9, crop.chanceForExtraCrops.Value))
                    {
                        ++harvest_amount;
                    }
                }
                if (crop.harvestMethod.Value == 1)
                {
                    // harvest with scythe
                    for (int i = 0; i < harvest_amount; i++)
                    {
                        harvest = new Object(parentSheetIndex: crop.indexOfHarvest, initialStack: 1, quality: quality);
                        grabberContents.addItem(harvest);
                    }
                    if (Config.DoGainExperience)
                    {
                        float num6 = (float)(16.0 * Math.Log(0.018 * (double)Convert.ToInt32(Game1.objectInformation[(int)((NetFieldBase <int, NetInt>)crop.indexOfHarvest)].Split('/')[1]) + 1.0, Math.E));
                        Game1.player.gainExperience(0, (int)Math.Round((double)num6));
                    }
                    if (crop.regrowAfterHarvest.Value != -1)
                    {
                        crop.dayOfCurrentPhase.Value = crop.regrowAfterHarvest.Value;
                        crop.fullyGrown.Value        = true;
                    }
                    else
                    {
                        dirt.crop = null;
                    }
                }
                else
                {
                    if (!crop.programColored.Value)
                    {
                        // not a flower
                        harvest = new Object(crop.indexOfHarvest.Value, 1, false, -1, quality);
                        grabberContents.addItem(harvest);
                    }
                    else
                    {
                        // is a flower
                        harvest         = new ColoredObject(crop.indexOfHarvest.Value, 1, crop.tintColor.Value);
                        harvest.Quality = quality;
                        grabberContents.addItem(harvest);
                    }
                    if (random.NextDouble() < (double)Game1.player.LuckLevel / 1500.0 + Game1.dailyLuck / 1200.0 + 9.99999974737875E-05)
                    {
                        harvest_amount *= 2;
                    }
                    if ((int)((NetFieldBase <int, NetInt>)crop.indexOfHarvest) == 421) // sunflower
                    {
                        crop.indexOfHarvest.Value = 431;                               // sunflower seed
                        harvest_amount            = random.Next(1, 4);
                    }
                    for (int index = 0; index < harvest_amount - 1; ++index)
                    {
                        harvest = new Object(parentSheetIndex: crop.indexOfHarvest, initialStack: 1, quality: 0);
                        grabberContents.addItem(harvest);
                        // this may fail, we already used one slot for normal/silver/gold quality crop and now
                        // we are adding normal. We still do need to clear the crop, and parent won't call us again
                    }
                    if (Config.DoGainExperience)
                    {
                        float num8 = (float)(16.0 * Math.Log(0.018 * (double)Convert.ToInt32(Game1.objectInformation[(int)((NetFieldBase <int, NetInt>)crop.indexOfHarvest)].Split('/')[1]) + 1.0, Math.E));
                        Game1.player.gainExperience(0, (int)Math.Round((double)num8));
                    }
                    if (crop.regrowAfterHarvest.Value != -1)
                    {
                        crop.dayOfCurrentPhase.Value = crop.regrowAfterHarvest.Value;
                        crop.fullyGrown.Value        = true;
                    }
                    else
                    {
                        dirt.crop = null;
                    }
                }
            }
        }
Ejemplo n.º 14
0
 // Token: 0x06000308 RID: 776 RVA: 0x0003CDAC File Offset: 0x0003AFAC
 public bool harvest(int xTile, int yTile, HoeDirt soil, JunimoHarvester junimoHarvester = null)
 {
     if (this.dead)
     {
         return(junimoHarvester != null);
     }
     if (this.forageCrop)
     {
         Object o          = null;
         int    experience = 3;
         int    fertilizer = this.whichForageCrop;
         if (fertilizer == 1)
         {
             o = new Object(399, 1, false, -1, 0);
         }
         if (Game1.player.professions.Contains(16))
         {
             o.quality = 4;
         }
         else if (Game1.random.NextDouble() < (double)((float)Game1.player.ForagingLevel / 30f))
         {
             o.quality = 2;
         }
         else if (Game1.random.NextDouble() < (double)((float)Game1.player.ForagingLevel / 15f))
         {
             o.quality = 1;
         }
         if (junimoHarvester != null)
         {
             junimoHarvester.tryToAddItemToHut(o);
             return(true);
         }
         if (Game1.player.addItemToInventoryBool(o, false))
         {
             Vector2 initialTile = new Vector2((float)xTile, (float)yTile);
             Game1.player.animateOnce(279 + Game1.player.facingDirection);
             Game1.player.canMove = false;
             Game1.playSound("harvest");
             DelayedAction.playSoundAfterDelay("coin", 260);
             if (this.regrowAfterHarvest == -1)
             {
                 Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(17, new Vector2(initialTile.X * (float)Game1.tileSize, initialTile.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 125f, 0, -1, -1f, -1, 0));
                 Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(14, new Vector2(initialTile.X * (float)Game1.tileSize, initialTile.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 50f, 0, -1, -1f, -1, 0));
             }
             Game1.player.gainExperience(2, experience);
             return(true);
         }
         Game1.showRedMessage("Inventory Full");
     }
     else if (this.currentPhase >= this.phaseDays.Count - 1 && (!this.fullyGrown || this.dayOfCurrentPhase <= 0))
     {
         int numToHarvest           = 1;
         int cropQuality            = 0;
         int fertilizerQualityLevel = 0;
         if (this.indexOfHarvest == 0)
         {
             return(true);
         }
         Random r          = new Random(xTile * 7 + yTile * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame);
         int    fertilizer = soil.fertilizer;
         if (fertilizer != 368)
         {
             if (fertilizer == 369)
             {
                 fertilizerQualityLevel = 2;
             }
         }
         else
         {
             fertilizerQualityLevel = 1;
         }
         double chanceForGoldQuality   = 0.2 * (double)(Game1.player.FarmingLevel / 10) + 0.2 * (double)fertilizerQualityLevel * (double)((float)(Game1.player.FarmingLevel + 2) / 12f) + 0.01;
         double chanceForSilverQuality = Math.Min(0.75, chanceForGoldQuality * 2.0);
         if (r.NextDouble() < chanceForGoldQuality)
         {
             cropQuality = 2;
         }
         else if (r.NextDouble() < chanceForSilverQuality)
         {
             cropQuality = 1;
         }
         if (this.minHarvest > 1 || this.maxHarvest > 1)
         {
             numToHarvest = r.Next(this.minHarvest, Math.Min(this.minHarvest + 1, this.maxHarvest + 1 + Game1.player.FarmingLevel / this.maxHarvestIncreasePerFarmingLevel));
         }
         if (this.chanceForExtraCrops > 0.0)
         {
             while (r.NextDouble() < Math.Min(0.9, this.chanceForExtraCrops))
             {
                 numToHarvest++;
             }
         }
         if (this.harvestMethod == 1)
         {
             if (junimoHarvester == null)
             {
                 DelayedAction.playSoundAfterDelay("daggerswipe", 150);
             }
             if (junimoHarvester != null && Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
             {
                 Game1.playSound("harvest");
             }
             if (junimoHarvester != null && Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
             {
                 DelayedAction.playSoundAfterDelay("coin", 260);
             }
             for (int i = 0; i < numToHarvest; i++)
             {
                 if (junimoHarvester != null)
                 {
                     junimoHarvester.tryToAddItemToHut(new Object(this.indexOfHarvest, 1, false, -1, cropQuality));
                 }
                 else
                 {
                     Game1.createObjectDebris(this.indexOfHarvest, xTile, yTile, -1, cropQuality, 1f, null);
                 }
             }
             if (this.regrowAfterHarvest == -1)
             {
                 return(true);
             }
             this.dayOfCurrentPhase = this.regrowAfterHarvest;
             this.fullyGrown        = true;
         }
         else
         {
             if (junimoHarvester == null)
             {
                 Farmer arg_487_0 = Game1.player;
                 Object arg_487_1;
                 if (!this.programColored)
                 {
                     arg_487_1 = new Object(this.indexOfHarvest, 1, false, -1, cropQuality);
                 }
                 else
                 {
                     (arg_487_1 = new ColoredObject(this.indexOfHarvest, 1, this.tintColor)).quality = cropQuality;
                 }
                 if (!arg_487_0.addItemToInventoryBool(arg_487_1, false))
                 {
                     Game1.showRedMessage("Inventory Full");
                     return(false);
                 }
             }
             Vector2 initialTile2 = new Vector2((float)xTile, (float)yTile);
             if (junimoHarvester == null)
             {
                 Game1.player.animateOnce(279 + Game1.player.facingDirection);
                 Game1.player.canMove = false;
             }
             else
             {
                 Object arg_4FD_1;
                 if (!this.programColored)
                 {
                     arg_4FD_1 = new Object(this.indexOfHarvest, 1, false, -1, cropQuality);
                 }
                 else
                 {
                     (arg_4FD_1 = new ColoredObject(this.indexOfHarvest, 1, this.tintColor)).quality = cropQuality;
                 }
                 junimoHarvester.tryToAddItemToHut(arg_4FD_1);
             }
             if (r.NextDouble() < (double)((float)Game1.player.LuckLevel / 1500f) + Game1.dailyLuck / 1200.0 + 9.9999997473787516E-05)
             {
                 numToHarvest *= 2;
                 if (junimoHarvester == null || Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
                 {
                     Game1.playSound("dwoop");
                 }
             }
             else if (this.harvestMethod == 0)
             {
                 if (junimoHarvester == null || Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
                 {
                     Game1.playSound("harvest");
                 }
                 if (junimoHarvester == null || Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
                 {
                     DelayedAction.playSoundAfterDelay("coin", 260);
                 }
                 if (this.regrowAfterHarvest == -1 && (junimoHarvester == null || junimoHarvester.currentLocation.Equals(Game1.currentLocation)))
                 {
                     Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(17, new Vector2(initialTile2.X * (float)Game1.tileSize, initialTile2.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 125f, 0, -1, -1f, -1, 0));
                     Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(14, new Vector2(initialTile2.X * (float)Game1.tileSize, initialTile2.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 50f, 0, -1, -1f, -1, 0));
                 }
             }
             if (this.indexOfHarvest == 421)
             {
                 this.indexOfHarvest = 431;
                 numToHarvest        = r.Next(1, 4);
             }
             for (int j = 0; j < numToHarvest - 1; j++)
             {
                 if (junimoHarvester == null)
                 {
                     Game1.createObjectDebris(this.indexOfHarvest, xTile, yTile, -1, 0, 1f, null);
                 }
                 else
                 {
                     junimoHarvester.tryToAddItemToHut(new Object(this.indexOfHarvest, 1, false, -1, 0));
                 }
             }
             int price = Convert.ToInt32(Game1.objectInformation[this.indexOfHarvest].Split(new char[]
             {
                 '/'
             })[1]);
             float experience2 = (float)(16.0 * Math.Log(0.018 * (double)price + 1.0, 2.7182818284590451));
             if (junimoHarvester == null)
             {
                 Game1.player.gainExperience(0, (int)Math.Round((double)experience2));
             }
             if (this.regrowAfterHarvest == -1)
             {
                 return(true);
             }
             this.dayOfCurrentPhase = this.regrowAfterHarvest;
             this.fullyGrown        = true;
         }
     }
     return(false);
 }
Ejemplo n.º 15
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));
        }
Ejemplo n.º 16
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));
        }
Ejemplo n.º 17
0
        public SObject GetOutputObject(Item inputItem)
        {
            if (inputItem is SObject inputObject)
            {
                bool turnIntoGeneric = false;

                SObject outputObject;

                // Handle roe/aged roe
                if (inputObject is ColoredObject)
                {
                    outputObject = new ColoredObject(inputObject.ParentSheetIndex, 1, ((ColoredObject)inputObject).color.Value);
                }
                else
                {
                    outputObject = new StardewValley.Object(Vector2.Zero, inputObject.ParentSheetIndex, 1);

                    // If input is honey, copy honey type
                    if (outputObject.Name.Contains("Honey"))
                    {
                        outputObject.honeyType.Value = inputObject.honeyType.Value;

                        if (Config.TurnHoneyIntoGenericHoney)
                        {
                            turnIntoGeneric = true;
                        }
                    }
                }

                outputObject.Quality = SObject.lowQuality;

                switch (inputObject.preserve.Value)
                {
                case SObject.PreserveType.AgedRoe:
                case SObject.PreserveType.Roe:
                    if (Config.TurnRoeIntoGenericRoe)
                    {
                        turnIntoGeneric = true;
                    }
                    break;

                case SObject.PreserveType.Jelly:
                    if (Config.TurnJellyIntoGenericJelly)
                    {
                        turnIntoGeneric = true;
                    }
                    break;

                case SObject.PreserveType.Juice:
                    if (Config.TurnJuiceIntoGenericJuice)
                    {
                        turnIntoGeneric = true;
                    }
                    break;

                case SObject.PreserveType.Pickle:
                    if (Config.PicklesIntoGenericPickles)
                    {
                        turnIntoGeneric = true;
                    }
                    break;

                case SObject.PreserveType.Wine:
                    if (Config.TurnWineIntoGenericWine)
                    {
                        turnIntoGeneric = true;
                    }
                    break;

                default:
                    break;
                }

                if (!turnIntoGeneric)
                {
                    outputObject.Name  = inputObject.Name;
                    outputObject.Price = inputObject.Price;
                    // Preserve value has to be defined here, otherwise the output will be named "Weeds {preservetype}"
                    outputObject.preserve.Value = inputObject.preserve.Value;
                    // Handle preserves (Wine, Juice, Jelly, Pickle)
                    // preservedParentSheetIndex + preserve type define the object's DisplayName
                    outputObject.preservedParentSheetIndex.Value = inputObject.preservedParentSheetIndex.Value;
                }

                return(outputObject);
            }

            return(null);
        }
Ejemplo n.º 18
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));
        }
Ejemplo n.º 19
0
 public bool harvest(int xTile, int yTile, HoeDirt soil, JunimoHarvester junimoHarvester = null)
 {
     if (this.dead)
     {
         return(junimoHarvester != null);
     }
     if (this.forageCrop)
     {
         Object @object    = null;
         int    howMuch    = 3;
         int    fertilizer = this.whichForageCrop;
         if (fertilizer == 1)
         {
             @object = new Object(399, 1, false, -1, 0);
         }
         if (Game1.player.professions.Contains(16))
         {
             @object.quality = 4;
         }
         else if (Game1.random.NextDouble() < (double)((float)Game1.player.ForagingLevel / 30f))
         {
             @object.quality = 2;
         }
         else if (Game1.random.NextDouble() < (double)((float)Game1.player.ForagingLevel / 15f))
         {
             @object.quality = 1;
         }
         Game1.stats.ItemsForaged += (uint)@object.Stack;
         if (junimoHarvester != null)
         {
             junimoHarvester.tryToAddItemToHut(@object);
             return(true);
         }
         if (Game1.player.addItemToInventoryBool(@object, false))
         {
             Vector2 vector = new Vector2((float)xTile, (float)yTile);
             Game1.player.animateOnce(279 + Game1.player.facingDirection);
             Game1.player.canMove = false;
             Game1.playSound("harvest");
             DelayedAction.playSoundAfterDelay("coin", 260);
             if (this.regrowAfterHarvest == -1)
             {
                 Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(17, new Vector2(vector.X * (float)Game1.tileSize, vector.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 125f, 0, -1, -1f, -1, 0));
                 Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(14, new Vector2(vector.X * (float)Game1.tileSize, vector.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 50f, 0, -1, -1f, -1, 0));
             }
             Game1.player.gainExperience(2, howMuch);
             return(true);
         }
         Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Crop.cs.588", new object[0]));
     }
     else if (this.currentPhase >= this.phaseDays.Count - 1 && (!this.fullyGrown || this.dayOfCurrentPhase <= 0))
     {
         int num  = 1;
         int num2 = 0;
         int num3 = 0;
         if (this.indexOfHarvest == 0)
         {
             return(true);
         }
         Random random     = new Random(xTile * 7 + yTile * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame);
         int    fertilizer = soil.fertilizer;
         if (fertilizer != 368)
         {
             if (fertilizer == 369)
             {
                 num3 = 2;
             }
         }
         else
         {
             num3 = 1;
         }
         double num4 = 0.2 * ((double)Game1.player.FarmingLevel / 10.0) + 0.2 * (double)num3 * (((double)Game1.player.FarmingLevel + 2.0) / 12.0) + 0.01;
         double num5 = Math.Min(0.75, num4 * 2.0);
         if (random.NextDouble() < num4)
         {
             num2 = 2;
         }
         else if (random.NextDouble() < num5)
         {
             num2 = 1;
         }
         if (this.minHarvest > 1 || this.maxHarvest > 1)
         {
             num = random.Next(this.minHarvest, Math.Min(this.minHarvest + 1, this.maxHarvest + 1 + Game1.player.FarmingLevel / this.maxHarvestIncreasePerFarmingLevel));
         }
         if (this.chanceForExtraCrops > 0.0)
         {
             while (random.NextDouble() < Math.Min(0.9, this.chanceForExtraCrops))
             {
                 num++;
             }
         }
         if (this.harvestMethod == 1)
         {
             if (junimoHarvester == null)
             {
                 DelayedAction.playSoundAfterDelay("daggerswipe", 150);
             }
             if (junimoHarvester != null && Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
             {
                 Game1.playSound("harvest");
             }
             if (junimoHarvester != null && Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
             {
                 DelayedAction.playSoundAfterDelay("coin", 260);
             }
             for (int i = 0; i < num; i++)
             {
                 if (junimoHarvester != null)
                 {
                     junimoHarvester.tryToAddItemToHut(new Object(this.indexOfHarvest, 1, false, -1, num2));
                 }
                 else
                 {
                     Game1.createObjectDebris(this.indexOfHarvest, xTile, yTile, -1, num2, 1f, null);
                 }
             }
             if (this.regrowAfterHarvest == -1)
             {
                 return(true);
             }
             this.dayOfCurrentPhase = this.regrowAfterHarvest;
             this.fullyGrown        = true;
         }
         else
         {
             if (junimoHarvester == null)
             {
                 Farmer arg_4C0_0 = Game1.player;
                 Object arg_4C0_1;
                 if (!this.programColored)
                 {
                     arg_4C0_1 = new Object(this.indexOfHarvest, 1, false, -1, num2);
                 }
                 else
                 {
                     (arg_4C0_1 = new ColoredObject(this.indexOfHarvest, 1, this.tintColor)).quality = num2;
                 }
                 if (!arg_4C0_0.addItemToInventoryBool(arg_4C0_1, false))
                 {
                     Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Crop.cs.588", new object[0]));
                     return(false);
                 }
             }
             Vector2 vector2 = new Vector2((float)xTile, (float)yTile);
             if (junimoHarvester == null)
             {
                 Game1.player.animateOnce(279 + Game1.player.facingDirection);
                 Game1.player.canMove = false;
             }
             else
             {
                 Object arg_536_1;
                 if (!this.programColored)
                 {
                     arg_536_1 = new Object(this.indexOfHarvest, 1, false, -1, num2);
                 }
                 else
                 {
                     (arg_536_1 = new ColoredObject(this.indexOfHarvest, 1, this.tintColor)).quality = num2;
                 }
                 junimoHarvester.tryToAddItemToHut(arg_536_1);
             }
             if (random.NextDouble() < (double)((float)Game1.player.LuckLevel / 1500f) + Game1.dailyLuck / 1200.0 + 9.9999997473787516E-05)
             {
                 num *= 2;
                 if (junimoHarvester == null || Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
                 {
                     Game1.playSound("dwoop");
                 }
             }
             else if (this.harvestMethod == 0)
             {
                 if (junimoHarvester == null || Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
                 {
                     Game1.playSound("harvest");
                 }
                 if (junimoHarvester == null || Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), Game1.tileSize, junimoHarvester.currentLocation))
                 {
                     DelayedAction.playSoundAfterDelay("coin", 260);
                 }
                 if (this.regrowAfterHarvest == -1 && (junimoHarvester == null || junimoHarvester.currentLocation.Equals(Game1.currentLocation)))
                 {
                     Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(17, new Vector2(vector2.X * (float)Game1.tileSize, vector2.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 125f, 0, -1, -1f, -1, 0));
                     Game1.currentLocation.temporarySprites.Add(new TemporaryAnimatedSprite(14, new Vector2(vector2.X * (float)Game1.tileSize, vector2.Y * (float)Game1.tileSize), Color.White, 7, Game1.random.NextDouble() < 0.5, 50f, 0, -1, -1f, -1, 0));
                 }
             }
             if (this.indexOfHarvest == 421)
             {
                 this.indexOfHarvest = 431;
                 num = random.Next(1, 4);
             }
             for (int j = 0; j < num - 1; j++)
             {
                 if (junimoHarvester == null)
                 {
                     Game1.createObjectDebris(this.indexOfHarvest, xTile, yTile, -1, 0, 1f, null);
                 }
                 else
                 {
                     junimoHarvester.tryToAddItemToHut(new Object(this.indexOfHarvest, 1, false, -1, 0));
                 }
             }
             int num6 = Convert.ToInt32(Game1.objectInformation[this.indexOfHarvest].Split(new char[]
             {
                 '/'
             })[1]);
             float num7 = (float)(16.0 * Math.Log(0.018 * (double)num6 + 1.0, 2.7182818284590451));
             if (junimoHarvester == null)
             {
                 Game1.player.gainExperience(0, (int)Math.Round((double)num7));
             }
             if (this.regrowAfterHarvest == -1)
             {
                 return(true);
             }
             this.dayOfCurrentPhase = this.regrowAfterHarvest;
             this.fullyGrown        = true;
         }
     }
     return(false);
 }
Ejemplo n.º 20
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));
        }
Ejemplo n.º 21
0
        private Object GetHarvest(HoeDirt dirt, Vector2 tile, GameLocation location)
        {
            Crop   crop = dirt.crop;
            Object harvest;
            int    stack = 0;

            if (crop is null)
            {
                return(null);
            }

            if (!Config.DoHarvestFlowers)
            {
                switch (crop.indexOfHarvest.Value)
                {
                case 421: return(null);    // sunflower

                case 593: return(null);    // summer spangle

                case 595: return(null);    // fairy rose

                case 591: return(null);    // tulip

                case 597: return(null);    // blue jazz

                case 376: return(null);    // poppy
                }
            }

            if (crop != null && crop.currentPhase.Value >= crop.phaseDays.Count - 1 && (!crop.fullyGrown.Value || crop.dayOfCurrentPhase.Value <= 0))
            {
                int num1 = 1;
                int num2 = 0;
                int num3 = 0;
                if (crop.indexOfHarvest.Value == 0)
                {
                    return(null);
                }
                System.Random random = new System.Random((int)tile.X * 7 + (int)tile.Y * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame);
                switch ((dirt.fertilizer.Value))
                {
                case 368:
                    num3 = 1;
                    break;

                case 369:
                    num3 = 2;
                    break;
                }
                double num4 = 0.2 * (Game1.player.FarmingLevel / 10.0) + 0.2 * num3 * ((Game1.player.FarmingLevel + 2.0) / 12.0) + 0.01;
                double num5 = System.Math.Min(0.75, num4 * 2.0);
                if (random.NextDouble() < num4)
                {
                    num2 = 2;
                }
                else if (random.NextDouble() < num5)
                {
                    num2 = 1;
                }
                if ((crop.minHarvest.Value) > 1 || (crop.maxHarvest.Value) > 1)
                {
                    num1 = random.Next(crop.minHarvest.Value, System.Math.Min(crop.minHarvest.Value + 1, crop.maxHarvest.Value + 1 + Game1.player.FarmingLevel / crop.maxHarvestIncreasePerFarmingLevel.Value));
                }
                if (crop.chanceForExtraCrops.Value > 0.0)
                {
                    while (random.NextDouble() < System.Math.Min(0.9, crop.chanceForExtraCrops.Value))
                    {
                        ++num1;
                    }
                }
                if (crop.harvestMethod.Value == 1)
                {
                    for (int i = 0; i < num1; i++)
                    {
                        stack += 1;
                    }
                    if (crop.regrowAfterHarvest.Value != -1)
                    {
                        crop.dayOfCurrentPhase.Value = crop.regrowAfterHarvest.Value;
                        crop.fullyGrown.Value        = true;
                    }
                    else
                    {
                        dirt.crop = null;
                    }
                    return(new Object(crop.indexOfHarvest.Value, stack, false, -1, num2));
                }
                else
                {
                    if (!crop.programColored.Value)
                    {
                        harvest = new Object(crop.indexOfHarvest.Value, 1, false, -1, num2);
                    }
                    else
                    {
                        harvest = new ColoredObject(crop.indexOfHarvest.Value, 1, crop.tintColor.Value)
                        {
                            Quality = num2
                        };
                    }
                    if (crop.regrowAfterHarvest.Value != -1)
                    {
                        crop.dayOfCurrentPhase.Value = crop.regrowAfterHarvest.Value;
                        crop.fullyGrown.Value        = true;
                    }
                    else
                    {
                        dirt.crop = null;
                    }
                    return(harvest);
                }
            }
            return(null);
        }
Ejemplo n.º 22
0
        /// <summary>Get flavored variants of a base item (like Blueberry Wine for Blueberry), if any.</summary>
        /// <param name="item">A sample of the base item.</param>
        private IEnumerable <SearchableItem> GetFlavoredObjectVariants(SObject item)
        {
            int id = item.ParentSheetIndex;

            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 = { id }
                }));

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

                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 = { id }
                }));

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

                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 = { id }
                    };
                    honey.Price += item.Price * 2;
                    return honey;
                }));

                break;

            // roe and aged roe (derived from FishPond.GetFishProduce)
            case SObject.sellAtFishShopCategory when id == 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 + 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;
            }
        }