FANDOM


-- <pre>
local p = {}
local herbloreData = mw.loadData("Module:Sandbox/User:CephHunter/2")
local Exchange = require("Module:ExchangeLite").price
local Coins = require("Module:Currency short")._amount
local AddCommas = require("Module:Addcommas")._add
local StringTables = require("Module:StringTables")._stringTable
local XPAtLevel = mw.loadData("Module:Experience/data")
 
local colors = {
    ["gotLvl"] = "#33cc33", 
    ["willGetLvl"] = "#f9f906", 
    ["noLvl"] = "#f23b0d"
}
 
local memberIcon = {
    ["yes"] = "[[File:P2P icon.png|30px|link=Pay-to-play]]", 
    ["no"] = "[[File:F2P icon.png|30px|link=Free-to-play]]"
}
 
local BotanistOutfit = {
    ["0 (+0%)"] = 0,
    ["1 (+1%)"] = 0.01,
    ["2 (+2%)"] = 0.02,
    ["3 (+3%)"] = 0.03,
    ["4 (+4%)"] = 0.04,
    ["5 (+6%)"] = 0.06
}
 
local pulseCore = {
    ["+0%"] = 0,
    ["+2%"] = 0.02,
    ["+4%"] = 0.04,
    ["+6%"] = 0.06,
    ["+8%"] = 0.08,
    ["+10%"] = 0.1
}
 
local wisePerk = {
    ["0 (+0%)"] = 0,
    ["1 (+1%)"] = 0.01,
    ["2 (+2%)"] = 0.02,
    ["3 (+3%)"] = 0.03
}
 
local clanAvatar = {
    ["None (+0%)"] = 0,
    ["Same world (+3%)"] = 0.03,
    ["Within 10 steps (+6%)"] = 0.06
}
 
local category = {
    ["Herbs (Normal)"] = {
            {data = "herbs", itt = "herbsItt", calcType = "herb", name = "Herbs (Normal)"}
        },
    ["Herbs (Dungeoneering)"] = {
            {data = "dungeoneeringHerbs", itt = "dungeoneeringHerbsItt", calcType = "herb", name = "Herbs (Dungeoneering)"}
        },
    ["Herbs (Herblore Habitat)"] = {
            {data = "herbloreHabitatHerbs", itt = "herbloreHabitatHerbsItt", calcType = "herb", name = "Herbs (Herblore Habitat)"}
        },
    ["Herbs (All)"] = {
            {data = "herbs", itt = "herbsItt", calcType = "herb", name = "Herbs (Normal)"}, 
            {data = "dungeoneeringHerbs", itt = "dungeoneeringHerbsItt", calcType = "herb", name = "Herbs (Dungeoneering)"}, 
            {data = "herbloreHabitatHerbs", itt = "herbloreHabitatHerbsItt", calcType = "herb", name = "Herbs (Herblore Habitat)"}
        },
    ["Potions (Normal)"] = {
            {data = "potions", itt = "potionsItt", calcType = "potion", name = "Potions (Normal)"}
        },
    ["Potions (Barbarian)"] = {
            {data = "barbarianPotions", itt = "barbarianPotionsItt", calcType = "potion", name = "Potions (Barbarian)"}
        },
    ["Potions (Combination)"] = {
            {data = "combinationPotions", itt = "combinationPotionsItt", calcType = "potion", name = "Potions (Combination)"}
        },
    ["Potions (Herblore Habitat)"] = {
            {data = "jujuPotions", itt = "jujuPotionsItt", calcType = "potion", name = "Potions (Herblore Habitat)"}
        },
    ["Potions (Dungeoneering)"] = {
            {data = "dungeoneeringPotions", itt = "dungeoneeringPotionsItt", calcType = "potion", name = "Potions (Dungeoneering)"}
        },
    ["Potions (All)"] = {
            {data = "potions", itt = "potionsItt", calcType = "potion", name = "Potions (Normal)"},
            {data = "barbarianPotions", itt = "barbarianPotionsItt", calcType = "potion", name = "Potions (Barbarian)"},
            {data = "combinationPotions", itt = "combinationPotionsItt", calcType = "potion", name = "Potions (Combination)"},
            {data = "jujuPotions", itt = "jujuPotionsItt", calcType = "potion", name = "Potions (Herblore Habitat)"},
            {data = "dungeoneeringPotions", itt = "dungeoneeringPotionsItt", calcType = "potion", name = "Potions (Dungeoneering)"}
        },
    ["Show all"] = {
            {data = "herbs", itt = "herbsItt", calcType = "herb", name = "Herbs (Normal)"}, 
            {data = "dungeoneeringHerbs", itt = "dungeoneeringHerbsItt", calcType = "herb", name = "Herbs (Dungeoneering)"}, 
            {data = "herbloreHabitatHerbs", itt = "herbloreHabitatHerbsItt", calcType = "herb", name = "Herbs (Herblore Habitat)"},
            {data = "potions", itt = "potionsItt", calcType = "potion", name = "Potions (Normal)"},
            {data = "barbarianPotions", itt = "barbarianPotionsItt", calcType = "potion", name = "Potions (Barbarian)"},
            {data = "combinationPotions", itt = "combinationPotionsItt", calcType = "potion", name = "Potions (Combination)"},
            {data = "jujuPotions", itt = "jujuPotionsItt", calcType = "potion", name = "Potions (Herblore Habitat)"},
            {data = "dungeoneeringPotions", itt = "dungeoneeringPotionsItt", calcType = "potion", name = "Potions (Dungeoneering)"}
        }
}
 
--@str  =   string
local function toboolean(str)
    return (str == "true" or (tonumber(str) or  0) ~= 0 or str == true)
end
 
--@args     =   table
local function calcXpBoost(args)
    local multiplier = 1
    local multiplierPlusBXP = 1
 
    multiplier = multiplier + (BotanistOutfit[args.botanistPieces] or 0)
                            + (pulseCore[args.pulseCore] or 0)
                            + (wisePerk[args.wisePerk] or 0)
                            + (clanAvatar[args.clanAva] or 0)
                            + ((toboolean(args.panteonAura) and 0.1) or 0)
                            + ((toboolean(args.wisdomAura) and 0.025) or 0)
                            + ((toboolean(args.perfJuju) and 0.05) or 0)
 
    multiplier = multiplier * ((toboolean(args.portableWell) and 1.1) or 1)
 
    multiplier = (toboolean(args.customBoost) and args.customBoost) or multiplier
 
    return multiplier
end
 
--@current  =   integer
--@goal     =   integer
--@bxp      =   integer
local function calcXpLeft(current, goal, bxp)
    current = tonumber(current) or 1
    goal = tonumber(goal) or 2
    bxp = tonumber(bxp) or 0
    local currentXP = 0
    local currentLVL = 1
    local goalXP = 0
    local goalLVL = 2
 
    if (current >= 1 and current <= 120) then
        currentXP = XPAtLevel[current]
        currentLVL = current
    else
        currentXP = current
        for i = 120, 1, -1 do
            if (XPAtLevel[i] <= current) then
                currentLVL = i
                break
            end
        end
    end
 
    if (goal >= 1 and goal <= 120) then
        goalXP = XPAtLevel[goal]
        goalLVL = goal
    else
        goalXP = goal
        for i = 120, 1, -1 do
            if (XPAtLevel[i] <= goal) then
                goalLVL = i
                break
            end
        end
    end
 
    local diff = goalXP - currentXP
 
    -- Check if input is valid
    if (diff < 0) then
        return "error"
    end
 
    -- Substracts the correct amount of bxp
    local left = 0
    if (diff / 2 > bxp) then
        left = diff - bxp
    else
        left = diff / 2
    end
 
    return {diff = diff, left = left, currentLVL = currentLVL, goalLVL = goalLVL}
end
 
--@currentLVL   =   integer
--@goalLVL      =   integer
--@lvlToMake    =   integer
local function setLevelColor(currentLVL, goalLVL, lvlToMake)
    if (lvlToMake <= currentLVL) then
        return colors.gotLvl
    elseif (lvlToMake <= goalLVL) then
        return colors.willGetLvl
    else
        return colors.noLvl
    end
end
 
--@herbName     =   string
local function findHerbData(herbName)
    local herb = herbName:lower():gsub("clean ", ""):gsub("grimy ", "")
    local herbData = 
            herbloreData.herbs[herb] or 
            herbloreData.dungeoneeringHerbs[herb] or 
            herbloreData.herbloreHabitatHerbs[herb]
 
    return herbData
end
 
--@nmbr     =   float
--@digits   =   integer
local function round(nmbr, digits)
    return math.floor(nmbr * 10 ^ digits + 0.5) / (10 ^ digits)
end
 
local knownPrices = {}
local function getPrice(item)
	if knownPrices[item] ~= nil then
		return knownPrices[item]
	else
		local price = Exchange(item)
		knownPrices[item] = price
		return price
	end
end
 
--@tbl  =   table
local function tableHeader(tbl)
    tbl.addClass = "wikitable sortable"
    table.insert(tbl, 
        {
            {tag = "th", text = "Level", css = {["min-width"] = "50px"}}, 
            {tag = "th", text = "Herb/Potion"},
            {tag = "th", text = "Category"},
            {tag = "th", text = "XP"},
            {tag = "th", text = "XP/h"},
            {tag = "th", text = "Actions left"},
            {tag = "th", text = "Estimated profit"},
            {tag = "th", text = "GP/XP"},
            {tag = "th", text = "GP/h"},
            {tag = "th", text = "Primary", attr = {class = "unsortable"}, css = {width = "75px"}},
            {tag = "th", text = "Secondary", attr = {class = "unsortable"}, css = {width = "75px"}},
            {tag = "th", text = "Extra info", attr = {class = "unsortable"}, css = {width = "80px"}}
        }
    )
end
 
--@tbl          =   table
--@data         =   table
--@itt          =   table
--@currentLVL   =   integer
--@goalLVL      =   integer
--@XPToTrain    =   integer
--@XPDiff       =   integer
--@xpBoost      =   float
--@args         =   table
local function herbCalc(tbl, data, itt, currentLVL, goalLVL, XPToTrain, XPDiff, xpBoost, args, catName)
    for _, herbName in ipairs(itt) do 
        local herbData = data[herbName]
 
    -- Give the Level cells the correct color
        local bgcolor = setLevelColor(currentLVL, goalLVL, herbData.lvl)
 
    -- Set some default values
        local xpPerAction = math.floor(round(herbData.xp * xpBoost, 2) * 10) / 10
        local xpPerActionText = xpPerAction .. ((toboolean(args.bonusXP) and ("<br />(" .. (xpPerAction * 2) .. ")")) or "")
        local actionsLeft = math.ceil(XPToTrain / xpPerAction)
        local priceGrimy = 0
        local priceClean = 0
        local profit = 0
        local profitText = "N/A"
        local NAClass = "table-na"
        local NAAlign = "center"
        local GPPerXP = 0
        local GPPerXPText = "N/A"
        local extraInfo = "N/A"
        local timePerInv = herbData.timePerInv + tonumber(args.bankTime or 0)
        local invPerHour = 3600 / timePerInv
        local XPPerHour = round(xpPerAction * herbData.itemsPerInv * invPerHour, 0)
		local XPPerHourText = AddCommas(XPPerHour) .. ((toboolean(args.bonusXP) and ("<br />(" .. AddCommas(XPPerHour * 2) .. ")")) or "")
        local GPPerHour = 0
        local GPPerHourText = "N/A"
        local usePreciseVal = toboolean(args.usePreciseVal or false)
 
    -- Calc monetary values
        if (herbData.tradeable) then
            priceGrimy = getPrice(herbData.grimy.link)
            priceClean = getPrice(herbData.clean.link)
            profit = (priceClean - priceGrimy) * actionsLeft
            profitText = Coins(profit, "coins", usePreciseVal)
            NAClass = "none"
            NAAlign = nil
            GPPerXP = profit / XPDiff
            GPPerXPText = Coins(GPPerXP, "coins", true)
            GPPerHour = (priceClean - priceGrimy) * herbData.itemsPerInv * invPerHour
            GPPerHourText = Coins(GPPerHour, "coins", usePreciseVal)
 
        -- Create the extra info table
            local extraInfoInnerTbl = 
                {
                    addClass = "calc-extra-info",
                    css = {float = "right", display = "inline-table", position = "relative", border = "solid 1px #cccccc", ["background-color"] = "#f2f2f2", ["text-align"] = "initial"},
                    {
                        {
                            tag = "th", 
                            text = "Herb",
                            css = {border = "none"}
                        },
                        {
                            tag = "th", 
                            text = "Price",
                            css = {border = "none"}
                        }
                    },
                    {
                        {
                            text = "[[File:" .. herbData.grimy.image .. "]] [[" .. herbData.grimy.link .. "]]",
                            css = {border = "none"}
                        },
                        {
                            text = Coins(-priceGrimy, "coins", usePreciseVal),
                            css = {border = "none", ["text-align"] = "right"}
                        }
                    },
                    {
                        {
                            text = "[[File:" .. herbData.clean.image .. "]] [[" .. herbData.clean.link .. "]]",
                            css = {border = "none"}
                        },
                        {
                            text = Coins(priceClean, "coins", usePreciseVal),
                            css = {border = "none", ["text-align"] = "right"}
                        }
                    },
                    {
                        {
                            tag = "th", 
                            text = "Total",
                            css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0", ["padding-bottom"] = "10px"}
                        },
                        {
                            text = Coins(priceClean - priceGrimy, "coins", usePreciseVal),
                            css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0", ["padding-bottom"] = "10px", ["text-align"] = "right"}
                        }
                    },
                    {
                        {
                            tag = "th",
                            text = "Time per inv",
                            css = {border = "double #aaa", ["border-width"] = "3px 0 0 0"}
                        },
                        {
                            text = timePerInv .. "s",
                            css = {border = "double #aaa", ["border-width"] = "3px 0 0 0", ["text-align"] = "right"}
                        }
                    },
                    {
                        {
                            tag = "th",
                            text = "Inv per hour",
                            css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0"}
                        },
                        {
                            text = AddCommas(round(invPerHour, 1)),
                            css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0", ["text-align"] = "right"}
                        }
                    }
                }
 
            local extraInfoOuterTbl = 
                {
                    addClass = "mw-collapsible mw-collapsed",
                    css = {["min-width"] = "0px", float = "right", ["border-collapse"] = collapse},
                    {
                        {
                            text = "", 
                            css = {border = "none"}
                        }
                    },
                    {
                        {
                            text = StringTables(extraInfoInnerTbl),
                            css = {border = "none", ["max-width"] = "0px", ["white-space"] = "nowrap", overflow = "visible"}
                        }
                    }
                }
 
            extraInfo = StringTables(extraInfoOuterTbl)
        end
 
    -- Add a row to the calculators result table
        table.insert(tbl, 
            {
                {   --Level column
                    text = memberIcon[herbData.member] .. " " .. herbData.lvl,
                    css = {["background-color"] = bgcolor},
                    attr = {["data-sort-value"] = herbData.lvl}
                },
                {   --Herb/Potion column
                    text = "[[File:" .. herbData.clean.image .. "]] [[" .. herbData.clean.link .. "]]",
                    attr = {["data-sort-value"] = herbData.clean.link}
                },
                {   --Category column
                    text = catName
                },
                {   --XP per action column
                    text = xpPerActionText,
                    attr = {["data-sort-value"] = xpPerAction},
                    css = {["text-align"] = "right"}
                },
                {   --XP per hour column
                    text = XPPerHourText,
                    attr = {["data-sort-value"] = XPPerHour},
                    css = {["text-align"] = "right"}
                },
                {   --Actions left column
                    text = AddCommas(actionsLeft),
                    css = {["text-align"] = "right"}
                },
                {   --Estimated profit column
                    text = profitText,
                    attr = {["data-sort-value"] = profit, class = NAClass},
                    css = {["text-align"] = (NAAlign or "right")}
                },
                {   --GP/XP column
                    text = GPPerXPText,
                    attr = {["data-sort-value"] = GPPerXP, class = NAClass},
                    css = {["text-align"] = (NAAlign or "right")}
                },
                {   --GP/h column
                    text = GPPerHourText,
                    attr = {["data-sort-value"] = GPPerHour, class = NAClass},
                    css = {["text-align"] = (NAAlign or "right")}
                },
                {   --Primary column
                    text = "[[File:" .. herbData.grimy.image .. "|link=" .. herbData.grimy.link .. "]]",
                    css = {["text-align"] = "center"}
                },
                {   --Secondary column
                    text = "N/A",
                    attr = {class = "table-na"},
                    css = {["text-align"] = "center"}
                },
                {   --Extra info column
                    text = extraInfo,
                    attr = {class = NAClass},
                    css = {["text-align"] = "center", ["vertical-align"] = (NAAlign or "top")}
                }
            }
        )
    end
end
 
--@tbl              =   table
--@data             =   table
--@itt              =   table
--@currentLVL       =   integer
--@goalLVL          =   integer
--@XPToTrain        =   integer
--@XPDiff           =   integer
--@xpBoost          =   float
--@args             =   table
--@useUnfPotions    =   boolean
--@useGrimyHerbs    =   boolean
local pricePrimary = {0, 0, 0, 0, 0, 0, 0}      -- Pre create the tables and reuse them for fater performance
local priceSecondary = {0, 0, 0, 0, 0, 0, 0}
local function potionCalc(tbl, data, itt, currentLVL, goalLVL, XPToTrain, XPDiff, xpBoost, args, useUnfPotions, useGrimyHerbs, catName)
    for _, potionName in ipairs(itt) do
        local potionData = data[potionName]
 
    -- Give the Level cells the correct color
        local bgcolor = setLevelColor(currentLVL, goalLVL, potionData.lvl)
 
    -- Set some default values
        local xpPerAction = potionData.xp
        local actionsLeft = 0
        local pricePotion = 0
        local profitOnePot = 0
        local profit = 0
        local profitText = "N/A"
        local GPPerXP = 0
        local GPPerXPText = "N/A"
        local extraInfo = "N/A"
        local primaryList = ""
        local secondaryList = ""
        local timePerInv = potionData.timePerInv + tonumber(args.bankTime or 0) * (potionData.banksPerInv or 1)     -- Minimum time
        local invPerHour = 0
        local XPPerHour = 0
		local XPPerHourText = ""
        local GPPerHour = 0
        local GPPerHourText = "N/A"
        local usePreciseVal = toboolean(args.usePreciseVal or false)
        local primaryOrUnfinished = (useUnfPotions and potionData.unfinished) or potionData.primary
 
    -- Calc time per inventory and xpPerAction
        -- Add time to add clean herbs to vials of water
        if (not useUnfPotions and potionData.primary[1].link ~= potionData.unfinished[1].link) then
            timePerInv = timePerInv * 2
            xpPerAction = xpPerAction + 1
        end
 
        if (useGrimyHerbs) then
            -- Add herb cleaning xp and time for the primary components
            for _, item in ipairs(primaryOrUnfinished) do
                local herbData = findHerbData(item.link)
                if herbData ~= nil then
                    -- Remove the effect of the portabel well as herb xp is not affected by it
                    xpPerAction = xpPerAction + (herbData.xp or 0) / ((toboolean(args.portableWell) and 1.1) or 1)
                    timePerInv = timePerInv + potionData.itemsPerInv / herbData.itemsPerInv * (herbData.timePerInv + tonumber(args.bankTime or 0))
                end
            end
 
            -- Add herb cleaning xp and time for the secondary components
            for _, item in ipairs(potionData.secondary) do
                local herbData = findHerbData(item.link)
                if herbData ~= nil then
                    -- Remove the effect of the portabel well as herb xp is not affected by it
                    xpPerAction = xpPerAction + (herbData.xp or 0) / ((toboolean(args.portableWell) and 1.1) or 1)
                    timePerInv = timePerInv + potionData.itemsPerInv / herbData.itemsPerInv * (herbData.timePerInv + tonumber(args.bankTime or 0))
                end
            end
        end
 
        -- Calc some values
        invPerHour = 3600 / timePerInv
        xpPerAction = math.floor(round(xpPerAction * xpBoost, 2) * 10) / 10
        xpPerActionText = AddCommas(xpPerAction) .. ((toboolean(args.bonusXP) and ("<br />(" .. AddCommas(xpPerAction * 2) .. ")")) or "")
        actionsLeft = math.ceil(XPToTrain / xpPerAction)
        XPPerHour = round(xpPerAction * potionData.itemsPerInv * invPerHour, 0)
		XPPerHourText = AddCommas(XPPerHour) .. ((toboolean(args.bonusXP) and ("<br />(" .. AddCommas(XPPerHour * 2) .. ")")) or "")
 
    -- Set the prices of the components and calc profitOnePot
    -- table of individual prices is needed for the "extra info" cell
        if (potionData.tradeable) then
            pricePotion = getPrice(potionData.GEname) * (potionData.output or 1) * ((toboolean(args.portableWell or false) and 1.05) or 1)
            profitOnePot = profitOnePot + pricePotion
        end
 
        for key, item in ipairs(primaryOrUnfinished) do
            if (item.tradeable) then
                -- Change the item name to grimy herb if necessary
                local itemName = item.GEname or item.link
                if (useGrimyHerbs) then
                    itemName = itemName:gsub("Clean", "Grimy")
                end
 
                -- Get item price and add it to the total potion price
                local compPrice = getPrice(itemName) * (item.amount or 1)
                pricePrimary[key] = -compPrice
                profitOnePot = profitOnePot - compPrice
            else
                pricePrimary[key] = 0
            end
        end
 
        for key, sec in ipairs(potionData.secondary) do
            if (sec.tradeable) then
                -- Change the item name to grimy herb if necessary
                local itemName = sec.GEname or sec.link
                if (useGrimyHerbs) then
                    itemName = itemName:gsub("Clean", "Grimy")
                end
 
                -- Get item price and add it to the total potion price
                local compPrice = getPrice(itemName) * (sec.amount or 1) * ((toboolean(args.scrollOfCleansing or false) and 0.9) or 1)
                priceSecondary[key] = -compPrice
                profitOnePot = profitOnePot - compPrice
            else
                priceSecondary[key] = 0
            end
        end
 
    -- Calc some other values
        profit = profitOnePot * actionsLeft
        profitText = Coins(profit, "coins", usePreciseVal)
        GPPerXP = profit / XPDiff
        GPPerXPText = Coins(GPPerXP, "coins", true)
        GPPerHour = profitOnePot * potionData.itemsPerInv * invPerHour
        GPPerHourText = Coins(GPPerHour, "coins", usePreciseVal)
 
    -- Create the "primary" cell value
        for _, item in ipairs(primaryOrUnfinished) do
            primaryList = primaryList .. "[[File:" .. item.image .. "|link=" .. item.link .. "]] "
        end
 
    -- Create the "secondary" cell value
        for _, sec in ipairs(potionData.secondary) do
            secondaryList = secondaryList .. "[[File:" .. sec.image .. "|link=" .. sec.link .. "]] "
        end
 
    -- Create the "extra info" table
 
        -- Create an array with the info to make the extraInfoTbl
        local extraInfoInnerTbl = {
            addClass = "calc-extra-info",
            css = {float = "right", display = "inline-table", position = "relative", border = "solid 1px #cccccc", ["background-color"] = "#f2f2f2", ["text-aling"] = "initial"}
        }
 
            -- Add a header to the table
        table.insert(extraInfoInnerTbl,
            {
                {
                    tag = "th", 
                    text = "Item",
                    css = {border = "none"}
                },
                {
                    tag = "th", 
                    text = "<span title='Amount used to make one potion'>x</span>",
                    css = {border = "none"}
                },
                {
                    tag = "th", 
                    text = "Price",
                    css = {border = "none"}
                }
            }
        )
 
        for key, item in ipairs((useUnfPotions and potionData.unfinished) or potionData.primary) do
            -- Change the item name to grimy herb if necessary
            local itemName = item.link
            local itemImage = item.image
            if (useGrimyHerbs) then
                itemName = itemName:gsub("Clean", "Grimy")
                itemImage = itemImage:gsub("Clean", "Grimy")
            end
 
            -- Add a row to the extraInfoInnerTbl
            table.insert(extraInfoInnerTbl,
                {
                    {
                        text = "[[File:" .. itemImage .. "]] [[" .. itemName .. "]]",
                        css = {border = "none"}
                    },
                    {
                        text = "x" .. (item.amount or 1),
                        css = {border = "none"}
                    },
                    {
                        text = Coins(pricePrimary[key], "coins", usePreciseVal),
                        css = {border = "none", ["text-align"] = "right"}
                    }
                }
            )
        end
 
        for key, sec in ipairs(potionData.secondary) do
            -- Change the item name to grimy herb if necessary
            local itemName = sec.link
            local itemImage = sec.image
            if (useGrimyHerbs) then
                itemName = itemName:gsub("Clean", "Grimy")
                itemImage = itemImage:gsub("Clean", "Grimy")
            end
 
            -- Add a row to the extraInfoInnerTbl
            table.insert(extraInfoInnerTbl,
                {
                    {
                        text = "[[File:" .. itemImage .. "]] [[" .. itemName .. "]]",
                        css = {border = "none"}
                    },
                    {
                        text = "x" .. ((sec.amount or 1) * ((toboolean(args.scrollOfCleansing or false) and 0.9) or 1)),
                        css = {border = "none"}
                    },
                    {
                        text = Coins(priceSecondary[key], "coins", usePreciseVal),
                        css = {border = "none", ["text-align"] = "right"}
                    }
                }
            )
        end
 
        table.insert(extraInfoInnerTbl,
            {
                {
                    text = "[[File:" .. potionData.image .. "]] [[" .. potionData.link .. "]]",
                    css = {border = "none"}
                },
                {
                    text = "x" .. ((potionData.output or 1) * ((toboolean(args.portableWell or false) and 1.05) or 1)),
                    css = {border = "none"}
                },
                {
                    text = Coins(pricePotion, "coins", usePreciseVal),
                    css = {border = "none", ["text-align"] = "right"}
                }
            }
        )
 
        table.insert(extraInfoInnerTbl,
            {
                {
                    tag = "th", 
                    text = "Total",
                    css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0", ["padding-bottom"] = "10px"},
                    attr = {colspan = "2"}
                },
                {
                    text = Coins(profitOnePot, "coins", usePreciseVal),
                    css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0", ["padding-bottom"] = "10px", ["text-align"] = "right"}
                }
            }
        )
 
        table.insert(extraInfoInnerTbl,
            {
                {
                    tag = "th", 
                    text = "Time per inv",
                    css = {border = "double #aaa", ["border-width"] = "3px 0 0 0"},
                    attr = {colspan = "2"}
                },
                {
                    text = timePerInv .. "s",
                    css = {border = "double #aaa", ["border-width"] = "3px 0 0 0", ["text-align"] = "right"}
                }
            }
        )
 
        table.insert(extraInfoInnerTbl,
            {
                {
                    tag = "th", 
                    text = "Inv per hour",
                    css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0"},
                    attr = {colspan = "2"}
                },
                {
                    text = AddCommas(round(invPerHour, 1)),
                    css = {border = "solid #aaa", ["border-width"] = "1px 0 0 0", ["text-align"] = "right"}
                }
            }
        )
 
 
        -- Create the "extra info" table
        local extraInfoOuterTbl = 
            {
                addClass = "mw-collapsible mw-collapsed",
                css = {["min-width"] = "0px", float = "right", ["border-collapse"] = collapse},
                {
                    {
                        text = "", 
                        css = {border = "none"}
                    }
                },
                {
                    {
                        text = StringTables(extraInfoInnerTbl),
                        css = {border = "none", ["max-width"] = "0px", ["white-space"] = "nowrap", overflow = "visible"}
                    }
                }
            }
 
        extraInfo = StringTables(extraInfoOuterTbl)
 
    -- Add a row to the calculators result table
        table.insert(tbl,
            {
                {   --Level column
                    text = memberIcon[potionData.member] .. " " .. potionData.lvl,
                    css = {["background-color"] = bgcolor},
                    attr = {["data-sort-value"] = potionData.lvl}
                },
                {   --Herb/Potion column
                    text = "[[File:" .. potionData.image .. "]] [[" .. potionData.link .. "]]",
                    attr = {["data-sort-value"] = potionData.link}
                },
                {   --Category column
                    text = catName
                },
                {   --XP per action column
                    text = xpPerActionText,
                    attr = {["data-sort-value"] = xpPerAction},
                    css = {["text-align"] = "right"}
                },
                {   --XP per hour column
                    text = XPPerHourText,
                    attr = {["data-sort-value"] = XPPerHour},
                    css = {["text-align"] = "right"}
                },
                {   --Actions left column
                    text = AddCommas(actionsLeft),
                    css = {["text-align"] = "right"}
                },
                {   --Estimated profit column
                    text = profitText,
                    attr = {["data-sort-value"] = profit},
                    css = {["text-align"] = "right"}
                },
                {   --GP/XP column
                    text = GPPerXPText,
                    attr = {["data-sort-value"] = GPPerXP},
                    css = {["text-align"] = "right"}
                },
                {   --GP/h column
                    text = GPPerHourText,
                    attr = {["data-sort-value"] = GPPerHour},
                    css = {["text-align"] = "right"}
                },
                {   --Primary column
                    text = primaryList,
                    css = {["text-align"] = "center"}
                },
                {   --Secondary column
                    text = secondaryList,
                    css = {["text-align"] = "center"}
                },
                {   --Extra info column
                    text = extraInfo,
                    css = {["vertical-align"] = "top"}
                }
            }
        )
    end
end
 
function p.main(frame)
    local args = frame:getParent().args
    --local args = frame
    local resTbltArr = {}
    local result = ""
    local xpBoost = calcXpBoost(args)
 
    local xpCalc = calcXpLeft(args.currentHerbXP, args.goalHerbXP, args.bonusXP)
        if (xpCalc == "error") then
            return "<span style='color:red;'><strong>Error: The given goal xp is smaller than your current xp.</strong></span>"
        end
    result = "You have " .. AddCommas(xpCalc.diff) .. " XP left to train.<br />Current XP multiplier = " .. xpBoost .. "<br />"
 
    -- Create table header
    tableHeader(resTbltArr)
 
    -- Make the body of the calculator
    for _, j in ipairs(category[args.category] or {}) do
        if (j.calcType == "herb") then
            herbCalc(resTbltArr, herbloreData[j.data], herbloreData[j.itt], xpCalc.currentLVL, xpCalc.goalLVL, xpCalc.left, xpCalc.diff, xpBoost, args, j.name)
        elseif (j.calcType == "potion") then
            potionCalc(resTbltArr, herbloreData[j.data], herbloreData[j.itt], xpCalc.currentLVL, xpCalc.goalLVL, xpCalc.left, xpCalc.diff, xpBoost, args, toboolean(args.unfPotions), toboolean(args.useGrimyHerbs), j.name)
        end
    end
 
    result = result .. StringTables(resTbltArr)
    return result
end
 
-- local starttime = 0
-- function timestart()
    -- starttime = os.clock()
-- end
 
-- function timestop(str)
    -- local dif = os.clock() - starttime
    -- if dif > 0.000 then
        -- mw.log(((str and str .. "\n") or "") .. "Diff: " .. dif .. "\n-----------")
    -- end
-- end
 
return p

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.