/// <summary>Harvest a bush if it's ready.</summary> /// <param name="bush">The bush to harvest.</param> /// <param name="location">The location being harvested.</param> /// <returns>Returns whether it was harvested.</returns> private bool TryHarvestBush(Bush bush, GameLocation location) { // harvest if ready if (bush?.tileSheetOffset.Value == 1) { bool isTeaBush = bush.size.Value == Bush.greenTeaBush; bool isBerryBush = !isTeaBush && bush.size.Value == Bush.mediumBush && !bush.townBush.Value; if ((isTeaBush && this.Config.HarvestCrops) || (isBerryBush && this.Config.HarvestForage)) { bush.performUseAction(bush.tilePosition.Value, location); return(true); } } return(false); }
/// <summary>Apply the tool to the given tile.</summary> /// <param name="tile">The tile to modify.</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tileFeature">The feature on the tile.</param> /// <param name="player">The current player.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="item">The item selected by the player (if any).</param> /// <param name="location">The current location.</param> public override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, Farmer player, Tool tool, Item item, GameLocation location) { // spawned forage if (this.Config.HarvestForage && tileObj?.IsSpawnedObject == true) { // pick up forage & cancel animation if (this.CheckTileAction(location, tile, player)) { IReflectedField <int> animationID = this.Reflection.GetField <int>(player.FarmerSprite, "currentSingleAnimation"); switch (animationID.GetValue()) { case FarmerSprite.harvestItemDown: case FarmerSprite.harvestItemLeft: case FarmerSprite.harvestItemRight: case FarmerSprite.harvestItemUp: player.completelyStopAnimatingOrDoingAction(); player.forceCanMove(); break; } } return(true); } // crop or spring onion (if an object like a scarecrow isn't placed on top of it) if (this.TryGetHoeDirt(tileFeature, tileObj, out HoeDirt dirt, out bool dirtCoveredByObj)) { if (dirtCoveredByObj || dirt.crop == null) { return(false); } if (this.Config.ClearDeadCrops && dirt.crop.dead.Value) { this.UseToolOnTile(this.FakePickaxe, tile, player, location); // clear dead crop return(true); } if (this.ShouldHarvest(dirt.crop)) { return(dirt.crop.harvestMethod.Value == Crop.sickleHarvest ? dirt.performToolAction(tool, 0, tile, location) : dirt.performUseAction(tile, location)); } return(true); } // machines if (this.Config.HarvestMachines && tileObj != null && tileObj.readyForHarvest.Value && tileObj.heldObject.Value != null) { tileObj.checkForAction(Game1.player); return(true); } // fruit tree if (this.Config.HarvestFruitTrees && tileFeature is FruitTree tree && tree.fruitsOnTree.Value > 0) { tree.performUseAction(tile, location); return(true); } // grass // (see Grass.performToolAction) if (this.Config.HarvestGrass && tileFeature is Grass) { location.terrainFeatures.Remove(tile); Random random = Game1.IsMultiplayer ? Game1.recentMultiplayerRandom : new Random((int)(Game1.uniqueIDForThisGame + tile.X * 1000.0 + tile.Y * 11.0)); if (random.NextDouble() < (tool.InitialParentTileIndex == MeleeWeapon.goldenScythe ? 0.75 : 0.5)) { if (Game1.getFarm().tryToAddHay(1) == 0) // returns number left { Game1.addHUDMessage(new HUDMessage("Hay", HUDMessage.achievement_type, true, Color.LightGoldenrodYellow, new SObject(178, 1))); } } return(true); } // weeds if (this.Config.ClearWeeds && this.IsWeed(tileObj)) { this.UseToolOnTile(tool, tile, player, location); // doesn't do anything to the weed, but sets up for the tool action (e.g. sets last user) tileObj.performToolAction(tool, location); // triggers weed drops, but doesn't remove weed location.removeObject(tile, false); return(true); } // bush Rectangle tileArea = this.GetAbsoluteTileArea(tile); if (this.Config.HarvestForage) { Bush bush = tileFeature as Bush ?? location.largeTerrainFeatures.FirstOrDefault(p => p.getBoundingBox(p.tilePosition.Value).Intersects(tileArea)) as Bush; if (bush?.tileSheetOffset.Value == 1 && (bush.size.Value == Bush.greenTeaBush || (bush.size.Value == Bush.mediumBush && !bush.townBush.Value))) { bush.performUseAction(bush.tilePosition.Value, location); return(true); } } return(false); }
internal static void ShakeBush(Bush bush, Vector2?tileLocation = null) { bush.performUseAction(tileLocation ?? Game1.player.getTileLocation() + new Vector2(0, -2), Game1.player.currentLocation); }