/// <summary>Break open a container using a tool, if applicable.</summary> /// <param name="tile">The tile position</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="location">The current location.</param> protected bool TryBreakContainer(Vector2 tile, SObject tileObj, Tool tool, GameLocation location) { if (tileObj is BreakableContainer) { return(tileObj.performToolAction(tool, location)); } if (tileObj?.GetItemType() == ItemType.Object && tileObj.Name == "SupplyCrate" && !(tileObj is Chest) && tileObj.performToolAction(tool, location)) { tileObj.performRemoveAction(tile, location); Game1.currentLocation.Objects.Remove(tile); return(true); } return(false); }
/// <summary>Get the custom fields indicating what an item is needed for.</summary> /// <param name="obj">The machine whose output to represent.</param> private IEnumerable <ICustomField> GetNeededForFields(SObject obj) { if (obj == null || obj.GetItemType() != ItemType.Object) { yield break; } List <string> neededFor = new List <string>(); // bundles { string[] missingBundles = ( from bundle in this.GetUnfinishedBundles(obj) orderby bundle.Area, bundle.DisplayName let countNeeded = this.GetIngredientCountNeeded(bundle, obj) select countNeeded > 1 ? $"{this.GetTranslatedBundleArea(bundle)}: {bundle.DisplayName} x {countNeeded}" : $"{this.GetTranslatedBundleArea(bundle)}: {bundle.DisplayName}" ) .ToArray(); if (missingBundles.Any()) { neededFor.Add(I18n.Item_NeededFor_CommunityCenter(bundles: string.Join(", ", missingBundles))); } } // polyculture achievement (ship 15 crops) if (this.Constants.PolycultureCrops.Contains(obj.ParentSheetIndex)) { int needed = this.Constants.PolycultureCount - this.GameHelper.GetShipped(obj.ParentSheetIndex); if (needed > 0) { neededFor.Add(I18n.Item_NeededFor_Polyculture(count: needed)); } } // full shipment achievement (ship every item) if (this.GameHelper.GetFullShipmentAchievementItems().Any(p => p.Key == obj.ParentSheetIndex && !p.Value)) { neededFor.Add(I18n.Item_NeededFor_FullShipment()); } // full collection achievement (donate every artifact) if (obj.needsToBeDonated()) { neededFor.Add(I18n.Item_NeededFor_FullCollection()); } // recipe achievements { var recipes = ( from recipe in this.GameHelper.GetRecipesForIngredient(this.DisplayItem) let item = recipe.CreateItem(this.DisplayItem) orderby item.DisplayName select new { recipe.Type, item.DisplayName, TimesCrafted = recipe.GetTimesCrafted(Game1.player) } ) .ToArray(); // gourmet chef achievement (cook every recipe) string[] uncookedNames = (from recipe in recipes where recipe.Type == RecipeType.Cooking && recipe.TimesCrafted <= 0 select recipe.DisplayName).ToArray(); if (uncookedNames.Any()) { neededFor.Add(I18n.Item_NeededFor_GourmetChef(recipes: string.Join(", ", uncookedNames))); } // craft master achievement (craft every item) string[] uncraftedNames = (from recipe in recipes where recipe.Type == RecipeType.Crafting && recipe.TimesCrafted <= 0 select recipe.DisplayName).ToArray(); if (uncraftedNames.Any()) { neededFor.Add(I18n.Item_NeededFor_CraftMaster(recipes: string.Join(", ", uncraftedNames))); } } // yield if (neededFor.Any()) { yield return(new GenericField(I18n.Item_NeededFor(), string.Join(", ", neededFor))); } }
/// <summary>Get the custom fields for machine output.</summary> /// <param name="machine">The machine whose output to represent.</param> private IEnumerable <ICustomField> GetMachineOutputFields(SObject machine) { if (machine == null) { yield break; } SObject heldObj = machine.heldObject.Value; int minutesLeft = machine.MinutesUntilReady; // cask if (machine is Cask cask) { // output item if (heldObj != null) { ItemQuality curQuality = (ItemQuality)heldObj.Quality; // calculate aging schedule float effectiveAge = this.Constants.CaskAgeSchedule.Values.Max() - cask.daysToMature.Value; var schedule = ( from entry in this.Constants.CaskAgeSchedule let quality = entry.Key let baseDays = entry.Value where baseDays > effectiveAge orderby baseDays ascending let daysLeft = (int)Math.Ceiling((baseDays - effectiveAge) / cask.agingRate.Value) select new { Quality = quality, DaysLeft = daysLeft, HarvestDate = SDate.Now().AddDays(daysLeft) } ) .ToArray(); // display fields yield return(new ItemIconField(this.GameHelper, I18n.Item_Contents(), heldObj)); if (minutesLeft <= 0 || !schedule.Any()) { yield return(new GenericField(I18n.Item_CaskSchedule(), I18n.Item_CaskSchedule_Now(quality: I18n.For(curQuality)))); } else { string scheduleStr = string.Join(Environment.NewLine, ( from entry in schedule let str = I18n.GetPlural(entry.DaysLeft, I18n.Item_CaskSchedule_Tomorrow(quality: I18n.For(entry.Quality)), I18n.Item_CaskSchedule_InXDays(quality: I18n.For(entry.Quality), count: entry.DaysLeft, date: this.Stringify(entry.HarvestDate))) select $"-{str}" )); yield return(new GenericField(I18n.Item_CaskSchedule(), $"{I18n.Item_CaskSchedule_NowPartial(quality: I18n.For(curQuality))}{Environment.NewLine}{scheduleStr}")); } } } // crab pot else if (machine is CrabPot pot) { // bait if (heldObj == null) { if (pot.bait.Value != null) { yield return(new ItemIconField(this.GameHelper, I18n.Item_CrabpotBait(), pot.bait.Value)); } else if (Game1.player.professions.Contains(11)) // no bait needed if luremaster { yield return(new GenericField(I18n.Item_CrabpotBait(), I18n.Item_CrabpotBaitNotNeeded())); } else { yield return(new GenericField(I18n.Item_CrabpotBait(), I18n.Item_CrabpotBaitNeeded())); } } // output item if (heldObj != null) { string summary = I18n.Item_Contents_Ready(name: heldObj.DisplayName); yield return(new ItemIconField(this.GameHelper, I18n.Item_Contents(), heldObj, summary)); } } // furniture else if (machine is Furniture) { // displayed item if (heldObj != null) { string summary = I18n.Item_Contents_Placed(name: heldObj.DisplayName); yield return(new ItemIconField(this.GameHelper, I18n.Item_Contents(), heldObj, summary)); } } // auto-grabber else if (machine.ParentSheetIndex == Constant.ObjectIndexes.AutoGrabber && machine.GetItemType() == ItemType.BigCraftable) { string readyText = I18n.Stringify(heldObj is Chest output && output.items.Any()); yield return(new GenericField(I18n.Item_Contents(), readyText)); } // generic machine else { // output item if (heldObj != null) { string summary = minutesLeft <= 0 ? I18n.Item_Contents_Ready(name: heldObj.DisplayName) : I18n.Item_Contents_Partial(name: heldObj.DisplayName, time: this.Stringify(TimeSpan.FromMinutes(minutesLeft))); yield return(new ItemIconField(this.GameHelper, I18n.Item_Contents(), heldObj, summary)); } } }