/// <summary>Simulates a day of growth on a fruit tree.</summary> private void SimulateFruitTreeDayUpdate(GameLocation l, FruitTree tree) { if (tree.daysUntilMature.Value > 28) { tree.daysUntilMature.Value = 28; } tree.daysUntilMature.Value--; int oldGrowthStage = tree.growthStage.Value; tree.growthStage.Value = tree.daysUntilMature.Value > 0 ? (tree.daysUntilMature.Value > 7 ? (tree.daysUntilMature.Value > 14 ? (tree.daysUntilMature.Value > 21 ? 0 : 1) : 2) : 3) : 4; //We only want to add a fruit to the tree if our simulated growth caused the tree to fully mature. If it is already mature, the game would have already added a fruit. if (oldGrowthStage != 4 && !tree.stump.Value && tree.growthStage.Value == 4 && (tree.struckByLightningCountdown.Value > 0 && !Game1.IsWinter || tree.IsInSeasonHere(l) || l.SeedsIgnoreSeasonsHere())) { tree.fruitsOnTree.Value = Math.Min(3, tree.fruitsOnTree.Value + 1); if (l.IsGreenhouse) { tree.GreenHouseTree = true; } } }
/// <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))); } }
private static bool Object_placementAction_Prefix(Object __instance, GameLocation location, int x, int y, Farmer who, ref bool __result) { if (!Config.EnableMod || !Config.PreventLatePlant || __instance.Category != -74) { return(true); } Vector2 placementTile = new Vector2((float)(x / 64), (float)(y / 64)); if (!location.terrainFeatures.ContainsKey(placementTile) || !(location.terrainFeatures[placementTile] is HoeDirt)) { return(true); } if ((new int[] { 495, 496, 497, 498, 770 }).Contains(__instance.ParentSheetIndex)) { return(true); } if (location.SeedsIgnoreSeasonsHere()) { return(true); } Crop c = new Crop(__instance.ParentSheetIndex, x, y); if (c == null) { return(true); } if (c.phaseDays.Count == 0 || EnoughDaysLeft(c)) { return(true); } SMonitor.Log($"Preventing planting {__instance.Name}"); __result = false; Game1.showRedMessage(string.Format(SHelper.Translation.Get("too-late-message"), __instance.Name)); return(false); }
private static bool Utility_tryToPlaceItem_Prefix(GameLocation location, Item item, ref bool __result) { if (!Config.EnableMod || !Config.PreventLatePlant || (new int[] { 495, 496, 497, 498, 770 }).Contains(item.ParentSheetIndex) || !(item is Object) || ((Object)item).Category != -74) { return(true); } if (location.SeedsIgnoreSeasonsHere()) { return(true); } Crop c = new Crop(item.ParentSheetIndex, 0, 0); if (c == null) { return(true); } if (c.phaseDays.Count == 0 || EnoughDaysLeft(c)) { return(true); } __result = false; Game1.showRedMessage(string.Format(SHelper.Translation.Get("too-late-message"), item.Name)); return(false); }
public void newDay(int state, int fertilizer, int xTile, int yTile, GameLocation environment) { if ((bool)environment.isOutdoors && ((bool)dead || (!environment.SeedsIgnoreSeasonsHere() && !seasonsToGrowIn.Contains(environment.GetSeasonForLocation())) || (!environment.SeedsIgnoreSeasonsHere() && (int)indexOfHarvest == 90))) { Kill(); return; } if (state == 1 || (int)indexOfHarvest == 771) { if (!fullyGrown) { dayOfCurrentPhase.Value = Math.Min((int)dayOfCurrentPhase + 1, (phaseDays.Count > 0) ? phaseDays[Math.Min(phaseDays.Count - 1, currentPhase)] : 0); } else { dayOfCurrentPhase.Value--; } if ((int)dayOfCurrentPhase >= ((phaseDays.Count > 0) ? phaseDays[Math.Min(phaseDays.Count - 1, currentPhase)] : 0) && (int)currentPhase < phaseDays.Count - 1) { currentPhase.Value++; dayOfCurrentPhase.Value = 0; } while ((int)currentPhase < phaseDays.Count - 1 && phaseDays.Count > 0 && phaseDays[currentPhase] <= 0) { currentPhase.Value++; } if ((int)rowInSpriteSheet == 23 && (int)phaseToShow == -1 && (int)currentPhase > 0) { phaseToShow.Value = Game1.random.Next(1, 7); } if (environment is Farm && (int)currentPhase == phaseDays.Count - 1 && ((int)indexOfHarvest == 276 || (int)indexOfHarvest == 190 || (int)indexOfHarvest == 254) && OneTimeRandom.GetDouble(Game1.uniqueIDForThisGame, Game1.stats.DaysPlayed, (ulong)xTile, (ulong)yTile) < 0.01) { for (int x2 = xTile - 1; x2 <= xTile + 1; x2++) { for (int y = yTile - 1; y <= yTile + 1; y++) { Vector2 v2 = new Vector2(x2, y); if (!environment.terrainFeatures.ContainsKey(v2) || !(environment.terrainFeatures[v2] is HoeDirt) || (environment.terrainFeatures[v2] as HoeDirt).crop == null || (environment.terrainFeatures[v2] as HoeDirt).crop.indexOfHarvest != indexOfHarvest) { return; } } } for (int x = xTile - 1; x <= xTile + 1; x++) { for (int y2 = yTile - 1; y2 <= yTile + 1; y2++) { Vector2 v3 = new Vector2(x, y2); (environment.terrainFeatures[v3] as HoeDirt).crop = null; } } (environment as Farm).resourceClumps.Add(new GiantCrop(indexOfHarvest, new Vector2(xTile - 1, yTile - 1))); } } if ((!fullyGrown || (int)dayOfCurrentPhase <= 0) && (int)currentPhase >= phaseDays.Count - 1 && (int)rowInSpriteSheet == 23) { Vector2 v = new Vector2(xTile, yTile); string season = Game1.currentSeason; switch ((int)whichForageCrop) { case 495: season = "spring"; break; case 496: season = "summer"; break; case 497: season = "fall"; break; case 498: season = "winter"; break; } if (environment.objects.ContainsKey(v)) { if (environment.objects[v] is IndoorPot) { (environment.objects[v] as IndoorPot).heldObject.Value = new Object(v, getRandomWildCropForSeason(season), 1); (environment.objects[v] as IndoorPot).hoeDirt.Value.crop = null; } else { environment.objects.Remove(v); } } if (!environment.objects.ContainsKey(v)) { environment.objects.Add(v, new Object(v, getRandomWildCropForSeason(season), 1) { IsSpawnedObject = true, CanBeGrabbed = true }); } if (environment.terrainFeatures.ContainsKey(v) && environment.terrainFeatures[v] != null && environment.terrainFeatures[v] is HoeDirt) { (environment.terrainFeatures[v] as HoeDirt).crop = null; } } updateDrawMath(new Vector2(xTile, yTile)); }
public override void dayUpdate(GameLocation environment, Vector2 tileLocation) { if (crop != null) { crop.newDay(state, fertilizer, (int)tileLocation.X, (int)tileLocation.Y, environment); if ((bool)environment.isOutdoors && Game1.GetSeasonForLocation(environment).Equals("winter") && crop != null && !crop.isWildSeedCrop() && (int)crop.indexOfHarvest != 771 && !environment.IsGreenhouse && !environment.SeedsIgnoreSeasonsHere()) { destroyCrop(tileLocation, showAnimation: false, environment); } } if ((!hasPaddyCrop() || !paddyWaterCheck(environment, tileLocation)) && ((int)fertilizer != 370 || !(Game1.random.NextDouble() < 0.33)) && ((int)fertilizer != 371 || !(Game1.random.NextDouble() < 0.66)) && (int)fertilizer != 920) { state.Value = 0; } if (environment.IsGreenhouse) { isGreenhouseDirt.Value = true; c.Value = Color.White; } }
public override void dayUpdate(GameLocation environment, Vector2 tileLocation) { if ((float)health <= -99f) { destroy = true; } if ((int)struckByLightningCountdown > 0) { struckByLightningCountdown.Value--; if ((int)struckByLightningCountdown <= 0) { fruitsOnTree.Value = 0; } } bool foundSomething = IsGrowthBlocked(tileLocation, environment); if (!foundSomething || (int)daysUntilMature <= 0) { if ((int)daysUntilMature > 28) { daysUntilMature.Value = 28; } daysUntilMature.Value--; if ((int)daysUntilMature <= 0) { growthStage.Value = 4; } else if ((int)daysUntilMature <= 7) { growthStage.Value = 3; } else if ((int)daysUntilMature <= 14) { growthStage.Value = 2; } else if ((int)daysUntilMature <= 21) { growthStage.Value = 1; } else { growthStage.Value = 0; } } else if (foundSomething && growthStage.Value != 4) { Game1.multiplayer.broadcastGlobalMessage("Strings\\UI:FruitTree_Warning", true, Game1.objectInformation[indexOfFruit].Split('/')[4]); } if (!stump && (int)growthStage == 4 && (((int)struckByLightningCountdown > 0 && !Game1.IsWinter) || IsInSeasonHere(environment) || environment.SeedsIgnoreSeasonsHere())) { fruitsOnTree.Value = Math.Min(3, (int)fruitsOnTree + 1); if (environment.IsGreenhouse) { greenHouseTree.Value = true; } } if ((bool)stump) { fruitsOnTree.Value = 0; } }
public override bool performUseAction(Vector2 tileLocation, GameLocation location) { if (maxShake == 0f && !stump && (int)growthStage >= 3 && (!Game1.GetSeasonForLocation(location).Equals("winter") || location.SeedsIgnoreSeasonsHere())) { location.playSound("leafrustle"); } shake(tileLocation, doEvenIfStillShaking: false, location); return(true); }