Пример #1
0
        public static string GetTraitLongDescr(CropTrait trait)
        {
            ITranslationHelper trans = ModEntry.GetHelper().Translation;

            switch (trait)
            {
            case CropTrait.PestResistanceNo:
                return(trans.Get("cult.msg_traitlongdesc_pestresno"));

            case CropTrait.PestResistanceI:
                return(trans.Get("cult.msg_traitlongdesc_pestresI"));

            case CropTrait.PestResistanceII:
                return(trans.Get("cult.msg_traitlongdesc_pestresII"));

            case CropTrait.QualityNo:
                return(trans.Get("cult.msg_traitlongdesc_qualityno"));

            case CropTrait.QualityI:
                return(trans.Get("cult.msg_traitlongdesc_qualityI"));

            case CropTrait.QualityII:
                return(trans.Get("cult.msg_traitlongdesc_qualityII"));

            case CropTrait.WaterNo:
                return(trans.Get("cult.msg_traitlongdesc_waterno"));

            case CropTrait.WaterI:
                return(trans.Get("cult.msg_traitlongdesc_waterI"));

            case CropTrait.WaterII:
                return(trans.Get("cult.msg_traitlongdesc_waterII"));

            case CropTrait.WaterIII:
                return(trans.Get("cult.msg_traitlongdesc_waterIII"));

            case CropTrait.SpeedNo:
                return(trans.Get("cult.msg_traitlongdesc_speedno"));

            case CropTrait.SpeedI:
                return(trans.Get("cult.msg_traitlongdesc_speedI"));

            case CropTrait.SpeedII:
                return(trans.Get("cult.msg_traitlongdesc_speedII"));

            case CropTrait.SpeedIII:
                return(trans.Get("cult.msg_traitlongdesc_speedIII"));

            default:
                return("ERROR gettraitlongdescr");
            }
        }
Пример #2
0
        public static void Load()
        {
            pests.Clear();

            List <Vector2> loadedInfestedCrops = ModEntry.GetHelper().Data.ReadSaveData <SaveData>(SaveData._InfestedCrops)?.InfestedCrops;

            if (loadedInfestedCrops != null)
            {
                pests.AddRange(loadedInfestedCrops.Select((vec) => TryInfestCrop(vec, Game1.getFarm().terrainFeatures[vec] is HoeDirt hd ? hd : null)).Where((arg) => arg != null));
            }
            ModEntry.GetMonitor().Log("Pests.Load() executed", LogLevel.Trace);
            ModEntry.GetMonitor().Log($"loaded {pests.Count} pests", LogLevel.Trace);
        }
Пример #3
0
            public PestFly(Vector2 pos) : base(pos)
            {
                this.cropPos          = AdjustPosition(pos * Game1.tileSize);
                this.position         = this.cropPos;
                this.startingPosition = this.cropPos;

                ModEntry.GetHelper().Reflection.GetField <bool>(this, "summerButterfly").SetValue(true);
                this.baseFrame = (128 + 4);
                this.sprite    = new AnimatedSprite(Critter.critterTexture, baseFrame, 16, 16)
                {
                    loop = false
                };
            }
Пример #4
0
        public static T LoadField <T>(string name)
        {
            SaveData data = ModEntry.GetHelper().Data.ReadSaveData <SaveData>(name);

            if (data == null)
            {
                return(default(T));
            }
            else
            {
                return(ModEntry.GetHelper().Reflection.GetField <T>(ModEntry.GetHelper().Data.ReadSaveData <SaveData>(name), name).GetValue());
            }
        }
Пример #5
0
 public static BluePrint GetComposterBlueprint()
 {
     return(new BluePrint("Shipping Bin")
     {
         displayName = ModEntry.GetHelper().Translation.Get("composter.name"),
         description = ModEntry.GetHelper().Translation.Get("composter.description"),
         maxOccupants = MaxOccupantsID,
         moneyRequired = 500,
         tilesWidth = 2,
         tilesHeight = 1
                       //sourceRectForMenuView = new Rectangle(0, 0, 64, 96),
                       //itemsRequired = this.Config.BuildMaterials
     });
 }
Пример #6
0
 void GameLoop_Saving(object sender, StardewModdingAPI.Events.SavingEventArgs e)
 {
     try
     {
         SaveData data = new SaveData();
         Pests.Save(data);
         Cultivation.Save(data);
         Composting.Save(data);
         ModEntry.GetHelper().Data.WriteSaveData <SaveData>(nameof(SaveData), data);
     }
     finally
     {
         Composting.ResetCompostingBins();
     }
 }
Пример #7
0
 public override void receiveLeftClick(int x, int y, bool playSound = true)
 {
     if (this.isWithinBounds(x, y))
     {
         Item clickedItem = leftClick(x, y, null, false);
         if (clickedItem != null)
         {
             Item remItem = OtherInventoryMenu.tryToAddItem(clickedItem);
             if (remItem != null && remItem.Stack == clickedItem.Stack)
             {
                 Game1.playSound("cancel");
                 Game1.showRedMessage(ModEntry.GetHelper().Translation.Get("composter.msg.error_inventory_full"));
             }
             //this.tryToAddItem(remItem);
             leftClick(x, y, remItem, false);
             CalcGreenBrown();
         }
     }
 }
Пример #8
0
            public void draw(SpriteBatch b)
            {
                double greenq = (green + brown) == 0 ? 0.5 : (double)green / (green + brown);
                double brownq = (green + brown) == 0 ? 0.5 : (double)brown / (brown + green);

                greenq = System.Math.Round(greenq, 2);
                brownq = System.Math.Round(brownq, 2);

                b.DrawString(Game1.smallFont, ModEntry.GetHelper().Translation.Get("composter.C", new { C = brown }), new Vector2(x, y + height / 2), Color.Brown);
                string greenstr = ModEntry.GetHelper().Translation.Get("composter.N", new { N = green });

                b.DrawString(Game1.smallFont, greenstr, new Vector2(x + width - Game1.smallFont.MeasureString(greenstr).X, y + height / 2), Color.Green);

                b.Draw(Game1.mouseCursors, new Rectangle(x, y, width, height / 2), new Rectangle(192 + 2, 1868, 240 - (192 + 3), 1882 - 1866), Color.White);
                //draw green bar
                b.Draw(Game1.mouseCursors, GetGreenBarArea(), new Rectangle(682 + 1, 2078, 690 - (682 + 1), 2086 - 2078), Color.White);
                //draw arrow
                b.Draw(Game1.mouseCursors, new Rectangle((int)(x + greenq * width - arrow_width / 2), (int)(y + height / 2 - (height / 2) * 0.3), (int)(arrow_width), height / 2), new Rectangle(120, 1234, 128 - 120, 1250 - 1234), Color.White);
                //b.DrawString(Game1.dialogueFont, greenq.ToString(), new Vector2((int)(x + greenq * width - arrow_width / 2), (int)(y + height / 2 - (height / 2) * 0.3)), Color.White);
            }
Пример #9
0
        public static void Save()
        {
            SaveData dat = new SaveData()
            {
                CropTraits              = CropTraits,
                CropSeeds               = CropSeeds,
                TempQualityFertilizer   = TempQualityFertilizer,
                TempQualityIIFertilizer = TempQualityIIFertilizer,
                TempWaterStop           = TempWaterStop,
                TempWaterOneDay         = TempWaterOneDay,
                TempWaterTwoDays        = TempWaterTwoDays
            };

            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._CropTraits, dat);
            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._CropSeeds, dat);
            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._TempQualityFertilizer, dat);
            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._TempQualityIIFertilizer, dat);
            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._TempWaterStop, dat);
            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._TempWaterOneDay, dat);
            ModEntry.GetHelper().Data.WriteSaveData <SaveData>(SaveData._TempWaterTwoDays, dat);
            ModEntry.GetMonitor().Log("Cultivation.Save() executed", LogLevel.Trace);
        }
Пример #10
0
            public override bool update(GameTime time, GameLocation environment)
            {
                Vector2 oldPosition = ModEntry.GetHelper().Reflection.GetField <Vector2>(this, "position").GetValue();

                bool result = base.update(time, environment);

                float   motionMultiplier = ModEntry.GetHelper().Reflection.GetField <float>(this, "motionMultiplier").GetValue();
                Vector2 motion           = ModEntry.GetHelper().Reflection.GetField <Vector2>(this, "motion").GetValue();

                Vector2 newPos = oldPosition + motion * motionMultiplier;

                if (Math.Abs((int)newPos.X - (int)cropPos.X) < Game1.tileSize / 3 && Math.Abs((int)newPos.Y - (int)cropPos.Y) < Game1.tileSize / 2)
                {
                    ModEntry.GetHelper().Reflection.GetField <Vector2>(this, "position").SetValue(newPos);
                }
                else
                {
                    ModEntry.GetHelper().Reflection.GetField <Vector2>(this, "position").SetValue(oldPosition);
                }

                //ModEntry.GetMonitor().Log("update: pestfly pos is" + pos +", and p is "+p);
                return(result);
            }
Пример #11
0
        public override void draw(SpriteBatch b)
        {
            base.draw(b);
            if ((int)ModEntry.GetHelper().Reflection.GetField <float>(this, "scale").GetValue() == 1)
            {
                SpriteText.drawString(b, "Traits for " + seeds.DisplayName + ":", xPositionOnScreen + 32, yPositionOnScreen + 32, 999999, width - 64, 999999, 0.75f, 0.865f, false, -1, "", -1 /*8 7*/);

                for (int i = 1; i <= drawTraits.Count; i++)
                {
                    SpriteText.drawString(b, Cultivation.GetTraitName(drawTraits[i - 1]) + ": " + Cultivation.GetTraitLongDescr(drawTraits[i - 1]), xPositionOnScreen + 32, i * 2 * (48 + 16) + yPositionOnScreen + 32, 999999, width - 64, 999999, 0.75f, 0.865f, false, -1, "", -1 /*8 7*/);
                    //SpriteText.drawString(b, Cultivation.GetTraitLongDescr(drawTraits[i - 1]), xPositionOnScreen + 32 + 32, (i+1) * 2 * 48 + yPositionOnScreen + 32, 999999, width - 64, 999999, 0.75f, 0.865f, false, -1, "", -1/*8 7*/);
                }

                if (drawTraits.Count == 0)
                {
                    SpriteText.drawString(b, ModEntry.GetHelper().Translation.Get("cult.msg_non"), xPositionOnScreen + 32, yPositionOnScreen + 32, 999999, width - 64, 999999, 0.75f, 0.865f, false, -1, "", -1 /*8 7*/);
                }
            }

            if (!Game1.options.hardwareCursor)
            {
                b.Draw(Game1.mouseCursors, new Vector2((float)Game1.getMouseX(), (float)Game1.getMouseY()), Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, 0, 16, 16), Color.White, 0f, Vector2.Zero, 4f + Game1.dialogueButtonScale / 150f, SpriteEffects.None, 1f);
            }
        }
Пример #12
0
 public CompostingBin(BluePrint bp, Vector2 tileLocation) : base(bp, tileLocation)
 {
     ModEntry.GetHelper().Reflection.GetField <TemporaryAnimatedSprite>(this, "shippingBinLid").SetValue(null);
     this.bluePrint    = bp;
     this.tileLocation = tileLocation;
 }
Пример #13
0
        public override void performHoverAction(int x, int y)
        {
            hoverApplyButton    = false;
            hoverActivateButton = false;
            hoverCancelButton   = false;

            if (!applyMode)
            {
                Item item = playerInventoryMenu.getItemAt(x, y);
                if (item == null)
                {
                    item = compostInventoryMenu.getItemAt(x, y);
                }

                if (state == State.fill && item != null)
                {
                    int   brown = Browns(item);
                    int   green = Greens(item);
                    float parts = (float)(green + brown) / Composting.one_part;

                    if (brown > 0 || green > 0)
                    {
                        hoverText = ModEntry.GetHelper().Translation.Get("composter.brown") + ": " + brown + " / " + ModEntry.GetHelper().Translation.Get("composter.green") + ": " + green + " (" + ModEntry.GetHelper().Translation.Get("composter.parts", new { parts }) + ")";
                    }
                    else
                    {
                        hoverText = "";
                    }
                }
                else if (state == State.fill && nutritionsComponent.GetBoundingBox().Contains(x, y))
                {
                    hoverText = ModEntry.GetHelper().Translation.Get("composter.greenbar");
                }
                else if (state == State.fill && nutritionsComponent.GoodDistribution() && activateButton.containsPoint(x, y))
                {
                    hoverText           = ModEntry.GetHelper().Translation.Get("composter.activate_button");
                    hoverActivateButton = true;
                }
                else if (state == State.ready && applyButton.containsPoint(x, y))
                {
                    hoverText        = ModEntry.GetHelper().Translation.Get("composter.apply_button");
                    hoverApplyButton = true;
                }
                else if (applyButton.containsPoint(x, y))
                {
                    hoverText        = ModEntry.GetHelper().Translation.Get("composter.apply_button_show");
                    hoverApplyButton = true;
                }
                else
                {
                    hoverText = "";
                }
            }
            else if (applyMode)
            {
                if (cancelButton.containsPoint(x, y))
                {
                    //hoverText = ModEntry.GetHelper().Translation.Get("composter.cancel_button");
                    hoverCancelButton = true;
                }
                else
                {
                    hoverText = "";
                }
            }

            base.performHoverAction(x, y);
        }
Пример #14
0
        public override void draw(SpriteBatch b)
        {
            Rectangle rectButton(Rectangle rect, bool hover)
            {
                int off = hover ? hover_button_inc / 2 : 0;

                return(new Rectangle(rect.X - off, rect.Y - off, rect.Width + off + off, rect.Height + off + off));
            }

            if (!applyMode)
            {
                base.draw(b);

                //IClickableMenu.drawTextureBox(b, xPositionOnScreen - 96, yPositionOnScreen - 16, compostInventoryMenu.width + 64, compostInventoryMenu.height*2 + space + nutrition_area_height + space + 64*2, Color.White);
                IClickableMenu.drawTextureBox(b, xPositionOnScreen, yPositionOnScreen, width, height, Color.White);

                compostInventoryMenu.draw(b);
                playerInventoryMenu.draw(b);
                if (state == State.fill)
                {
                    nutritionsComponent.draw(b);
                }

                b.Draw(Game1.mouseCursors, rectButton(applyButton.bounds, hoverApplyButton), CursorsOkButtonRect, Color.White);

                if (state == State.fill && nutritionsComponent.GoodDistribution())
                {
                    b.Draw(Game1.mouseCursors, rectButton(activateButton.bounds, hoverActivateButton), CursorsPlayButtonRect, Color.White);
                }

                //int needed = nutritionsComponent.ItemsNeeded();
                //needed = needed <= 0 ? 0 : needed;

                switch (state)
                {
                case State.fill:
                    SpriteText.drawStringWithScrollCenteredAt(b, ModEntry.GetHelper().Translation.Get("composter.fillheadline", new { parts = nutritionsComponent.Parts(), min_needed = Composting.config.composter_min_parts }), Game1.viewport.Width / 2, 64);
                    break;

                case State.ready:
                    SpriteText.drawStringWithScrollCenteredAt(b, ModEntry.GetHelper().Translation.Get("composter.readyheadline", new { amount = Composting.ComposterCompostLeft[BinPos] }), Game1.viewport.Width / 2, 64);
                    break;

                case State.active:
                    SpriteText.drawStringWithScrollCenteredAt(b, ModEntry.GetHelper().Translation.Get("composter.activeheadline", new { amount = Composting.ComposterDaysLeft[BinPos] }), Game1.viewport.Width / 2, 64);
                    break;
                }
            }
            else //applyMode
            {
                int color = 0; //1: red, 0: green

                foreach (Vector2 v in greenTiles)
                {
                    b.Draw(Game1.mouseCursors, Game1.GlobalToLocal(Game1.viewport, (new Vector2(v.X, v.Y)) * 64f), CursorsColoredTileRect(color), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.999f);
                }
                foreach (Vector2 vec in Composting.CompostAppliedDays.Keys)
                {
                    b.DrawString(Game1.smallFont, Composting.CompostAppliedDays[vec].ToString(), Game1.GlobalToLocal(Game1.viewport, new Vector2(vec.X * Game1.tileSize + Game1.tileSize / 2, vec.Y * Game1.tileSize + Game1.tileSize / 2)), Color.White);
                }

                b.Draw(Game1.mouseCursors, rectButton(cancelButton.bounds, hoverCancelButton), CursorsCancelButtonRect, Color.White);
                if (Composting.ComposterCompostLeft.ContainsKey(BinPos) && Composting.ComposterCompostLeft[BinPos] > 0)
                {
                    SpriteText.drawStringWithScrollCenteredAt(b, ModEntry.GetHelper().Translation.Get("composter.applyheadline", new { amount = Composting.ComposterCompostLeft[BinPos] }), Game1.viewport.Width / 2, 64);
                }
            }

            drawMouse(b);
            if (heldItem != null)
            {
                heldItem.drawInMenu(b, new Vector2(Game1.getOldMouseX() + 32, Game1.getOldMouseY() - 32), 1);
            }

            if (hoverText.Length > 0)
            {
                drawHoverText(b, hoverText, Game1.smallFont, 0, 0, -1, null, -1, null, null, 0, -1, -1, -1, -1, 1f, null);
            }
        }
Пример #15
0
 private void ShowError(string msg, object args = null)
 {
     Game1.showRedMessage(args == null ? ModEntry.GetHelper().Translation.Get(msg) : ModEntry.GetHelper().Translation.Get(msg, args));
 }
Пример #16
0
        public static void AddTrait(CropTrait trait, List <CropTrait> traits, int id)
        {
            ITranslationHelper trans = ModEntry.GetHelper().Translation;

            void add()
            {
                ModEntry.GetMonitor().Log($"Added {trait} to {CropSeedsDisplayName(id)}", LogLevel.Trace);
                Game1.showGlobalMessage(trans.Get("cult.msg_traitinc", new { traitdesc = GetTraitDescr(trait), seed = CropSeedsDisplayName(id), trait = GetTraitName(trait) }));
                Game1.playSound("achievement");
                traits.Add(trait);
                CropTraits[id] = traits;
            }

            bool alreadyContains() => traits.Contains(trait);

            CropTrait newTrait = GetNewRandomTrait(traits);

            if (traits.Contains(newTrait))
            {
                ModEntry.GetMonitor().Log("Bug: tried to find new trait with full list or returned wrong trait", LogLevel.Error);
                return;
            }

            if (alreadyContains())
            {
                switch (trait)
                {
                case CropTrait.PestResistanceI:
                    AddTrait(CropTrait.PestResistanceII, traits, id);
                    break;

                case CropTrait.WaterI:
                    AddTrait(CropTrait.WaterII, traits, id);
                    break;

                case CropTrait.QualityI:
                    AddTrait(CropTrait.QualityII, traits, id);
                    break;

                case CropTrait.SpeedI:
                    AddTrait(CropTrait.SpeedII, traits, id);
                    break;

                default:
                    AddTrait(newTrait, traits, id);
                    break;
                }
            }
            else
            {
                switch (trait)
                {
                case CropTrait.PestResistanceII:
                    if (traits.Contains(CropTrait.PestResistanceI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.PestResistanceI;
                        add();
                    }
                    break;

                case CropTrait.WaterII:
                    if (traits.Contains(CropTrait.WaterI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.WaterI;
                        add();
                    }

                    break;

                case CropTrait.QualityII:
                    if (traits.Contains(CropTrait.QualityI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.QualityI;
                        add();
                    }

                    break;

                case CropTrait.SpeedII:
                    if (traits.Contains(CropTrait.SpeedI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.SpeedI;
                        add();
                    }
                    break;

                default:
                    add();
                    break;
                }
            }
        }
Пример #17
0
        public static void AddTrait(CropTrait trait, List <CropTrait> traits, int id)
        {
            ITranslationHelper trans = ModEntry.GetHelper().Translation;

            string gettraitdescr()
            {
                switch (trait)
                {
                case CropTrait.PestResistanceI:
                case CropTrait.PestResistanceII:
                    return(trans.Get("cult.msg_traitdesc_pestres"));

                case CropTrait.QualityI:
                case CropTrait.QualityII:
                    return(trans.Get("cult.msg_traitdesc_quality"));

                case CropTrait.WaterI:
                case CropTrait.WaterII:
                    return(trans.Get("cult.msg_traitdesc_water"));

                case CropTrait.SpeedI:
                case CropTrait.SpeedII:
                    return(trans.Get("cult.msg_traitdesc_speed"));

                default:
                    return("ERROR gettraitdescr");
                }
            }

            string gettraitname()
            {
                switch (trait)
                {
                case CropTrait.PestResistanceI:
                    return(trans.Get("cult.msg_trait_pestresI"));

                case CropTrait.PestResistanceII:
                    return(trans.Get("cult.msg_trait_pestresII"));

                case CropTrait.QualityI:
                    return(trans.Get("cult.msg_trait_qualityI"));

                case CropTrait.QualityII:
                    return(trans.Get("cult.msg_trait_qualityII"));

                case CropTrait.WaterI:
                    return(trans.Get("cult.msg_trait_waterI"));

                case CropTrait.WaterII:
                    return(trans.Get("cult.msg_trait_waterII"));

                case CropTrait.SpeedI:
                    return(trans.Get("cult.msg_trait_speedI"));

                case CropTrait.SpeedII:
                    return(trans.Get("cult.msg_trait_speedII"));

                default:
                    return("ERROR gettraitname");
                }
            }

            void add()
            {
                ModEntry.GetMonitor().Log($"Added {trait} to {CropSeedsName(id)}", LogLevel.Trace);
                Game1.showGlobalMessage(trans.Get("cult.msg_traitinc", new { traitdesc = gettraitdescr(), seed = CropSeedsName(id), trait = gettraitname() }));
                traits.Add(trait);
                CropTraits[id] = traits;
            }

            bool alreadyContains() => traits.Contains(trait);

            CropTrait newTrait = GetNewRandomTrait(traits);

            if (traits.Contains(newTrait))
            {
                ModEntry.GetMonitor().Log("Bug: tried to find new trait with full list or returned wrong trait", LogLevel.Error);
                return;
            }

            if (alreadyContains())
            {
                switch (trait)
                {
                case CropTrait.PestResistanceI:
                    AddTrait(CropTrait.PestResistanceII, traits, id);
                    break;

                case CropTrait.WaterI:
                    AddTrait(CropTrait.WaterII, traits, id);
                    break;

                case CropTrait.QualityI:
                    AddTrait(CropTrait.QualityII, traits, id);
                    break;

                case CropTrait.SpeedI:
                    AddTrait(CropTrait.SpeedII, traits, id);
                    break;

                default:
                    AddTrait(newTrait, traits, id);
                    break;
                }
            }
            else
            {
                switch (trait)
                {
                case CropTrait.PestResistanceII:
                    if (traits.Contains(CropTrait.PestResistanceI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.PestResistanceI;
                        add();
                    }
                    break;

                case CropTrait.WaterII:
                    if (traits.Contains(CropTrait.WaterI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.WaterI;
                        add();
                    }

                    break;

                case CropTrait.QualityII:
                    if (traits.Contains(CropTrait.QualityI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.QualityI;
                        add();
                    }

                    break;

                case CropTrait.SpeedII:
                    if (traits.Contains(CropTrait.SpeedI))
                    {
                        add();
                    }
                    else
                    {
                        trait = CropTrait.SpeedI;
                        add();
                    }
                    break;

                default:
                    add();
                    break;
                }
            }
        }
Пример #18
0
 public static void AddBlueprint(CarpenterMenu menu)
 {
     ModEntry.GetHelper().Reflection.GetField <List <BluePrint> >(menu, "blueprints").GetValue().Add(GetComposterBlueprint());
 }
Пример #19
0
 public static SaveData AddToSaveData <T>(SaveData data, string name, T value)
 {
     ModEntry.GetHelper().Reflection.GetField <T>(data, name).SetValue(value);
     return(data);
 }