local function length_of(coll) if coll then local c = 0 for k in pairs(coll) do c = (c + 1) end return c else return 0 end end local function first(coll) local key = next(coll) return coll[key] end local function starts_with(s, patt) return (string.sub(s, 1, string.len(patt)) == patt) end local function un_quote(s) return string.gsub(s, "'", "") end local function max(a, b) if (a > b) then return a else return b end end local function matches(a, b) if starts_with(a, "lte:") then return (tonumber(string.sub(a, 5)) >= tonumber(b)) elseif starts_with(a, "gte:") then return (tonumber(string.sub(a, 5)) <= tonumber(b)) else return (a == b) end end local function find_items(params, _3fsort) _G.assert((nil ~= params), "Missing argument params on main.fnl:42") local results do local tbl_17_auto = {} local i_18_auto = #tbl_17_auto for _, row in ipairs(items) do local val_19_auto do local hit = true for key, param in pairs(params) do hit = (hit and matches(param, row[key])) end if hit then val_19_auto = row else val_19_auto = nil end end if (nil ~= val_19_auto) then i_18_auto = (i_18_auto + 1) do end (tbl_17_auto)[i_18_auto] = val_19_auto else end end results = tbl_17_auto end if (_3fsort and results) then table.sort(results, _3fsort) return results else return results end end local function find_item(params, _3fsort) _G.assert((nil ~= params), "Missing argument params on main.fnl:57") local results = find_items(params, _3fsort) if results then return first(results) else return nil end end local function find_item_by_name(name) return find_item({[8] = name}) end local function find_next_better_item(class, subclass, invtype, lv, ilv, stat_position, item_stat, _3fsort) return find_items({[4] = class, [6] = subclass, [10] = invtype, [14] = string.format("lte:%d", lv), [stat_position] = string.format("gte:%d", item_stat)}, _3fsort) end local function find_good_item(invtype, lv, stat_position, stat_baseline, _3fsort) _G.assert((nil ~= stat_baseline), "Missing argument stat-baseline on main.fnl:77") _G.assert((nil ~= stat_position), "Missing argument stat-position on main.fnl:77") _G.assert((nil ~= lv), "Missing argument lv on main.fnl:77") _G.assert((nil ~= invtype), "Missing argument invtype on main.fnl:77") return find_items({[10] = invtype, [14] = string.format("lte:%d", lv), [stat_position] = string.format("gte:%d", stat_baseline)}, _3fsort) end local function parse_opts(msg) local tbl_17_auto = {} local i_18_auto = #tbl_17_auto for k, v in string.gmatch(msg, "%w+") do local val_19_auto = v if (nil ~= val_19_auto) then i_18_auto = (i_18_auto + 1) do end (tbl_17_auto)[i_18_auto] = val_19_auto else end end return tbl_17_auto end local function ui_print(msg) return UIErrorsFrame:AddMessage(msg) end local function stat_name(n) local stat_names = {"Mana", "Health", "No Visible Effect", "Agility", "Strength", "Intellect", "Spirit", "Stamina", "No Visible Effect", "No Visible Effect", "No Visible Effect", "No Visible Effect*", "Defense Rating", "Dodge", "Parry Rating", "Shield Block Rating", "Melee Hit Rating", "Ranged Hit Rating", "Spell Hit Rating", "Melee Critical Strike", "Ranged Critical Strike", "Spell Critical Strike", "Melee Hit Avoidance", "Ranged Hit Avoidance", "Spell Hit Avoidance", "Melee Critical Avoidance", "Spell Critical Avoidance", "Melee Haste Rating", "Ranged Haste Rating", "Spell Haste Rating", "Hit Avoidance Rating", "Hit Rating", "Critical Strike", "Hit Avoidance Rating", "Critical Avoidance Rating", "Resilience", "Haste", "Expertise", "Attack Power", "Ranged Attack Power", "No Visible Effect", "Healing Done By Magical Spells and Effects up to value", "Damage Done By Magical Spells and Effects up to value", "Mana Regeneration (Ticks every 5 seconds)", "Armor Penetration Rating", "Spell Power", "Health Regeneration (Ticks every 5 seconds)", "Spell Penetration", "Block Value of Shield", "Mastery", "Armor", "Fire Resist", "Frost Resist", "Shadow Resist", "Nature Resist", "Arcane Resist"} return (stat_names[(n + 1)] .. " (" .. n .. ")") end local function stat_print(item) local val = "" for n = 22, 56 do if (0 < item[n]) then val = (val .. " " .. stat_name((n - 21)) .. ": " .. item[n]) else end end return val end local function main0(msg) local opts do local tbl_17_auto = {} local i_18_auto = #tbl_17_auto for v in string.gmatch(msg, "%w+") do local val_19_auto = v if (nil ~= val_19_auto) then i_18_auto = (i_18_auto + 1) do end (tbl_17_auto)[i_18_auto] = val_19_auto else end end opts = tbl_17_auto end local _let_11_ = opts local slot = _let_11_[1] local stat = _let_11_[2] local gear_index = _let_11_[3] local slot0 = (slot .. "Slot") local stat0 = (21 + tonumber(stat)) local gear_index0 = tonumber((gear_index or "1")) local inv_slot = GetInventorySlotInfo(slot0) local i_link = GetInventoryItemLink("player", inv_slot) local p_level = UnitLevel("player") if not i_link then local best local function _12_(a, b) return ((a[stat0] < b[stat0]) and (a[12] < b[12])) end best = (find_good_item(inv_slot, UnitLevel("player"), stat0, 1, _12_))[gear_index0] if best then DEFAULT_CHAT_FRAME:AddMessage(string.format("|Hitem:%d:0:0:0:0:0:0:0:0|h[%s]|h|r", best[2], best[8])) return ui_print(("next best available: " .. best[8] .. " " .. stat_print(best) .. " at " .. best[20] .. "N/A")) else return nil end else local i_name = GetItemInfo(i_link) local stats = find_item_by_name(un_quote(i_name)) if stats then local i_class = stats[4] local i_subclass = stats[6] local i_invtype = stats[10] local i_level = stats[12] local i_stat = stats[stat0] local best local function _14_(a, b) return (a[stat0] < b[stat0]) end best = (find_next_better_item(i_class, i_subclass, i_invtype, p_level, i_level, stat0, max(i_stat, 1), _14_))[gear_index0] if best then DEFAULT_CHAT_FRAME:AddMessage(string.format("|Hitem:%d:0:0:0:0:0:0:0:0|h[%s]|h|r", best[2], best[8])) ui_print(("next best available: " .. best[8] .. " " .. stat_print(best) .. " at " .. best[20] .. "N/A")) ui_print(("currently equipped " .. i_name .. " " .. (stats[stat0] or "N/A"))) else end else end return "ok" end end main = main0 local function maxxed() local slots = {"AmmoSlot", "BackSlot", "Bag0Slot", "Bag1Slot", "Bag2Slot", "Bag3Slot", "ChestSlot", "FeetSlot", "Finger0Slot", "Finger1Slot", "HandsSlot", "HeadSlot", "LegsSlot", "MainHandSlot", "NeckSlot", "RangedSlot", "SecondaryHandSlot", "ShirtSlot", "ShoulderSlot", "TabardSlot", "Trinket0Slot", "Trinket1Slot", "WaistSlot", "WristSlot"} return slots end return maxxed