Now does somewhat arbitrary sorting in the Provisioning Window

Wobin [05-12-14 - 11:45]
Now does somewhat arbitrary sorting in the Provisioning Window
Colours recipes according to quality
Filename
Provisioning.lua
SousChef.lua
diff --git a/Provisioning.lua b/Provisioning.lua
index 312f5c6..d600c2e 100644
--- a/Provisioning.lua
+++ b/Provisioning.lua
@@ -57,7 +57,7 @@ function SousChef:HookRecipeTreeFunction()
             function(...)
                 local node, control, data, open, userRequested, enabled = ...
                 SousChef.hookedProvisioningFunction(...)
-                local link = GetRecipeResultItemLink(data.recipeListIndex, SousChef.recipeLookup[data.recipeListIndex][data.recipeIndex], LINK_STYLE_BRACKETS)
+                local link = GetRecipeResultItemLink(data.recipeListIndex, data.recipeIndex, LINK_STYLE_BRACKETS)
                 if link then
                     SousChef:AddNotifier(control, SousChef.settings.shoppingList[zo_strformat(SI_TOOLTIP_ITEM_NAME, link)])
                 end
@@ -122,48 +122,130 @@ function SousChef:UnhookRecipeTree()
 end

 function SousChef:HookGetRecipeInfo()
-    SousChef.GetRecipeInfo = GetRecipeInfo
-    GetRecipeInfo =
-        function(recipeListIndex, recipeIndex)
-            local val = SousChef.recipeIndex[recipeListIndex][recipeIndex]
-            return val.known, val.name, val.ingredients, val.levelReq, val.quality, val.specialIngType
+    SousChef.OldRefreshRecipeTree = ZO_Provisioner.RefreshRecipeTree
+    ZO_Provisioner.RefreshRecipeTree =
+        function()
+            return SousChef.RefreshRecipeTree(PROVISIONER)
         end

-    SousChef.GetSelectedRecipeIndex = PROVISIONER.GetSelectedRecipeIndex
-    PROVISIONER.GetSelectedRecipeIndex =
-        function()
-            return SousChef.recipeLookup[PROVISIONER:GetSelectedRecipeListIndex()][SousChef.GetSelectedRecipeIndex(PROVISIONER)]
+    SousChef.OldZO_ProvisionerRow_GetTextColor = ZO_ProvisionerRow_GetTextColor
+    ZO_ProvisionerRow_GetTextColor =
+        function(self)
+            return SousChef.ZO_ProvisionerRow_GetTextColor(self)
         end
 end

 local function SortRecipe(a, b)
-    if a.levelReq == b.levelReq then
-        if a.quality == b.quality then
+    if a.provisionerLevelReq == b.provisionerLevelReq then
+        if a.qualityReq == b.qualityReq then
             if a.name == b.name then
-                return a.index < b.index
+                return a.recipeIndex < b.recipeIndex
             end
             return a.name < b.name
         end
-        return a.quality < b.quality
+        return a.qualityReq < b.qualityReq
     end
-    return a.levelReq < b.levelReq
+    return a.provisionerLevelReq < b.provisionerLevelReq
 end

-function SousChef:ResortRecipes()
-    SousChef.recipeIndex = {}
-    SousChef.recipeLookup = {}
+local function CalculateHowManyCouldBeCreated(recipeListIndex, recipeIndex, numIngredients)
+    local minCount
+
+    for ingredientIndex = 1, numIngredients do
+        local _, _, requiredQuantity = GetRecipeIngredientItemInfo(recipeListIndex, recipeIndex, ingredientIndex)
+        local ingredientCount = GetCurrentRecipeIngredientCount(recipeListIndex, recipeIndex, ingredientIndex)
+
+        minCount = zo_min(zo_floor(ingredientCount / requiredQuantity), minCount or math.huge)
+        if minCount == 0 then
+            return 0
+        end
+    end
+
+    return minCount or 0
+end

+-- This is an almost direct clone of the existing function
+-- Except for two parts.
+-- 1) Storing the parent in the data (for each category of recipe)
+-- 2) Putting them all in a table first, then sorting, then adding them to the tree
+function SousChef:RefreshRecipeTree()
+    self.dirty = false
+
+    self.recipeTree:Reset()
+
+    local hasAnyRecipes = false
+    local RecipeLines = {}
     for recipeListIndex = 1, GetNumRecipeLists() do
-        local recipeListName, numRecipes = GetRecipeListInfo(recipeListIndex)
-        SousChef.recipeIndex[recipeListIndex] = {}
-        SousChef.recipeLookup[recipeListIndex] = {}
+        local recipeListName, numRecipes, upIcon, downIcon, overIcon, disabledIcon, createSound = GetRecipeListInfo(recipeListIndex)
+        local parent
+
         for recipeIndex = 1, numRecipes do
-            local known, recipeName, numIngredients, provisionerLevelReq, qualityReq, specialIngredientType = SousChef.GetRecipeInfo(recipeListIndex, recipeIndex)
-            table.insert(SousChef.recipeIndex[recipeListIndex], {index = recipeIndex, known = known, name = recipeName, ingredients = numIngredients, levelReq = provisionerLevelReq, quality = qualityReq, specialIngType = specialIngredientType})
-        end
-        table.sort(SousChef.recipeIndex[recipeListIndex], SortRecipe)
-        for i,v in ipairs(SousChef.recipeIndex[recipeListIndex]) do
-            SousChef.recipeLookup[recipeListIndex][i] = v.index
+            local known, recipeName, numIngredients, provisionerLevelReq, qualityReq, specialIngredientType = GetRecipeInfo(recipeListIndex, recipeIndex)
+            if known then
+                local numCreatable = CalculateHowManyCouldBeCreated(recipeListIndex, recipeIndex, numIngredients)
+                if self:DoesRecipePassFilter(specialIngredientType, numCreatable, provisionerLevelReq, qualityReq) then
+                    parent = parent or self.recipeTree:AddNode("ZO_IconHeader", { recipeListIndex = recipeListIndex, name = recipeListName, upIcon = upIcon, downIcon = downIcon, overIcon = overIcon, disabledIcon = disabledIcon }, nil, SOUNDS.PROVISIONING_BLADE_SELECTED)
+                    local data = {
+                        recipeListIndex = recipeListIndex,
+                        recipeIndex = recipeIndex,
+
+                        name = recipeName,
+                        provisionerLevelReq = provisionerLevelReq,
+                        qualityReq = qualityReq,
+                        specialIngredientType = specialIngredientType,
+                        numIngredients = numIngredients,
+                        numCreatable = numCreatable,
+                        createSound = createSound,
+                        parent = parent
+                    }
+
+                    table.insert(RecipeLines, data)
+                    hasAnyRecipes = true
+                end
+            end
         end
     end
+
+    table.sort(RecipeLines, SortRecipe)
+    for i,data in ipairs(RecipeLines) do
+        self.recipeTree:AddNode("ZO_ProvisionerNavigationEntry", data, data.parent, SOUNDS.PROVISIONING_ENTRY_SELECTED)
+    end
+
+    self.recipeTree:Commit()
+
+    self.noRecipesLabel:SetHidden(hasAnyRecipes)
+    if not hasAnyRecipes then
+        self:RefreshRecipeDetails()
+    end
+end
+
+local function Lighten(...)
+    r, g, b = ...
+    return r + 0.1, g + 0.1, b + 0.1
+end
+
+local function Lightest(...)
+    r, g, b = ...
+    return r + 0.3, g + 0.3, b + 0.3
+end
+
+function SousChef:ZO_ProvisionerRow_GetTextColor()
+    if not self.enabled then return GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_DISABLED) end
+
+    if self.selected then
+        if self.data.qualityReq > 1 then return Lightest(GetInterfaceColor(INTERFACE_COLOR_TYPE_ITEM_QUALITY_COLORS, self.data.qualityReq + 1)) end
+        return GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_SELECTED)
+    end
+
+    if self.mouseover then
+        if self.data.qualityReq > 1 then return Lighten(GetInterfaceColor(INTERFACE_COLOR_TYPE_ITEM_QUALITY_COLORS, self.data.qualityReq + 1)) end
+     return GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_HIGHLIGHT)
+    end
+
+    if self.meetsLevelReq and self.meetsQualityReq then
+        if self.data.qualityReq > 1 then return GetInterfaceColor(INTERFACE_COLOR_TYPE_ITEM_QUALITY_COLORS, self.data.qualityReq + 1) end
+        return GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_NORMAL)
+    end
+
+    return ZO_ERROR_COLOR:UnpackRGBA()
 end
\ No newline at end of file
diff --git a/SousChef.lua b/SousChef.lua
index e658704..f25efb4 100644
--- a/SousChef.lua
+++ b/SousChef.lua
@@ -49,15 +49,9 @@ local typeIconLookup = {
 function SousChef:ParseRecipes()
 	local lists = GetNumRecipeLists()

-	if SousChef.GetRecipeInfo then SousChef:ResortRecipes() end
-
 	for listIndex = 1, lists do
 		local name, count = GetRecipeListInfo(listIndex)
 		for recipeIndex = 1, count do
-
-			-- If we've already hooked, then use the new index
-			if SousChef.GetRecipeInfo then recipeIndex = SousChef.recipeLookup[listIndex][recipeIndex] end
-
 			if GetRecipeInfo(listIndex, recipeIndex) then
 				-- Store the recipes known
 				local recipeName = u.CleanString((GetRecipeResultItemInfo(listIndex, recipeIndex)))
@@ -248,8 +242,8 @@ local function SousChef_Loaded(eventCode, addOnName)
 	SLASH_COMMANDS['/scilist'] = SousChef.ListIgnoredRecipes

 	SousChef:UpdateProvisioningTable()
-
 	SousChef:HookGetRecipeInfo()
+
 	-- Now we want to hook into the function that sets the details on the inventory slot
 	zo_callLater(SousChef.HookEvents, 3000)
 end