From 2e737e9809b54f9269a8e9c567f80b74ae3f1004 Mon Sep 17 00:00:00 2001 From: Genju Date: Tue, 6 Feb 2024 15:37:34 +0100 Subject: [PATCH] First draft recipescan optimize subrecipes --- Data/Classes/PriceData.lua | 2 +- Data/Classes/RecipeData.lua | 11 ++++++++--- Main/CraftSim.lua | 4 +++- Modules/CostDetails/Frames.lua | 2 +- .../ReagentOptimization/ReagentOptimization.lua | 10 +++++----- Modules/RecipeScan/Frames.lua | 14 ++++++++++++-- Modules/RecipeScan/RecipeScan.lua | 8 ++++++++ 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/Data/Classes/PriceData.lua b/Data/Classes/PriceData.lua index 80e33be8..0905e87c 100644 --- a/Data/Classes/PriceData.lua +++ b/Data/Classes/PriceData.lua @@ -30,7 +30,7 @@ function CraftSim.PriceData:Update() wipe(self.qualityPriceList) wipe(self.expectedCostsByQuality) - local useSubRecipes = CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization + local useSubRecipes = self.recipeData.subRecipeCostsEnabled print("Update PriceData", false, true) print("using subrecipes: " .. tostring(useSubRecipes)) diff --git a/Data/Classes/RecipeData.lua b/Data/Classes/RecipeData.lua index 2aeae365..124995bc 100644 --- a/Data/Classes/RecipeData.lua +++ b/Data/Classes/RecipeData.lua @@ -37,6 +37,7 @@ function CraftSim.RecipeData:new(recipeID, isRecraft, isWorkOrder, crafterData) --- might be not necessary ---@type CraftSim.RecipeData[] self.optimizedSubRecipes = {} + self.subRecipeCostsEnabled = false if not recipeID then return -- e.g. when deserializing @@ -249,6 +250,10 @@ function CraftSim.RecipeData:new(recipeID, isRecraft, isWorkOrder, crafterData) end end +function CraftSim.RecipeData:SetSubRecipeCostsUsage(enabled) + self.subRecipeCostsEnabled = enabled +end + ---@param reagentList CraftSim.ReagentListItem[] function CraftSim.RecipeData:SetReagents(reagentList) -- go through required reagents and set quantity accordingly @@ -467,9 +472,9 @@ function CraftSim.RecipeData:Copy() copy.resultData = self.resultData:Copy(copy) -- Is this needed or covered by constructor? -- copy spec data or already handled in constructor? copy.orderData = self.orderData - copy.crafter = self.crafter - copy.crafterClass = self.crafterClass - copy.crafterRealm = self.crafterRealm + copy.crafterData = self.crafterData + copy.subRecipeCostsEnabled = self.subRecipeCostsEnabled + copy.optimizedSubRecipes = self.optimizedSubRecipes copy:Update() return copy diff --git a/Main/CraftSim.lua b/Main/CraftSim.lua index 2e81ad09..e6275395 100644 --- a/Main/CraftSim.lua +++ b/Main/CraftSim.lua @@ -67,6 +67,7 @@ CraftSimOptions = CraftSimOptions or { recipeScanFilteredExpansions = nil, recipeScanAltProfessions = nil, recipeScanImportAllProfessions = false, + recipeScanOptimizeSubRecipes = false, -- profit calc customMulticraftConstant = CraftSim.CONST.MULTICRAFT_CONSTANT, @@ -682,7 +683,8 @@ function CraftSim.MAIN:TriggerModulesByRecipeType() end -- subrecipe optimization - if CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization then + recipeData:SetSubRecipeCostsUsage(CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization) + if recipeData.subRecipeCostsEnabled then CraftSim.UTIL:StartProfiling("OptimizeSubRecipes") recipeData:OptimizeSubRecipes() CraftSim.UTIL:StopProfiling("OptimizeSubRecipes") diff --git a/Modules/CostDetails/Frames.lua b/Modules/CostDetails/Frames.lua index 79060568..e5918090 100644 --- a/Modules/CostDetails/Frames.lua +++ b/Modules/CostDetails/Frames.lua @@ -224,7 +224,7 @@ function CraftSim.COST_DETAILS:UpdateDisplay(recipeData, exportMode) costDetailsFrame = CraftSim.COST_DETAILS.frame end - local considerSubRecipes = CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization + local considerSubRecipes = recipeData.subRecipeCostsEnabled costDetailsFrame.content.craftingCostsValue:SetText(CraftSim.GUTIL:FormatMoney(recipeData.priceData.craftingCosts)) diff --git a/Modules/ReagentOptimization/ReagentOptimization.lua b/Modules/ReagentOptimization/ReagentOptimization.lua index e9b69d85..845a95a7 100644 --- a/Modules/ReagentOptimization/ReagentOptimization.lua +++ b/Modules/ReagentOptimization/ReagentOptimization.lua @@ -225,7 +225,7 @@ function CraftSim.REAGENT_OPTIMIZATION:IsCurrentAllocation(recipeData, bestResul return recipeData.reagentData:EqualsQualityReagents(bestResult.reagents) end -function CraftSim.REAGENT_OPTIMIZATION:CreateCrumbs(ksItem) +function CraftSim.REAGENT_OPTIMIZATION:CreateCrumbs(ksItem, useSubRecipeCosts) local inf = math.huge local j, k, a, b, c, n, w @@ -241,11 +241,11 @@ function CraftSim.REAGENT_OPTIMIZATION:CreateCrumbs(ksItem) end local q3ItemPrice = CraftSim.PRICEDATA:GetMinBuyoutByItemID(ksItem.reagent.items[3].item:GetItemID(), true, false, - CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization) + useSubRecipeCosts) local q2ItemPrice = CraftSim.PRICEDATA:GetMinBuyoutByItemID(ksItem.reagent.items[2].item:GetItemID(), true, false, - CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization) + useSubRecipeCosts) local q1ItemPrice = CraftSim.PRICEDATA:GetMinBuyoutByItemID(ksItem.reagent.items[1].item:GetItemID(), true, false, - CraftSimOptions.costOptimizationAutomaticSubRecipeOptimization) + useSubRecipeCosts) --print("start crumb creation: " .. ksItem.name) for k = 0, n, 1 do @@ -341,7 +341,7 @@ function CraftSim.REAGENT_OPTIMIZATION:OptimizeReagentAllocation(recipeData) --print("mWeight[index] / weightGCD -> " .. mWeight[index] .. " / " .. weightGCD .. " = " .. mWeight[index] / weightGCD) -- fill crumbs - CraftSim.REAGENT_OPTIMIZATION:CreateCrumbs(ksItem) + CraftSim.REAGENT_OPTIMIZATION:CreateCrumbs(ksItem, recipeData.subRecipeCostsEnabled) ksItems[index] = ksItem end CraftSim.UTIL:StopProfiling("KnapsackKsItemCreation") diff --git a/Modules/RecipeScan/Frames.lua b/Modules/RecipeScan/Frames.lua index 8bebd93a..e682084b 100644 --- a/Modules/RecipeScan/Frames.lua +++ b/Modules/RecipeScan/Frames.lua @@ -4,6 +4,7 @@ local CraftSim = select(2, ...) local GGUI = CraftSim.GGUI local GUTIL = CraftSim.GUTIL local L = CraftSim.UTIL:GetLocalizer() +local f = CraftSim.UTIL:GetFormatter() ---@class CraftSim.RECIPE_SCAN CraftSim.RECIPE_SCAN = CraftSim.RECIPE_SCAN @@ -697,6 +698,15 @@ function CraftSim.RECIPE_SCAN.FRAMES:InitScanOptionsTab(scanOptionsTab) clickCallback = function(_, checked) CraftSimOptions.recipeScanUseInsight = checked end } + content.optimizeSubRecipes = GGUI.Checkbox { + parent = content, anchorParent = content.useInsightCB.frame, anchorA = "TOP", anchorB = "BOTTOM", offsetY = checkBoxSpacingY, + label = "Optimize Sub Recipes", + tooltip = "If enabled, " .. f.l("CraftSim") .. " also optimizes crafts of cached reagent recipes of scanned recipes and uses their\n" .. + f.bb("expected costs") .. " to calculate the crafting costs for the final product.\n\n" .. f.r("Warning: This might reduce scanning performance"), + initialValue = CraftSimOptions.recipeScanOptimizeSubRecipes, + clickCallback = function(_, checked) CraftSimOptions.recipeScanOptimizeSubRecipes = checked end + } + content.expansionSelector = GGUI.CheckboxSelector { savedVariablesTable = CraftSimOptions.recipeScanFilteredExpansions, initialItems = GUTIL:Sort(GUTIL:Map(CraftSim.CONST.EXPANSION_IDS, @@ -717,9 +727,9 @@ function CraftSim.RECIPE_SCAN.FRAMES:InitScanOptionsTab(scanOptionsTab) }, buttonOptions = { - parent = content, anchorParent = content.useInsightCB.frame, + parent = content, anchorParent = content.optimizeSubRecipes.frame, anchorA = "TOPLEFT", anchorB = "BOTTOMLEFT", offsetY = checkBoxSpacingY, - label = L(CraftSim.CONST.TEXT.RECIPE_SCAN_EXPANSION_FILTER_BUTTON), offsetX = 20, + label = L(CraftSim.CONST.TEXT.RECIPE_SCAN_EXPANSION_FILTER_BUTTON), offsetX = 25, adjustWidth = true, sizeX = 20, }, } diff --git a/Modules/RecipeScan/RecipeScan.lua b/Modules/RecipeScan/RecipeScan.lua index 437f27d3..30df6bef 100644 --- a/Modules/RecipeScan/RecipeScan.lua +++ b/Modules/RecipeScan/RecipeScan.lua @@ -286,6 +286,14 @@ function CraftSim.RECIPE_SCAN:StartScan(row) return end + -- if optimizing subrecipes + if CraftSimOptions.recipeScanOptimizeSubRecipes then + printS("Optimizing SubRecipes..") + recipeData:SetSubRecipeCostsUsage(true) + recipeData:OptimizeSubRecipes() + printS("optimizedRecipes: " .. tostring(#recipeData.optimizedSubRecipes)) + end + --optimize top gear first cause optimized reagents might change depending on the gear if CraftSimOptions.recipeScanOptimizeProfessionTools then printS("Optimizing Gear...")