public static bool ScytheForage(StardewValley.Object o, Tool t, GameLocation loc) { if (o.IsSpawnedObject && !o.questItem.Value && o.isForage(loc) && CanHarvestObject(o, HARVEST_SCYTHING)) { var who = t.getLastFarmerToUse(); var vector = o.TileLocation; // For objects stored in GameLocation.Objects, the TileLocation is not always set. // So determine its location by looping trough all such objects. #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator if (vector.X == 0 && vector.Y == 0) { #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator foreach (System.Collections.Generic.KeyValuePair <Vector2, StardewValley.Object> pair in loc.Objects.Pairs) { if (pair.Value.Equals(o)) { vector = pair.Key; break; } } } Random random = new Random((int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed + (int)vector.X + (int)vector.Y * 777); if (who.professions.Contains(16)) { o.Quality = 4; } else if (random.NextDouble() < (double)((float)who.ForagingLevel / 30)) { o.Quality = 2; } else if (random.NextDouble() < (double)((float)who.ForagingLevel / 15)) { o.Quality = 1; } vector *= 64.0f; who.gainExperience(2, 7); Game1.createItemDebris(o.getOne(), vector, -1, null, -1); Game1.stats.ItemsForaged += 1; if (who.professions.Contains(13) && random.NextDouble() < 0.2) { Game1.createItemDebris(o.getOne(), vector, -1, null, -1); who.gainExperience(2, 7); } return(true); } else { return(false); } }
private SObject attach(SObject newSeed) { Game1.playSound("seeds"); SObject seedReturn = null; if (newSeed.Stack == 1) { Game1.player.removeItemFromInventory(newSeed); newSeed.NetFields.Parent = null; } else { --newSeed.Stack; seedReturn = newSeed; newSeed = (SObject)newSeed.getOne(); } if (Base.Stack == 1) { seed = newSeed; return(seedReturn); } else { SObject fusion = GetNew(newSeed); --Base.Stack; if (seedReturn != null) { Game1.player.addItemToInventory(seedReturn); } return(fusion); } }
public void PopExtraHeldMushrooms(bool giveNothing) { Log.D($"PopExtraHeldMushrooms at {Game1.currentLocation?.Name} {TileLocation.ToString()}", ModEntry.Instance.Config.DebugMode); // Incorporate Gatherer's skill effects for bonus production var popQuantity = heldObject.Value.Stack; if (Game1.player.professions.Contains(Farmer.gatherer) && new Random().Next(5) == 0) { popQuantity += 1; } var popQuality = Game1.player.professions.Contains(Farmer.botanist) ? 4 : SourceMushroomQuality; var popObject = new Object(SourceMushroomIndex, 1, false, -1, popQuality); // Create mushroom item drops in the world from the machine if (!giveNothing) { for (var i = 0; i < popQuantity; ++i) { Game1.createItemDebris(popObject.getOne(), new Vector2(TileLocation.X * 64 + 32, TileLocation.Y * 64 + 32), -1); } } // Clear the extra mushroom data heldObject.Value = null; }
public ITrackedStack GetOutput() { SObject machine = this.Machine; SObject heldObject = machine.heldObject.Value; return(new TrackedItem(heldObject.getOne(), item => { CustomCloner cloner = ClonerController.GetCloner(machine.Name); int?machineMinutesUntilReady = null; if (cloner.CloningDataId.ContainsKey(item.ParentSheetIndex)) { machineMinutesUntilReady = cloner.CloningDataId[item.ParentSheetIndex]; } else if (cloner.CloningDataId.ContainsKey(item.Category)) { machineMinutesUntilReady = cloner.CloningDataId[item.Category]; } if (machineMinutesUntilReady.HasValue) { machine.heldObject.Value = heldObject; machine.MinutesUntilReady = machineMinutesUntilReady.Value; machine.initializeLightSource(machine.TileLocation, false); } else { machine.heldObject.Value = (SObject)null; machine.MinutesUntilReady = -1; } machine.readyForHarvest.Value = false; })); }
/// <summary> /// Instantiates any mushroom objects currently attached to /// the machine when the farm is loaded. /// </summary> private void loadHeldObject(int index, int quality, int quantity, int days, bool produceExtra) { if (index >= 0 && quality >= 0 && quantity >= 0) { Item obj = new StardewValley.Object(index, 1) { Quality = quality }; if (Data.MushroomGrowingRates.TryGetValue(index, out float rate)) { putObject(obj.getOne(), rate); Quantity = quantity; daysToMature.Value = days; ProduceExtra = produceExtra; } else { Log.E("Failed to reload held object: See TRACE"); } Data.MushroomQuantityLimits.TryGetValue( index, out int max); Log.T("\nLoad: " + index + " at(" + TileLocation.X + " " + TileLocation.Y + ") val(" + quality + ") qty (" + quantity + "/" + max + ") age(" + daysToMature + "/" + defaultDaysToMature + " [+" + agingRate + "])"); } }
public dynamic getReplacement() { Chest r = new Chest(true); r.items.Add(sObject.getOne()); r.TileLocation = sObject.TileLocation; return(r); }
/// <summary>Get the output item.</summary> public override ITrackedStack GetOutput() { Cask cask = this.Machine; SObject heldObject = cask.heldObject.Value; return(new TrackedItem(heldObject.getOne(), this.Reset)); }
public static Item GetNew(StardewValley.Object obj) { SaveIndex.ValidateIndex(); var newFrame = new Furniture(SaveIndex.Index, Vector2.Zero); newFrame.netName.Value = "Plato:IsComicFrameObject=true|ComicId=216384"; newFrame.heldObject.Value = (StardewValley.Object)obj?.getOne(); return(newFrame); }
public static Object MoveItemToFarmer(Object itemToMove, Chest sourceChest, SFarmer target, int amount) { var temporaryItem = (Object)itemToMove.getOne(); temporaryItem.Stack = amount; var freeIndex = target.items.IndexOf(null); target.items[freeIndex] = temporaryItem; ItemHelper.RemoveItemFromChest(itemToMove, sourceChest, amount); return(temporaryItem); }
public bool hitWithHoe(int xTile, int yTile, GameLocation location, HoeDirt dirt) { if ((bool)forageCrop && (int)whichForageCrop == 2) { dirt.state.Value = (Game1.IsRainingHere(location) ? 1 : 0); Object harvestedItem = new Object(829, 1); Game1.multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(12, new Vector2(xTile * 64, yTile * 64), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); location.playSound("dirtyHit"); Game1.createItemDebris(harvestedItem.getOne(), new Vector2(xTile * 64 + 32, yTile * 64 + 32), -1); return(true); } return(false); }
/// <summary>Get the output item.</summary> public override ITrackedStack GetOutput() { Cask cask = this.Machine; SObject heldObject = this.Machine.heldObject.Value; return(new TrackedItem(heldObject.getOne(), item => { cask.heldObject.Value = null; cask.MinutesUntilReady = 0; cask.readyForHarvest.Value = false; cask.agingRate.Value = 0; cask.daysToMature.Value = 0; })); }
/// <summary> /// Ejects a duplicate of the originally-inserted mushroom if the machine /// has held it overnight, otherwise ejects the original mushroom and resets to empty. /// </summary> /// <param name="remove"> /// Whether or not to nullify the held mushroom, ejecting the originally-inserted /// mushroom and leaving the machine empty. /// </param> private void popObject(bool remove) { Data.MushroomQuantityLimits.TryGetValue( heldObject.Value.ParentSheetIndex, out int max); Log.T( "\nPop: " + heldObject.Value.DisplayName + " at(" + TileLocation.X + " " + TileLocation.Y + ") val(" + Quality + ") qty (" + Quantity + "/" + max + ") age(" + daysToMature + "/" + defaultDaysToMature + " [+" + agingRate + "])"); // Incorporate Gatherer's skill effects for extra production. int extra = 0; if (ProduceExtra && Game1.player.professions.Contains(Farmer.gatherer) && new Random().Next(5) == 0) { extra = 1; } // Extract held object. Game1.playSound("coin"); Game1.createMultipleObjectDebris(heldObject.Value.ParentSheetIndex, (int)TileLocation.X, (int)TileLocation.Y, Quantity + extra, Game1.player.UniqueMultiplayerID); // Reset the harvest. StardewValley.Object obj = heldObject.Value; if (remove) { heldObject.Value = null; minutesUntilReady.Value = -1; Quantity = 0; } else { putObject(obj.getOne(), Data.MushroomGrowingRates[obj.ParentSheetIndex]); minutesUntilReady.Value = 999999; Quantity = 1; } ProduceExtra = false; readyForHarvest.Value = false; daysToMature.Value = 0; }
public Item TryExtractItem(ContainerNode input, NetObjectList <Item> itemList, int index, int flux) { //Exception for multiple thread collisions Item source = itemList[index]; Item tosend = null; if (source is SObject) { SObject obj = (SObject)source; SObject tosendObject = (SObject)tosend; if (input.CanRecieveItem(source) && !IsEmpty()) { if (obj.Stack <= flux) { tosendObject = obj; itemList.RemoveAt(index); } else { obj.stack.Value -= flux; tosendObject = (SObject)obj.getOne(); tosendObject.stack.Value = flux; } Chest.clearNulls(); return(tosendObject); } } else if (source is Tool) { Tool tool = (Tool)source; Tool tosendTool = (Tool)tosend; if (input.CanRecieveItem(tool)) { tosendTool = tool; itemList.RemoveAt(index); } Chest.clearNulls(); return(tosendTool); } return(null); }
public override void receiveLeftClick(int x, int y, bool playSound = true) { base.receiveLeftClick(x, y, playSound); foreach (Request r in Requests.RequestList) { if (r.itemIndex == Util.CompletedRequestIndex) { string name = Game1.objectInformation[r.itemIndex].Split('/')[0]; foreach (ClickableTextureComponent component in textures) { if (component.name == name && Game1.player.Money >= r.totalPrice && component.containsPoint(x, y)) { SObject tempObject = new SObject(r.itemIndex, 1); for (int i = 0; i < r.itemCount; i++) { Item oneTempObject = tempObject.getOne(); Game1.player.addItemToInventory(oneTempObject); } Game1.player.Money -= r.totalPrice; Game1.activeClickableMenu = null; break; } else if (Game1.player.Money < r.totalPrice) { Game1.activeClickableMenu = (IClickableMenu)new DialogueBox("You do not have enough money to claim this item"); break; } else break; } } } Util.TryToRemoveRequests(); if (!RequestItemButton.visible || !RequestItemButton.containsPoint(x, y)) return; else Game1.activeClickableMenu = (IClickableMenu)new ItemSelectionMenu("Select It4m", Monitor); }
public override bool performObjectDropInAction(StardewValley.Object dropIn, bool probe, StardewValley.Farmer who) { if ((this.Decoration_type == 11 || this.Decoration_type == 5) && this.heldObject == null && !dropIn.bigCraftable && (!(dropIn is ModularDecoration) || ((dropIn as ModularDecoration).getTilesWide() == 1 && (dropIn as ModularDecoration).getTilesHigh() == 1))) { this.heldObject = (StardewValley.Object)dropIn.getOne(); this.heldObject.tileLocation = this.tileLocation; this.heldObject.boundingBox.X = this.boundingBox.X; this.heldObject.boundingBox.Y = this.boundingBox.Y; // Log.AsyncO(getDefaultBoundingBoxForType((dropIn as Decoration).Decoration_type)); this.heldObject.performDropDownAction(who); if (!probe) { Game1.playSound("woodyStep"); // Log.AsyncC("HUH?"); if (who != null) { who.reduceActiveItemByOne(); } } return(true); } return(false); }
private SObject attach(SObject seed) { Game1.playSound("seeds"); SObject seedReturn = null; if (seed.Stack == 1) { Game1.player.removeItemFromInventory(seed); seed.NetFields.Parent = null; } else { --seed.Stack; seedReturn = seed; seed = (SObject)seed.getOne(); } if (Stack == 1) { heldObject.Value = seed; appearsFull = true; return(seedReturn); } else { FlowerBomb fusion = (FlowerBomb)getOne(); --Stack; fusion.heldObject.Value = seed; fusion.appearsFull = true; if (seedReturn != null) { Game1.player.addItemToInventory(seedReturn); } return(fusion); } }
/// <summary> /// Instantiates any mushroom objects currently attached to /// the machine when the farm is loaded. /// </summary> private void loadHeldObject(int index, int quality, int quantity, int days, bool produceExtra) { if (index < 0 || quality < 0 || quantity < 0) { return; } Item obj = new StardewValley.Object(index, 1) { Quality = quality }; if (Const.MushroomGrowingRates.TryGetValue(index, out var rate)) { putObject(obj.getOne(), rate); Quantity = quantity; daysToMature.Value = days; ProduceExtra = produceExtra; } else { Log.E("Failed to reload held object: See TRACE"); } }
public override bool performToolAction(Tool t, GameLocation location) { var Game1_multiplayer = Mod.instance.Helper.Reflection.GetField <Multiplayer>(typeof(Game1), "multiplayer").GetValue(); if (this.heldObject.Value != null && t is not(null or MeleeWeapon) && t.isHeavyHitter()) { StardewValley.Object value = this.heldObject.Value; this.heldObject.Value.performRemoveAction(this.tileLocation, location); this.heldObject.Value = null; Game1.createItemDebris(value.getOne(), this.TileLocation * 64f, -1); location.playSound("axchop"); return(false); } if ((bool)this.isGate && t is Axe or Pickaxe) { location.playSound("axchop"); Game1.createObjectDebris(325, (int)this.tileLocation.X, (int)this.tileLocation.Y, Game1.player.UniqueMultiplayerID, Game1.player.currentLocation); location.objects.Remove(this.tileLocation); Game1.createRadialDebris(location, 12, (int)this.tileLocation.X, (int)this.tileLocation.Y, 6, resource: false); Game1_multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(12, new Vector2(this.tileLocation.X * 64f, this.tileLocation.Y * 64f), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); } if (t == null || (t is Pickaxe && this.Data.BreakTool == FencePackData.ToolType.Pickaxe) || (t is Axe && this.Data.BreakTool == FencePackData.ToolType.Axe)) { location.playSound(this.Data.BreakTool == FencePackData.ToolType.Axe ? "axchop" : "hammer"); location.objects.Remove(this.tileLocation); for (int i = 0; i < 4; i++) { location.temporarySprites.Add(new CosmeticDebris(this.fenceTexture.Value, new Vector2(this.tileLocation.X * 64f + 32f, this.tileLocation.Y * 64f + 32f), (float)Game1.random.Next(-5, 5) / 100f, (float)Game1.random.Next(-64, 64) / 30f, (float)Game1.random.Next(-800, -100) / 100f, (int)((this.tileLocation.Y + 1f) * 64f), new Rectangle(32 + Game1.random.Next(2) * 16 / 2, 96 + Game1.random.Next(2) * 16 / 2, 8, 8), Color.White, (Game1.soundBank != null) ? Game1.soundBank.GetCue("shiny4") : null, null, 0, 200)); } Game1.createRadialDebris(location, 12, (int)this.tileLocation.X, (int)this.tileLocation.Y, 6, resource: false); Game1_multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(12, new Vector2(this.tileLocation.X * 64f, this.tileLocation.Y * 64f), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); location.debris.Add(new Debris(this.getOne(), this.tileLocation.Value * 64f + new Vector2(32f, 32f))); } return(false); }
/// <summary>Get the output item.</summary> public override ITrackedStack GetOutput() { SObject heldObject = this.Machine.heldObject; return(new TrackedItem(heldObject.getOne(), this.GenericReset)); }
private static void TryCookRecipe(CraftingPage cookingMenu, ref Item heldItem) { SMonitor.Log("Trying to cook recipe"); bool succeeded = false; bool wouldHaveCooked = false; while (true) { bool keepCooking = false; List <string> possible = new List <string>(); foreach (var name in CraftingRecipe.cookingRecipes.Keys) { if (!Config.AllowUnknownRecipes && !Game1.player.cookingRecipes.ContainsKey(name)) { continue; } CraftingRecipe recipe = new CraftingRecipe(name, true); Item crafted = recipe.createItem(); if (crafted == null) { continue; } foreach (var key in recipe.recipeList.Keys) { int need = recipe.recipeList[key]; for (int i = 0; i < ingredients.Count; i++) { if (IsCorrectIngredient(ingredients[i], key)) { int consume = Math.Min(need, ingredients[i].Stack); need -= consume; } if (need <= 0) { break; } } if (need > 0) { goto nextRecipe; } } possible.Add(name); nextRecipe: continue; } possible.Sort(delegate(string a, string b) { return(new CraftingRecipe(b, true).recipeList.Count.CompareTo(new CraftingRecipe(a, true).recipeList.Count)); }); foreach (var name in possible) { CraftingRecipe recipe = new CraftingRecipe(name, true); Item crafted = recipe.createItem(); if (crafted == null) { continue; } if (heldItem is not null && (!heldItem.Name.Equals(crafted.Name) || !heldItem.getOne().canStackWith(crafted.getOne()) || heldItem.Stack + recipe.numberProducedPerCraft - 1 >= heldItem.maximumStackSize())) { if (Config.StoreOtherHeldItemOnCook) { heldItem = Utility.addItemToThisInventoryList(heldItem, cookingMenu.inventory.actualInventory, 36); } if (heldItem != null) { wouldHaveCooked = true; continue; } } SMonitor.Log($"Cooking recipe {name}"); foreach (var key in recipe.recipeList.Keys) { int need = recipe.recipeList[key]; for (int i = 0; i < ingredients.Count; i++) { if (IsCorrectIngredient(ingredients[i], key)) { int consume = Math.Min(need, ingredients[i].Stack); ingredients[i].Stack -= consume; if (ingredients[i].Stack <= 0) { ingredients[i] = null; } need -= consume; } if (need <= 0) { break; } } } bool seasoned = false; for (int i = 0; i < ingredients.Count; i++) { if (ingredients[i]?.ParentSheetIndex == 917) { ingredients[i].Stack--; if (ingredients[i].Stack <= 0) { ingredients[i] = null; } seasoned = true; (crafted as Object).Quality = 2; break; } } Game1.playSound("coin"); if (heldItem == null) { heldItem = crafted; } else { heldItem.Stack += recipe.numberProducedPerCraft; } if (seasoned) { SMonitor.Log("Added seasoning to recipe"); Game1.playSound("breathin"); } Game1.player.checkForQuestComplete(null, -1, -1, crafted, null, 2, -1); Game1.player.cookedRecipe(heldItem.ParentSheetIndex); Game1.stats.checkForCookingAchievements(); if (Game1.options.gamepadControls && heldItem != null && Game1.player.couldInventoryAcceptThisItem(heldItem)) { Game1.player.addItemToInventoryBool(heldItem, false); heldItem = null; } if (Config.LearnUnknownRecipes && !Game1.player.cookingRecipes.ContainsKey(name)) { Game1.player.cookingRecipes.Add(name, 0); Game1.playSound("yoba"); SMonitor.Log("Added new recipe"); Game1.showGlobalMessage(string.Format(SHelper.Translation.Get("new-recipe-x"), name)); AccessTools.Method(typeof(CraftingPage), "layoutRecipes").Invoke(cookingMenu, new object[] { CraftingRecipe.cookingRecipes.Keys.ToList() }); } succeeded = true; if (SHelper.Input.IsDown(Config.CookAllModKey)) { keepCooking = true; } else { UpdateCurrentCookables(); return; } } if (!keepCooking) { break; } } if (succeeded) { if (!SHelper.Input.IsDown(Config.CookAllModKey) && Config.ConsumeExtraIngredientsOnSucceed) { for (int i = 0; i < ingredients.Count; i++) { ingredients[i] = null; } } } else if (wouldHaveCooked) { Game1.addHUDMessage(new HUDMessage(SHelper.Translation.Get("cannot-cook"), 3)); Game1.playSound("cancel"); } else { Game1.addHUDMessage(new HUDMessage(SHelper.Translation.Get("cooking-failed"), 3)); Game1.playSound("cancel"); SMonitor.Log("Failed to cook recipe"); if (!SHelper.Input.IsDown(Config.CookAllModKey)) { if (Config.GiveTrashOnFail || Config.ConsumeIngredientsOnFail) { for (int i = 0; i < ingredients.Count; i++) { ingredients[i] = null; } if (Config.GiveTrashOnFail) { Object trash = new Object(168, 1); if (heldItem == null) { heldItem = trash; } else if (heldItem.Name.Equals(trash.Name) && heldItem.getOne().canStackWith(trash.getOne()) && heldItem.Stack < heldItem.maximumStackSize()) { heldItem.Stack++; } } } } } UpdateCurrentCookables(); }
/// <summary> /// Override to lift the pot back when an empty spot on the tool bar is selected. /// </summary> /// <param name="__result"></param> /// <returns></returns> public static bool PressUseToolButton(ref bool __result) { if (Game1.fadeToBlack) { return(false); } Game1.player.toolPower = 0; Game1.player.toolHold = 0; if (Game1.player.CurrentTool == null && Game1.player.ActiveObject == null) { Vector2 key = key = Game1.currentCursorTile; if (!Game1.currentLocation.Objects.ContainsKey(key) || !(Game1.currentLocation.Objects[key] is IndoorPot) || !Utility.tileWithinRadiusOfPlayer((int)key.X, (int)key.Y, 1, Game1.player)) { key = Game1.player.GetToolLocation(false) / 64f; key.X = (float)(int)key.X; key.Y = (float)(int)key.Y; } if (Game1.currentLocation.Objects.ContainsKey(key)) { Object @object = Game1.currentLocation.Objects[key]; if (@object is IndoorPot pot) { pot.performRemoveAction(pot.TileLocation, Game1.currentLocation); Game1.currentLocation.Objects.Remove(pot.TileLocation); HoeDirt potHoeDirt = pot.hoeDirt.Value; if (potHoeDirt.crop != null) { CurrentHeldIndoorPot = new HeldIndoorPot(pot.TileLocation); HoeDirt holdenHoeDirt = CurrentHeldIndoorPot.hoeDirt.Value; holdenHoeDirt.crop = potHoeDirt.crop; holdenHoeDirt.fertilizer.Value = potHoeDirt.fertilizer.Value; ShakeCrop(holdenHoeDirt, pot.TileLocation); Game1.player.Stamina -= ((float)DataLoader.ModConfig.CropTransplantEnergyCost - (float)Game1.player.FarmingLevel * DataLoader.ModConfig.CropTransplantEnergyCost / 20f); Game1.player.ActiveObject = CurrentHeldIndoorPot; Events.GameLoop.UpdateTicked += OnUpdateTicked; } else if (pot.bush.Value is Bush bush) { CurrentHeldIndoorPot = new HeldIndoorPot(pot.TileLocation); CurrentHeldIndoorPot.bush.Value = bush; Bush holdenBush = CurrentHeldIndoorPot.bush.Value; ShakeBush(holdenBush); Game1.player.Stamina -= ((float)DataLoader.ModConfig.CropTransplantEnergyCost - (float)Game1.player.FarmingLevel * DataLoader.ModConfig.CropTransplantEnergyCost / 20f); Game1.player.ActiveObject = CurrentHeldIndoorPot; Events.GameLoop.UpdateTicked += OnUpdateTicked; } else { Game1.player.ActiveObject = (Object)RegularPotObject.getOne(); } __result = true; return(false); } } } return(true); }
public override bool performToolAction(Tool t, GameLocation location) { if (heldObject.Value != null && t != null && !(t is MeleeWeapon) && t.isHeavyHitter()) { Object value = heldObject.Value; heldObject.Value.performRemoveAction(tileLocation, location); heldObject.Value = null; Game1.createItemDebris(value.getOne(), base.TileLocation * 64f, -1); location.playSound("axchop"); return(false); } if ((bool)isGate && t != null && (t is Axe || t is Pickaxe)) { location.playSound("axchop"); Game1.createObjectDebris(325, (int)tileLocation.X, (int)tileLocation.Y, Game1.player.UniqueMultiplayerID, Game1.player.currentLocation); location.objects.Remove(tileLocation); Game1.createRadialDebris(location, 12, (int)tileLocation.X, (int)tileLocation.Y, 6, resource: false); Game1.multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(12, new Vector2(tileLocation.X * 64f, tileLocation.Y * 64f), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); } if (((int)whichType == 1 || (int)whichType == 5) && (t == null || t is Axe)) { location.playSound("axchop"); location.objects.Remove(tileLocation); for (int i = 0; i < 4; i++) { location.temporarySprites.Add(new CosmeticDebris(fenceTexture.Value, new Vector2(tileLocation.X * 64f + 32f, tileLocation.Y * 64f + 32f), (float)Game1.random.Next(-5, 5) / 100f, (float)Game1.random.Next(-64, 64) / 30f, (float)Game1.random.Next(-800, -100) / 100f, (int)((tileLocation.Y + 1f) * 64f), new Rectangle(32 + Game1.random.Next(2) * 16 / 2, 96 + Game1.random.Next(2) * 16 / 2, 8, 8), Color.White, (Game1.soundBank != null) ? Game1.soundBank.GetCue("shiny4") : null, null, 0, 200)); } Game1.createRadialDebris(location, 12, (int)tileLocation.X, (int)tileLocation.Y, 6, resource: false); Game1.multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(12, new Vector2(tileLocation.X * 64f, tileLocation.Y * 64f), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); if ((float)maxHealth - (float)health < 0.5f) { switch ((int)whichType) { case 1: location.debris.Add(new Debris(new Object(322, 1), tileLocation.Value * 64f + new Vector2(32f, 32f))); break; case 5: location.debris.Add(new Debris(new Object(298, 1), tileLocation.Value * 64f + new Vector2(32f, 32f))); break; } } } else if (((int)whichType == 2 || (int)whichType == 3) && (t == null || t is Pickaxe)) { location.playSound("hammer"); location.objects.Remove(tileLocation); for (int j = 0; j < 4; j++) { location.temporarySprites.Add(new CosmeticDebris(fenceTexture.Value, new Vector2(tileLocation.X * 64f + 32f, tileLocation.Y * 64f + 32f), (float)Game1.random.Next(-5, 5) / 100f, (float)Game1.random.Next(-64, 64) / 30f, (float)Game1.random.Next(-800, -100) / 100f, (int)((tileLocation.Y + 1f) * 64f), new Rectangle(32 + Game1.random.Next(2) * 16 / 2, 96 + Game1.random.Next(2) * 16 / 2, 8, 8), Color.White, (Game1.soundBank != null) ? Game1.soundBank.GetCue("shiny4") : null, null, 0, 200)); } Game1.createRadialDebris(location, 14, (int)tileLocation.X, (int)tileLocation.Y, 6, resource: false); Game1.multiplayer.broadcastSprites(location, new TemporaryAnimatedSprite(12, new Vector2(tileLocation.X * 64f, tileLocation.Y * 64f), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f)); if ((float)maxHealth - (float)health < 0.5f) { switch ((int)whichType) { case 2: location.debris.Add(new Debris(new Object(323, 1), tileLocation.Value * 64f + new Vector2(32f, 32f))); break; case 3: location.debris.Add(new Debris(new Object(324, 1), tileLocation.Value * 64f + new Vector2(32f, 32f))); break; } } } return(false); }
internal static bool HarvestPrefix(Crop __instance, Vector2 ___tilePosition, int xTile, int yTile, HoeDirt soil, JunimoHarvester junimoHarvester = null) { Object cropObj = new Object(__instance.indexOfHarvest, 1); string cropName = "Unknown"; if (cropObj != null) { cropName = cropObj.DisplayName; } if (soil is null) { _monitor.Log($"Crop ({cropName}) at {xTile}, {yTile} is missing HoeDirt, unable to process!", LogLevel.Trace); return(true); } if (soil.currentLocation is null) { _monitor.Log($"Crop ({cropName}) at {xTile}, {yTile} is missing currentLocation (bad GameLocation?), unable to process!", LogLevel.Trace); return(true); } if (!soil.currentLocation.objects.Values.Any(o => o.modData.ContainsKey(ModEntry.harvestStatueFlag))) { return(true); } // If any farmer is in a location with a Harvest Statue and the farmer is not in bed, skip logic if (soil.currentLocation.farmers.Any(f => !f.isInBed)) { return(true); } // Get the nearby HarvestStatue, which will be placing the harvested crop into Chest statueObj = soil.currentLocation.objects.Values.First(o => o.modData.ContainsKey(ModEntry.harvestStatueFlag)) as Chest; if ((bool)__instance.dead) { return(false); } bool success = false; if ((bool)__instance.forageCrop) { Object o = null; System.Random r2 = new System.Random((int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame / 2 + xTile * 1000 + yTile * 2000); switch ((int)__instance.whichForageCrop) { case 1: o = new Object(399, 1); break; case 2: soil.shake((float)System.Math.PI / 48f, (float)System.Math.PI / 40f, (float)(xTile * 64) < Game1.player.Position.X); return(false); } if (Game1.player.professions.Contains(16)) { o.Quality = 4; } else if (r2.NextDouble() < (double)((float)Game1.player.ForagingLevel / 30f)) { o.Quality = 2; } else if (r2.NextDouble() < (double)((float)Game1.player.ForagingLevel / 15f)) { o.Quality = 1; } Game1.stats.ItemsForaged += (uint)o.Stack; // Try to add the forage crop to the HarvestStatue's inventory if (statueObj.addItem(o) != null) { // Statue is full, flag it as being eaten statueObj.modData[ModEntry.ateCropsFlag] = true.ToString(); } return(false); } else if ((int)__instance.currentPhase >= __instance.phaseDays.Count - 1 && (!__instance.fullyGrown || (int)__instance.dayOfCurrentPhase <= 0)) { int numToHarvest = 1; int cropQuality = 0; int fertilizerQualityLevel = 0; if ((int)__instance.indexOfHarvest == 0) { return(false); } System.Random r = new System.Random(xTile * 7 + yTile * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame); switch ((int)soil.fertilizer) { case 368: fertilizerQualityLevel = 1; break; case 369: fertilizerQualityLevel = 2; break; case 919: fertilizerQualityLevel = 3; break; } double chanceForGoldQuality = 0.2 * ((double)Game1.player.FarmingLevel / 10.0) + 0.2 * (double)fertilizerQualityLevel * (((double)Game1.player.FarmingLevel + 2.0) / 12.0) + 0.01; double chanceForSilverQuality = System.Math.Min(0.75, chanceForGoldQuality * 2.0); if (fertilizerQualityLevel >= 3 && r.NextDouble() < chanceForGoldQuality / 2.0) { cropQuality = 4; } else if (r.NextDouble() < chanceForGoldQuality) { cropQuality = 2; } else if (r.NextDouble() < chanceForSilverQuality || fertilizerQualityLevel >= 3) { cropQuality = 1; } if ((int)__instance.minHarvest > 1 || (int)__instance.maxHarvest > 1) { int max_harvest_increase = 0; if (__instance.maxHarvestIncreasePerFarmingLevel.Value > 0) { max_harvest_increase = Game1.player.FarmingLevel / (int)__instance.maxHarvestIncreasePerFarmingLevel; } numToHarvest = r.Next(__instance.minHarvest, System.Math.Max((int)__instance.minHarvest + 1, (int)__instance.maxHarvest + 1 + max_harvest_increase)); } if ((double)__instance.chanceForExtraCrops > 0.0) { while (r.NextDouble() < System.Math.Min(0.9, __instance.chanceForExtraCrops)) { numToHarvest++; } } if ((int)__instance.indexOfHarvest == 771 || (int)__instance.indexOfHarvest == 889) { cropQuality = 0; } Object harvestedItem = (__instance.programColored ? new ColoredObject(__instance.indexOfHarvest, 1, __instance.tintColor) { Quality = cropQuality } : new Object(__instance.indexOfHarvest, 1, isRecipe: false, -1, cropQuality)); if ((int)__instance.harvestMethod == 1) { if (statueObj.addItem(harvestedItem.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[ModEntry.ateCropsFlag] = true.ToString(); } success = true; } else if (statueObj.addItem(harvestedItem.getOne()) is null) { Vector2 initialTile = new Vector2(xTile, yTile); if (r.NextDouble() < Game1.player.team.AverageLuckLevel() / 1500.0 + Game1.player.team.AverageDailyLuck() / 1200.0 + 9.9999997473787516E-05) { numToHarvest *= 2; } success = true; } else { // Statue is full, flag it as being eaten statueObj.modData[ModEntry.ateCropsFlag] = true.ToString(); } if (success) { if ((int)__instance.indexOfHarvest == 421) { __instance.indexOfHarvest.Value = 431; numToHarvest = r.Next(1, 4); } int price = System.Convert.ToInt32(Game1.objectInformation[__instance.indexOfHarvest].Split('/')[1]); harvestedItem = (__instance.programColored ? new ColoredObject(__instance.indexOfHarvest, 1, __instance.tintColor) : new Object(__instance.indexOfHarvest, 1)); float experience = (float)(16.0 * System.Math.Log(0.018 * (double)price + 1.0, System.Math.E)); for (int i = 0; i < numToHarvest - 1; i++) { if (statueObj.addItem(harvestedItem.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[ModEntry.ateCropsFlag] = true.ToString(); } } if ((int)__instance.indexOfHarvest == 262 && r.NextDouble() < 0.4) { Object hay_item = new Object(178, 1); if (statueObj.addItem(hay_item.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[ModEntry.ateCropsFlag] = true.ToString(); } } else if ((int)__instance.indexOfHarvest == 771) { if (r.NextDouble() < 0.1) { Object mixedSeeds_item = new Object(770, 1); if (statueObj.addItem(mixedSeeds_item.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[ModEntry.ateCropsFlag] = true.ToString(); } } } if ((int)__instance.regrowAfterHarvest == -1) { return(false); } __instance.fullyGrown.Value = true; if (__instance.dayOfCurrentPhase.Value == (int)__instance.regrowAfterHarvest) { __instance.updateDrawMath(___tilePosition); } __instance.dayOfCurrentPhase.Value = __instance.regrowAfterHarvest; } } return(false); }
public bool harvest(int xTile, int yTile, HoeDirt soil, JunimoHarvester junimoHarvester = null) { if ((bool)dead) { if (junimoHarvester != null) { return(true); } return(false); } bool success = false; if ((bool)forageCrop) { Object o = null; int experience2 = 3; Random r2 = new Random((int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame / 2 + xTile * 1000 + yTile * 2000); switch ((int)whichForageCrop) { case 1: o = new Object(399, 1); break; case 2: soil.shake((float)Math.PI / 48f, (float)Math.PI / 40f, (float)(xTile * 64) < Game1.player.Position.X); return(false); } if (Game1.player.professions.Contains(16)) { o.Quality = 4; } else if (r2.NextDouble() < (double)((float)Game1.player.ForagingLevel / 30f)) { o.Quality = 2; } else if (r2.NextDouble() < (double)((float)Game1.player.ForagingLevel / 15f)) { o.Quality = 1; } Game1.stats.ItemsForaged += (uint)o.Stack; if (junimoHarvester != null) { junimoHarvester.tryToAddItemToHut(o); return(true); } if (Game1.player.addItemToInventoryBool(o)) { Vector2 initialTile2 = new Vector2(xTile, yTile); Game1.player.animateOnce(279 + Game1.player.FacingDirection); Game1.player.canMove = false; Game1.player.currentLocation.playSound("harvest"); DelayedAction.playSoundAfterDelay("coin", 260); if ((int)regrowAfterHarvest == -1) { Game1.multiplayer.broadcastSprites(Game1.currentLocation, new TemporaryAnimatedSprite(17, new Vector2(initialTile2.X * 64f, initialTile2.Y * 64f), Color.White, 7, r2.NextDouble() < 0.5, 125f)); Game1.multiplayer.broadcastSprites(Game1.currentLocation, new TemporaryAnimatedSprite(14, new Vector2(initialTile2.X * 64f, initialTile2.Y * 64f), Color.White, 7, r2.NextDouble() < 0.5, 50f)); } Game1.player.gainExperience(2, experience2); return(true); } Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Crop.cs.588")); } else if ((int)currentPhase >= phaseDays.Count - 1 && (!fullyGrown || (int)dayOfCurrentPhase <= 0)) { int numToHarvest = 1; int cropQuality = 0; int fertilizerQualityLevel = 0; if ((int)indexOfHarvest == 0) { return(true); } Random r = new Random(xTile * 7 + yTile * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame); switch ((int)soil.fertilizer) { case 368: fertilizerQualityLevel = 1; break; case 369: fertilizerQualityLevel = 2; break; case 919: fertilizerQualityLevel = 3; break; } double chanceForGoldQuality = 0.2 * ((double)Game1.player.FarmingLevel / 10.0) + 0.2 * (double)fertilizerQualityLevel * (((double)Game1.player.FarmingLevel + 2.0) / 12.0) + 0.01; double chanceForSilverQuality = Math.Min(0.75, chanceForGoldQuality * 2.0); if (fertilizerQualityLevel >= 3 && r.NextDouble() < chanceForGoldQuality / 2.0) { cropQuality = 4; } else if (r.NextDouble() < chanceForGoldQuality) { cropQuality = 2; } else if (r.NextDouble() < chanceForSilverQuality || fertilizerQualityLevel >= 3) { cropQuality = 1; } if ((int)minHarvest > 1 || (int)maxHarvest > 1) { int max_harvest_increase = 0; if (maxHarvestIncreasePerFarmingLevel.Value > 0) { max_harvest_increase = Game1.player.FarmingLevel / (int)maxHarvestIncreasePerFarmingLevel; } numToHarvest = r.Next(minHarvest, Math.Max((int)minHarvest + 1, (int)maxHarvest + 1 + max_harvest_increase)); } if ((double)chanceForExtraCrops > 0.0) { while (r.NextDouble() < Math.Min(0.9, chanceForExtraCrops)) { numToHarvest++; } } if ((int)indexOfHarvest == 771 || (int)indexOfHarvest == 889) { cropQuality = 0; } Object harvestedItem = (programColored ? new ColoredObject(indexOfHarvest, 1, tintColor) { Quality = cropQuality } : new Object(indexOfHarvest, 1, isRecipe: false, -1, cropQuality)); if ((int)harvestMethod == 1) { if (junimoHarvester != null) { DelayedAction.playSoundAfterDelay("daggerswipe", 150, junimoHarvester.currentLocation); } if (junimoHarvester != null && Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), 64, junimoHarvester.currentLocation)) { junimoHarvester.currentLocation.playSound("harvest"); } if (junimoHarvester != null && Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), 64, junimoHarvester.currentLocation)) { DelayedAction.playSoundAfterDelay("coin", 260, junimoHarvester.currentLocation); } if (junimoHarvester != null) { junimoHarvester.tryToAddItemToHut(harvestedItem.getOne()); } else { Game1.createItemDebris(harvestedItem.getOne(), new Vector2(xTile * 64 + 32, yTile * 64 + 32), -1); } success = true; } else if (junimoHarvester != null || Game1.player.addItemToInventoryBool(harvestedItem.getOne())) { Vector2 initialTile = new Vector2(xTile, yTile); if (junimoHarvester == null) { Game1.player.animateOnce(279 + Game1.player.FacingDirection); Game1.player.canMove = false; } else { junimoHarvester.tryToAddItemToHut(harvestedItem.getOne()); } if (r.NextDouble() < Game1.player.team.AverageLuckLevel() / 1500.0 + Game1.player.team.AverageDailyLuck() / 1200.0 + 9.9999997473787516E-05) { numToHarvest *= 2; if (junimoHarvester == null) { Game1.player.currentLocation.playSound("dwoop"); } else if (Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), 64, junimoHarvester.currentLocation)) { junimoHarvester.currentLocation.playSound("dwoop"); } } else if ((int)harvestMethod == 0) { if (junimoHarvester == null) { Game1.player.currentLocation.playSound("harvest"); } else if (Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), 64, junimoHarvester.currentLocation)) { junimoHarvester.currentLocation.playSound("harvest"); } if (junimoHarvester == null) { DelayedAction.playSoundAfterDelay("coin", 260, Game1.player.currentLocation); } else if (Utility.isOnScreen(junimoHarvester.getTileLocationPoint(), 64, junimoHarvester.currentLocation)) { DelayedAction.playSoundAfterDelay("coin", 260, junimoHarvester.currentLocation); } if ((int)regrowAfterHarvest == -1 && (junimoHarvester == null || junimoHarvester.currentLocation.Equals(Game1.currentLocation))) { Game1.multiplayer.broadcastSprites(Game1.currentLocation, new TemporaryAnimatedSprite(17, new Vector2(initialTile.X * 64f, initialTile.Y * 64f), Color.White, 7, Game1.random.NextDouble() < 0.5, 125f)); Game1.multiplayer.broadcastSprites(Game1.currentLocation, new TemporaryAnimatedSprite(14, new Vector2(initialTile.X * 64f, initialTile.Y * 64f), Color.White, 7, Game1.random.NextDouble() < 0.5, 50f)); } } success = true; } else { Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Crop.cs.588")); } if (success) { if ((int)indexOfHarvest == 421) { indexOfHarvest.Value = 431; numToHarvest = r.Next(1, 4); } int price = Convert.ToInt32(Game1.objectInformation[indexOfHarvest].Split('/')[1]); harvestedItem = (programColored ? new ColoredObject(indexOfHarvest, 1, tintColor) : new Object(indexOfHarvest, 1)); float experience = (float)(16.0 * Math.Log(0.018 * (double)price + 1.0, Math.E)); if (junimoHarvester == null) { Game1.player.gainExperience(0, (int)Math.Round(experience)); } for (int i = 0; i < numToHarvest - 1; i++) { if (junimoHarvester == null) { Game1.createItemDebris(harvestedItem.getOne(), new Vector2(xTile * 64 + 32, yTile * 64 + 32), -1); } else { junimoHarvester.tryToAddItemToHut(harvestedItem.getOne()); } } if ((int)indexOfHarvest == 262 && r.NextDouble() < 0.4) { Object hay_item = new Object(178, 1); if (junimoHarvester == null) { Game1.createItemDebris(hay_item.getOne(), new Vector2(xTile * 64 + 32, yTile * 64 + 32), -1); } else { junimoHarvester.tryToAddItemToHut(hay_item.getOne()); } } else if ((int)indexOfHarvest == 771) { Game1.player.currentLocation.playSound("cut"); if (r.NextDouble() < 0.1) { Object mixedSeeds_item = new Object(770, 1); if (junimoHarvester == null) { Game1.createItemDebris(mixedSeeds_item.getOne(), new Vector2(xTile * 64 + 32, yTile * 64 + 32), -1); } else { junimoHarvester.tryToAddItemToHut(mixedSeeds_item.getOne()); } } } if ((int)regrowAfterHarvest == -1) { return(true); } fullyGrown.Value = true; if (dayOfCurrentPhase.Value == (int)regrowAfterHarvest) { updateDrawMath(tilePosition); } dayOfCurrentPhase.Value = regrowAfterHarvest; } } return(false); }
private static void CollectObj(GameLocation loc, SVObject obj) { Farmer who = Game1.player; Vector2 vector = Util.GetLocationOf(loc, obj); if ((int)vector.X == -1 && (int)vector.Y == -1) { return; } if (obj.questItem.Value) { return; } int quality = obj.Quality; Random random = new Random((int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed + (int)vector.X + (int)vector.Y * 777); if (who.professions.Contains(16) && obj.isForage(loc)) { obj.Quality = 4; } else if (obj.isForage(loc)) { if (random.NextDouble() < who.ForagingLevel / 30f) { obj.Quality = 2; } else if (random.NextDouble() < who.ForagingLevel / 15f) { obj.Quality = 1; } } if (who.couldInventoryAcceptThisItem(obj)) { Logger.Log($"picked up {obj.DisplayName} at [{vector.X},{vector.Y}]"); if (who.IsLocalPlayer) { loc.localSound("pickUpItem"); DelayedAction.playSoundAfterDelay("coin", 300); } if (!who.isRidingHorse() && !who.ridingMineElevator) { who.animateOnce(279 + who.FacingDirection); } if (!loc.isFarmBuildingInterior()) { if (obj.isForage(loc)) { who.gainExperience(2, 7); } } else { who.gainExperience(0, 5); } who.addItemToInventoryBool(obj.getOne()); Game1.stats.ItemsForaged++; if (who.professions.Contains(13) && random.NextDouble() < 0.2 && !obj.questItem.Value && who.couldInventoryAcceptThisItem(obj) && !loc.isFarmBuildingInterior()) { who.addItemToInventoryBool(obj.getOne()); who.gainExperience(2, 7); } loc.Objects.Remove(vector); return; } obj.Quality = quality; }
/// <summary>Get the output item.</summary> public override ITrackedStack GetOutput() { SObject heldObject = this.Machine.heldObject.Value; return(new TrackedItem(heldObject.getOne(), onEmpty: this.Reset)); }