public void TryAdd(ProtoItemWithCountFractional entry) { if (!(entry.ProtoItem is IProtoItemFood protoItemFood)) { return; } this.FoodRestore += protoItemFood.FoodRestore * entry.Count; this.HealthRestore += protoItemFood.HealthRestore * entry.Count; this.StaminaRestore += protoItemFood.StaminaRestore * entry.Count; this.WaterRestore += protoItemFood.WaterRestore * entry.Count; }
private static void AddListEntry( List <ProtoItemWithCountFractional> list, ProtoItemWithCountFractional entry) { for (var index = 0; index < list.Count; index++) { var existingEntry = list[index]; if (!ReferenceEquals(existingEntry.ProtoItem, entry.ProtoItem)) { continue; } // entry found - combine them list[index] = new ProtoItemWithCountFractional(entry.ProtoItem, entry.Count + existingEntry.Count); return; } // entry not found - add new entry list.Add(entry); }
public ViewModelRequiredItemControl(ProtoItemWithCountFractional protoItemWithCount) { this.ProtoItemWithCount = protoItemWithCount; }
public ViewModelRecipeBreakdown(Recipe recipe) { var inputItems = new List <ProtoItemWithCountFractional>(); var outputItems = new List <ProtoItemWithCountFractional>(); var outputItemsExtras = new List <ProtoItemWithCountFractional>(); var intermediateRecipes = new List <ViewModelIntermediateRecipe>(); var inputNutrition = new NutritionValueInfo(); var outputNutrition = new NutritionValueInfo(); var multiplier = 1 / (double)recipe.OutputItems.Items[0].Count; var isOriginalRecipeManufacturing = recipe.RecipeType == RecipeType.Manufacturing || recipe.RecipeType == RecipeType.ManufacturingByproduct; var originalRecipeDurationPerItem = recipe.OriginalDuration * multiplier; double specificDurationCrafting, specificDurationManufacturing; if (isOriginalRecipeManufacturing) { specificDurationCrafting = 0; specificDurationManufacturing = originalRecipeDurationPerItem; } else { specificDurationCrafting = originalRecipeDurationPerItem; specificDurationManufacturing = 0; } var timeSb = new StringBuilder() .AppendLine($"{recipe.Name} — per single item:") .AppendLine(); var recursiveErrorsSb = new StringBuilder(); var tag = isOriginalRecipeManufacturing ? "[manufacture]" : "[craft]"; timeSb.AppendLine($"{tag} {originalRecipeDurationPerItem:0.##}s — x{multiplier:0.##} {recipe.Name}"); foreach (var outputItem in recipe.OutputItems.Items) { var entry = new ProtoItemWithCountFractional(outputItem.ProtoItem, outputItem.Count * multiplier); outputItems.Add(entry); outputNutrition.TryAdd(entry); } ProcessInputRecursive(recipe, multiplier, depth: 0); inputItems.Sort(ListOrderComparison); outputItems.Sort(ListOrderComparison); outputItemsExtras.Sort(ListOrderComparison); this.InputItems = inputItems; this.OutputItems = outputItems; this.OutputItemsExtras = outputItemsExtras; this.IntermediateRecipes = intermediateRecipes; this.InputTotalNutritionValue = inputNutrition; this.OutputTotalNutritionValue = outputNutrition; this.RecipesDurationTotalText = ClientTimeFormatHelper.FormatTimeDuration( specificDurationCrafting, roundSeconds: false) + " + " + ClientTimeFormatHelper.FormatTimeDuration( specificDurationManufacturing, roundSeconds: false); timeSb.AppendLine() .AppendLine($"Total duration: {this.RecipesDurationTotalText} (crafting + manufacturing)"); this.recipeTimeCalculation = timeSb.ToString().Trim('\r', '\n'); this.RecursiveErrors = recursiveErrorsSb.Length > 0 ? "Nested recipes recursion detected." + Environment.NewLine + "Recursion was broken when looking for recipes for these item(s):" + Environment.NewLine + recursiveErrorsSb + Environment.NewLine + "Intermediate recipes list:" + string.Join("", this.IntermediateRecipes.Select( r => Environment.NewLine + "* " + r.ViewModelCraftingRecipe.Title)) + Environment.NewLine + Environment.NewLine + $"Please edit {nameof(BasicItems)} or {nameof(RecipesHelper.BlacklistRecipes)} lists in {nameof(ViewModelRecipeBreakdown)}.cs (Editor.mpk)" : null; void ProcessInputRecursive(Recipe outerRecipe, double outerMultiplier, int depth) { foreach (var inputItem in outerRecipe.InputItems) { if (BasicItems.Contains(inputItem.ProtoItem.GetType())) { // don't lookup recipe var entry = new ProtoItemWithCountFractional(inputItem.ProtoItem, inputItem.Count * outerMultiplier); AddListEntry(inputItems, entry); inputNutrition.TryAdd(entry); continue; } var inputItemRecipe = RecipesHelper.FindFirstRecipe(inputItem.ProtoItem); if (inputItemRecipe == null) { // no recipe var entry = new ProtoItemWithCountFractional(inputItem.ProtoItem, inputItem.Count * outerMultiplier); AddListEntry(inputItems, entry); inputNutrition.TryAdd(entry); continue; } if (depth > 20) { // recursion went too deep, stop here recursiveErrorsSb.AppendLine("* " + inputItem.ProtoItem.Name); return; } // expand recipe var recipeMultiplier = inputItem.Count / (double)inputItemRecipe.OutputItems.Items[0].Count; AddIntermediateRecipe(intermediateRecipes, inputItemRecipe, recipeMultiplier * outerMultiplier); ProcessInputRecursive(inputItemRecipe, recipeMultiplier * outerMultiplier, depth: depth + 1); var isManufacturing = inputItemRecipe.RecipeType == RecipeType.Manufacturing || inputItemRecipe.RecipeType == RecipeType.ManufacturingByproduct; var inputItemRecipeDuration = inputItemRecipe.OriginalDuration * recipeMultiplier * outerMultiplier; if (isManufacturing) { specificDurationManufacturing += inputItemRecipeDuration; } else { specificDurationCrafting += inputItemRecipeDuration; } var tag = isManufacturing ? "[manufacture]" : "[craft]"; timeSb.AppendLine( $"{tag} {ClientTimeFormatHelper.FormatTimeDuration(inputItemRecipeDuration, roundSeconds: true)} — x{recipeMultiplier * outerMultiplier:0.##} {inputItemRecipe.Name} (for {outerRecipe.Name})"); foreach (var outputItem in inputItemRecipe.OutputItems.Items) { if (outputItem.ProtoItem == inputItem.ProtoItem) { continue; } var entry = new ProtoItemWithCountFractional(outputItem.ProtoItem, outputItem.Count * recipeMultiplier * outerMultiplier); AddListEntry(outputItemsExtras, entry); outputNutrition.TryAdd(entry); } } } }
private static int ListOrderComparison(ProtoItemWithCountFractional x, ProtoItemWithCountFractional y) { return(string.Compare(x.ProtoItem.Id, y.ProtoItem.Id, StringComparison.Ordinal)); }