/// <summary>Get the data to display for this subject.</summary> /// <param name="metadata">Provides metadata that's not available from the game data directly.</param> /// <remarks>Tree growth algorithm reverse engineered from <see cref="StardewValley.TerrainFeatures.Tree.dayUpdate"/>.</remarks> public override IEnumerable <ICustomField> GetData(Metadata metadata) { Tree tree = this.Target; // get growth stage WildTreeGrowthStage stage = (WildTreeGrowthStage)Math.Min(tree.growthStage, (int)WildTreeGrowthStage.Tree); bool isFullyGrown = stage == WildTreeGrowthStage.Tree; yield return(isFullyGrown ? new GenericField("Growth stage", "fully grown") : new GenericField("Growth stage", $"{stage} ({(int)stage} of {(int)WildTreeGrowthStage.Tree})")); // get growth scheduler if (!isFullyGrown) { if (Game1.IsWinter && Game1.currentLocation.Name != Constant.LocationNames.Greenhouse) { yield return(new GenericField("Next growth", "can't grow in winter outside greenhouse")); } else if (stage == WildTreeGrowthStage.SmallTree && this.HasAdjacentTrees(this.Tile)) { yield return(new GenericField("Next growth", "can't grow because other trees are too close")); } else { yield return(new GenericField("Next growth", $"20% chance to grow into {stage + 1} tomorrow")); } } // get seed if (isFullyGrown) { yield return(new GenericField("Has seed", tree.hasSeed)); } }
/// <summary>Get whether the visible sprite intersects the specified coordinate. This can be an expensive test.</summary> /// <param name="tile">The tile to search.</param> /// <param name="position">The viewport-relative coordinates to search.</param> /// <param name="spriteArea">The approximate sprite area calculated by <see cref="GetWorldArea"/>.</param> /// <remarks>Reverse engineered from <see cref="Tree.draw"/>.</remarks> public override bool SpriteIntersectsPixel(Vector2 tile, Vector2 position, Rectangle spriteArea) { // get tree Tree tree = this.Value; WildTreeGrowthStage growth = (WildTreeGrowthStage)tree.growthStage.Value; // get sprite data Texture2D spriteSheet = this.Reflection.GetField <Lazy <Texture2D> >(tree, "texture").GetValue().Value; SpriteEffects spriteEffects = tree.flipped.Value ? SpriteEffects.FlipHorizontally : SpriteEffects.None; // check tree sprite if (this.SpriteIntersectsPixel(tile, position, spriteArea, spriteSheet, this.GetSpritesheetArea(), spriteEffects)) { return(true); } // check stump attached to bottom of grown tree if (growth == WildTreeGrowthStage.Tree) { Rectangle stumpSpriteArea = new Rectangle(spriteArea.Center.X - (Tree.stumpSourceRect.Width / 2 * Game1.pixelZoom), spriteArea.Y + spriteArea.Height - Tree.stumpSourceRect.Height * Game1.pixelZoom, Tree.stumpSourceRect.Width * Game1.pixelZoom, Tree.stumpSourceRect.Height * Game1.pixelZoom); if (stumpSpriteArea.Contains((int)position.X, (int)position.Y) && this.SpriteIntersectsPixel(tile, position, stumpSpriteArea, spriteSheet, Tree.stumpSourceRect, spriteEffects)) { return(true); } } return(false); }
/// <summary>Get the data to display for this subject.</summary> /// <remarks>Tree growth algorithm reverse engineered from <see cref="StardewValley.TerrainFeatures.Tree.dayUpdate"/>.</remarks> public override IEnumerable <ICustomField> GetData() { Tree tree = this.Target; TreeType treeType = (TreeType)tree.treeType.Value; GameLocation location = tree.currentLocation; // get growth stage WildTreeGrowthStage stage = (WildTreeGrowthStage)Math.Min(tree.growthStage.Value, (int)WildTreeGrowthStage.Tree); bool isFullyGrown = stage == WildTreeGrowthStage.Tree; yield return(new GenericField(I18n.Tree_Stage(), isFullyGrown ? I18n.Tree_Stage_Done() : I18n.Tree_Stage_Partial(stageName: I18n.For(stage), step: (int)stage, max: (int)WildTreeGrowthStage.Tree) )); // get growth schedule if (!isFullyGrown) { string label = I18n.Tree_NextGrowth(); if (location.GetSeasonForLocation() == "winter" && !location.SeedsIgnoreSeasonsHere() && !tree.fertilized.Value) { yield return(new GenericField(label, I18n.Tree_NextGrowth_Winter())); } else if (stage == WildTreeGrowthStage.SmallTree && this.HasAdjacentTrees(this.Tile)) { yield return(new GenericField(label, I18n.Tree_NextGrowth_AdjacentTrees())); } else { yield return(new GenericField(label, I18n.Tree_NextGrowth_Chance(stage: I18n.For(stage + 1), chance: this.GetNormalGrowthChance()))); } } // get fertilizer if (!isFullyGrown) { if (!tree.fertilized.Value) { yield return(new GenericField(I18n.Tree_IsFertilized(), this.Stringify(false))); } else { var fertilizer = new StardewValley.Object(805, 1); yield return(new ItemIconField(this.GameHelper, I18n.Tree_IsFertilized(), fertilizer, this.Codex)); } } // get seed if (isFullyGrown) { yield return(new GenericField(I18n.Tree_HasSeed(), this.Stringify(tree.hasSeed.Value))); } }
/// <summary>Get the data to display for this subject.</summary> /// <remarks>Tree growth algorithm reverse engineered from <see cref="StardewValley.TerrainFeatures.Tree.dayUpdate"/>.</remarks> public override IEnumerable <ICustomField> GetData() { Tree tree = this.Target; var location = tree.currentLocation; // get growth stage WildTreeGrowthStage stage = (WildTreeGrowthStage)Math.Min(tree.growthStage.Value, (int)WildTreeGrowthStage.Tree); bool isFullyGrown = stage == WildTreeGrowthStage.Tree; yield return(new GenericField(I18n.Tree_Stage(), isFullyGrown ? I18n.Tree_Stage_Done() : I18n.Tree_Stage_Partial(stageName: I18n.For(stage), step: (int)stage, max: (int)WildTreeGrowthStage.Tree) )); // get growth schedule if (!isFullyGrown) { string label = I18n.Tree_NextGrowth(); if (location.GetSeasonForLocation() == "winter" && !location.SeedsIgnoreSeasonsHere()) { yield return(new GenericField(label, I18n.Tree_NextGrowth_Winter())); } else if (stage == WildTreeGrowthStage.SmallTree && this.HasAdjacentTrees(this.Tile)) { yield return(new GenericField(label, I18n.Tree_NextGrowth_AdjacentTrees())); } else { yield return(new GenericField(label, I18n.Tree_NextGrowth_Chance(stage: I18n.For(stage + 1), chance: tree.fertilized.Value ? 100 : 20))); } } // get fertilizer if (!isFullyGrown) { yield return(new GenericField(I18n.Tree_IsFertilized(), this.Stringify(tree.fertilized.Value) + (tree.fertilized.Value ? $" ({I18n.Tree_IsFertilized_Effects()})" : ""))); } // get seed if (isFullyGrown) { yield return(new GenericField(I18n.Tree_HasSeed(), this.Stringify(tree.hasSeed.Value))); } }
/// <summary>Get the data to display for this subject.</summary> /// <param name="metadata">Provides metadata that's not available from the game data directly.</param> /// <remarks>Tree growth algorithm reverse engineered from <see cref="StardewValley.TerrainFeatures.Tree.dayUpdate"/>.</remarks> public override IEnumerable <ICustomField> GetData(Metadata metadata) { Tree tree = this.Target; // get growth stage WildTreeGrowthStage stage = (WildTreeGrowthStage)Math.Min(tree.growthStage.Value, (int)WildTreeGrowthStage.Tree); bool isFullyGrown = stage == WildTreeGrowthStage.Tree; yield return(new GenericField(this.GameHelper, L10n.Tree.Stage(), isFullyGrown ? L10n.Tree.StageDone() : L10n.Tree.StagePartial(stageName: L10n.For(stage), step: (int)stage, max: (int)WildTreeGrowthStage.Tree) )); // get growth schedule if (!isFullyGrown) { string label = L10n.Tree.NextGrowth(); if (Game1.IsWinter && !Game1.currentLocation.IsGreenhouse) { yield return(new GenericField(this.GameHelper, label, L10n.Tree.NextGrowthWinter())); } else if (stage == WildTreeGrowthStage.SmallTree && this.HasAdjacentTrees(this.Tile)) { yield return(new GenericField(this.GameHelper, label, L10n.Tree.NextGrowthAdjacentTrees())); } else { yield return(new GenericField(this.GameHelper, label, L10n.Tree.NextGrowthChance(stage: L10n.For(stage + 1), chance: tree.fertilized.Value ? 100 : 20))); } } // get fertilizer if (!isFullyGrown) { yield return(new GenericField(this.GameHelper, L10n.Tree.IsFertilized(), this.Stringify(tree.fertilized.Value) + (tree.fertilized.Value ? $" ({L10n.Tree.IsFertilizedEffects()})" : ""))); } // get seed if (isFullyGrown) { yield return(new GenericField(this.GameHelper, L10n.Tree.HasSeed(), this.Stringify(tree.hasSeed.Value))); } }
/// <summary>Get the data to display for this subject.</summary> /// <param name="metadata">Provides metadata that's not available from the game data directly.</param> /// <remarks>Tree growth algorithm reverse engineered from <see cref="StardewValley.TerrainFeatures.Tree.dayUpdate"/>.</remarks> public override IEnumerable <ICustomField> GetData(Metadata metadata) { Tree tree = this.Target; // get growth stage WildTreeGrowthStage stage = (WildTreeGrowthStage)Math.Min(tree.growthStage, (int)WildTreeGrowthStage.Tree); bool isFullyGrown = stage == WildTreeGrowthStage.Tree; yield return(new GenericField(this.Translate(L10n.Tree.Stage), isFullyGrown ? this.Translate(L10n.Tree.StageDone) : this.Translate(L10n.Tree.StagePartial, new { stageName = this.Translate(L10n.For(stage)), step = (int)stage, max = (int)WildTreeGrowthStage.Tree }) )); // get growth scheduler if (!isFullyGrown) { string label = this.Translate(L10n.Tree.NextGrowth); if (Game1.IsWinter && Game1.currentLocation.Name != Constant.LocationNames.Greenhouse) { yield return(new GenericField(label, this.Translate(L10n.Tree.NextGrowthWinter))); } else if (stage == WildTreeGrowthStage.SmallTree && this.HasAdjacentTrees(this.Tile)) { yield return(new GenericField(label, this.Translate(L10n.Tree.NextGrowthAdjacentTrees))); } else { yield return(new GenericField(label, this.Translate(L10n.Tree.NextGrowthRandom, new { stage = this.Translate(L10n.For(stage + 1)) }))); } } // get seed if (isFullyGrown) { yield return(new GenericField(this.Translate(L10n.Tree.HasSeed), this.Stringify(tree.hasSeed))); } }
/// <summary>Get a translation for an enum value.</summary> /// <param name="stage">The tree growth stage.</param> public static Translation For(WildTreeGrowthStage stage) { return(L10n.Helper.Get($"tree.stages.{stage}")); }
/********* ** Public methods *********/ /// <summary>Get a translation key for an enum value.</summary> /// <param name="stage">The tree growth stage.</param> public static string For(WildTreeGrowthStage stage) { return($"tree.stages.{stage}"); }
/********* ** Public methods *********/ /// <summary>Get a translation for an enum value.</summary> /// <param name="stage">The tree growth stage.</param> public static string For(WildTreeGrowthStage stage) { return(I18n.GetByKey($"tree.stages.{stage}")); }