|
|
(6 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| --Splitting some functions into here to avoid bloating a single file
| |
| --Contains function for skills that consume resources (ie smithing, cooking, herblore, etc.)
| |
| local p = {}
| |
|
| |
|
| local Shared = require('Module:Shared')
| |
| local Common = require('Module:Common')
| |
| local GameData = require('Module:GameData')
| |
| local SkillData = GameData.skillData
| |
| local Modifiers = require('Module:Modifiers')
| |
| local Skills = require('Module:Skills')
| |
| local Items = require('Module:Items')
| |
| local Icons = require('Module:Icons')
| |
| local ItemSourceTables = require('Module:Items/SourceTables')
| |
|
| |
| function p.getCookedItemsTable(frame)
| |
| local args = frame.args ~= nil and frame.args or frame
| |
| local category = args[1]
| |
| local realmName = args.realm
| |
| local realm = Skills.getRealmFromName(realmName)
| |
| if realm == nil then
| |
| return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil'))
| |
| end
| |
| local skillID = 'Cooking'
| |
|
| |
| local categoryMap = {
| |
| ["Cooking Fire"] = 'melvorD:Fire',
| |
| ["Furnace"] = 'melvorD:Furnace',
| |
| ["Pot"] = 'melvorD:Pot'
| |
| }
| |
| local categoryID = categoryMap[category]
| |
|
| |
| -- Find recipes for the relevant categories
| |
| -- Note: Excludes Lemon cake
| |
| local recipeArray = GameData.getEntities(SkillData.Cooking.recipes,
| |
| function(recipe)
| |
| return (
| |
| (categoryID == nil or recipe.categoryID == categoryID)
| |
| and recipe.noMastery == nil
| |
| and Skills.getRecipeRealm(recipe) == realm.id
| |
| )
| |
| end
| |
| )
| |
| table.sort(recipeArray, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end)
| |
|
| |
| -- Logic for generating some cells of the table which are consistent for normal & perfect items
| |
| local getHealingCell = function(item, qty)
| |
| if item ~= nil then
| |
| return 'data-sort-value="'..(math.floor(item.healsFor) * qty)..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..Shared.formatnum(math.floor(item.healsFor * 10))..(qty > 1 and ' (x'..qty..')' or '')
| |
| else
| |
| return ' '
| |
| end
| |
| end
| |
| local getSaleValueCell = function(item, qty)
| |
| if item ~= nil then
| |
| return 'data-sort-value="'..math.floor(item.sellsFor * qty)..'"|'..Items.getValueText(item)..(qty > 1 and ' (x'..qty..')' or '')
| |
| else
| |
| return ' '
| |
| end
| |
| end
| |
|
| |
| local resultPart = {}
| |
| table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
| |
| table.insert(resultPart, '\r\n|- class="headerRow-0"')
| |
| table.insert(resultPart, '\r\n!colspan="3" rowspan="2"|Cooked Item!!rowspan="2"|Requirements')
| |
| table.insert(resultPart, '!!rowspan="2"|Cook Time (s)!!rowspan="2"|XP!!rowspan="2"|XP/s!!colspan="2"|Healing!!colspan="2"|Value!!rowspan="2"|Ingredients')
| |
| table.insert(resultPart, '\r\n|- class="headerRow-1"')
| |
| table.insert(resultPart, '\r\n!Normal!!' .. Icons.Icon({'Perfect', type='bonus', ext='png', notext=true, nolink=true}))
| |
| table.insert(resultPart, '!!Normal!!' .. Icons.Icon({'Perfect', type='bonus', ext='png', notext=true, nolink=true}))
| |
|
| |
| for i, recipe in ipairs(recipeArray) do
| |
| local level = Skills.getRecipeLevel(skillID, recipe)
| |
| local baseXP = recipe.baseAbyssalExperience or recipe.baseExperience
| |
| local baseInt = recipe.baseInterval / 1000
| |
| local reqText = Skills.getRecipeRequirementText(SkillData.Cooking.name, recipe)
| |
| local xpRate = baseXP / baseInt
| |
| local item = Items.getItemByID(recipe.productID)
| |
| local perfectItem = nil
| |
| if recipe.perfectCookID ~= nil then
| |
| perfectItem = Items.getItemByID(recipe.perfectCookID)
| |
| end
| |
| local qty = recipe.baseQuantity or 1
| |
|
| |
| table.insert(resultPart, '\r\n|-')
| |
| table.insert(resultPart, '\r\n|class="table-img"|'..Icons.Icon({item.name, type='item', notext=true, size='50'}))
| |
| table.insert(resultPart, '\r\n|class="table-img"| ')
| |
| if perfectItem ~= nil then
| |
| table.insert(resultPart, Icons.Icon({perfectItem.name, type='item', notext=true, size='50'}))
| |
| end
| |
| table.insert(resultPart, '||')
| |
| if qty > 1 then
| |
| table.insert(resultPart, qty..'x ')
| |
| end
| |
| table.insert(resultPart, Icons.getExpansionIcon(item.id))
| |
| table.insert(resultPart, Icons.Icon({item.name, type='item', noicon = true}))
| |
| table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. level .. '"|' .. reqText)
| |
| table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. baseInt .. '"|' .. Shared.round(baseInt, 2, 0))
| |
| table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. baseXP .. '"|' .. Shared.formatnum(baseXP))
| |
| table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. xpRate .. '"|' .. Shared.formatnum(Shared.round(xpRate, 2, 0)))
| |
| table.insert(resultPart, '||'..getHealingCell(item, qty)..'||'..getHealingCell(perfectItem, qty))
| |
| table.insert(resultPart, '||'..getSaleValueCell(item, qty)..'||'..getSaleValueCell(perfectItem, qty))
| |
| local matArray = {}
| |
| for j, mat in ipairs(recipe.itemCosts) do
| |
| local matItem = Items.getItemByID(mat.id)
| |
| if matItem ~= nil then
| |
| table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.quantity}))
| |
| end
| |
| end
| |
| table.insert(resultPart, '\r\n|'..table.concat(matArray, ' '))
| |
| end
| |
|
| |
| table.insert(resultPart, '\r\n|}')
| |
| return table.concat(resultPart)
| |
| end
| |
|
| |
| local tierSuffix = { 'I', 'II', 'III', 'IV' }
| |
| function p._getPotionDescription(potion)
| |
| -- TODO: Temporary fix below for incorrect Traps Potion descriptions. To amend
| |
| -- once corrected within game data
| |
| if potion.customDescription and not Shared.contains(potion.id, 'melvorTotH:Traps_Potion_') then
| |
| return potion.customDescription
| |
| elseif type(potion.modifiers) == 'table' and not Shared.tableIsEmpty(potion.modifiers) then
| |
| return Modifiers.getModifiersText(potion.modifiers, false, true)
| |
| else
| |
| return ''
| |
| end
| |
| end
| |
|
| |
| function p._getHerblorePotionTable(categoryName)
| |
| local skillID = 'Herblore'
| |
| local category = GameData.getEntityByName(SkillData.Herblore.categories, categoryName)
| |
| if category == nil then
| |
| local catNames = {}
| |
| for i, cat in pairs(SkillData.Herblore.categories) do
| |
| table.insert(catNames, cat.name)
| |
| end
| |
| return Shared.printError('No such category ' .. categoryName .. ', the following are available: ' .. table.concat(catNames, ', '))
| |
| end
| |
| local categoryID = category.id
| |
|
| |
| local potionArray = GameData.getEntities(SkillData.Herblore.recipes,
| |
| function(potion)
| |
| -- Category implies a realm selection, so no ned to check this separately
| |
| return potion.categoryID == categoryID
| |
| end
| |
| )
| |
|
| |
| table.sort(potionArray, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end)
| |
|
| |
| local html = mw.html.create('table')
| |
| :addClass('wikitable sortable stickyHeader')
| |
|
| |
| html:tag('tr'):addClass('headerRow-0')
| |
| :tag('th'):wikitext('Potion')
| |
| :tag("th"):wikitext(Icons.Icon({'Herblore', type='skill', notext=true}) .. '<br>Level')
| |
| :tag('th'):wikitext('XP')
| |
| :tag('th'):wikitext('Ingredients')
| |
| :tag('th'):wikitext('Tier')
| |
| :css('width', '30px')
| |
| --:tag('th'):wikitext('Value')
| |
| :tag('th'):wikitext('Charges')
| |
| :tag('th'):wikitext('Effect')
| |
|
| |
| for i, potion in ipairs(potionArray) do
| |
| local level = Skills.getRecipeLevel(skillID, potion)
| |
| local baseXP = potion.baseAbyssalExperience or potion.baseExperience
| |
| local reqText = Skills.getRecipeRequirementText(SkillData.Herblore.name, potion)
| |
| local costText = Common.getCostString({
| |
| ["items"] = potion.itemCosts,
| |
| ["currencies"] = potion.currencyCosts
| |
| }, 'N/A', nil, ', ')
| |
|
| |
| local row = html:tag('tr')
| |
| row:tag('td'):attr('rowspan', 4):wikitext('[['..potion.name..']]')
| |
| row:tag('td'):attr('rowspan', 4):wikitext(level)
| |
| :css('text-align', 'center')
| |
| row:tag('td'):attr('rowspan', 4):wikitext(Shared.formatnum(baseXP))
| |
| :attr('data-sort-value', baseXP)
| |
| :css('text-align', 'right')
| |
| row:tag('td'):attr('rowspan', 4):wikitext(costText)
| |
|
| |
| local expIcon = Icons.getExpansionIcon(potion.potionIDs[1])
| |
|
| |
| local tierRows = {}
| |
| for j, potionID in ipairs(potion.potionIDs) do
| |
| local rowTxt = {}
| |
| local tierPot = Items.getItemByID(potionID)
| |
| local tierrow = html:tag('tr')
| |
| tierrow:tag('td'):wikitext(Icons.Icon({tierPot.name, type='item', notext=true}))
| |
| :wikitext('[[' .. tierPot.name .. '|' .. tierSuffix[j] .. ']]')
| |
| --tierrow:tag('td'):wikitext(Items.getValueText(tierPot))
| |
| -- :css('text-align', 'right')
| |
| -- :attr('data-sort-value', tierPot.sellsFor)
| |
| tierrow:tag('td'):wikitext(tierPot.charges)
| |
| :css('text-align', 'right')
| |
| tierrow:tag('td'):wikitext(p._getPotionDescription(tierPot))
| |
| end
| |
| end
| |
|
| |
| return tostring(html)
| |
| end
| |
|
| |
| function p.getHerblorePotionTable(frame)
| |
| local args = frame.args ~= nil and frame.args or frame
| |
| local category = args[1]
| |
| return p._getHerblorePotionTable(category)
| |
| end
| |
|
| |
| function p._getHerbloreHerbTable(realmID)
| |
| local allHerbs = {}
| |
|
| |
| -- Finds the herb from a potion along with the level required to make the potion.
| |
| local function handlePotion(potion)
| |
| local potionCosts = potion.itemCosts
| |
| local level = Skills.getRecipeLevel('Herblore', potion)
| |
|
| |
| if potionCosts == nil or level == nil then
| |
| return
| |
| end
| |
|
| |
| -- Find if this potion uses a herb, and which herb it is.
| |
| for _, ingredient in ipairs(potionCosts) do
| |
| local ingredientID = ingredient.id
| |
| if ingredientID ~= nil and string.sub(ingredientID, -5) == "_Herb" then
| |
| -- Set the lowest level of potion this herb is used in.
| |
| local currLevel = allHerbs[ingredientID] or 9999999
| |
| if level < currLevel then
| |
| allHerbs[ingredientID] = level
| |
| end
| |
| end
| |
| end
| |
| end
| |
|
| |
| local recipes = GameData.getEntities(SkillData.Herblore.recipes,
| |
| function(obj)
| |
| return Skills.getRecipeRealm(obj) == realmID
| |
| end
| |
| )
| |
| for _, potion in ipairs(recipes) do
| |
| handlePotion(potion)
| |
| end
| |
|
| |
| local sortedValues = Shared.sortDictionary(
| |
| allHerbs,
| |
| function (a, b) return a.value < b.value end)
| |
|
| |
| local tbl = mw.html.create("table")
| |
| :addClass("wikitable sortable stickyHeader")
| |
|
| |
| -- Add header
| |
| tbl :tag("tr"):addClass("headerRow-0")
| |
| :tag("th"):wikitext(Icons.Icon({'Herblore', type='skill', notext=true}) .. '<br>Level')
| |
| :tag("th"):wikitext("Herb")
| |
| :tag("th"):wikitext("Value")
| |
| :tag("th"):wikitext("Herb Sources")
| |
| :done()
| |
|
| |
| -- Fill wikitable.
| |
| for _, v in pairs(sortedValues) do
| |
| local herbItem = Items.getItemByID(v['key'])
| |
| local herbLevel = v['value']
| |
| local dlcIcon = Icons.getExpansionIcon(herbItem.id)
| |
|
| |
| -- Add rows
| |
| tbl :tag("tr")
| |
| :tag("td"):wikitext(herbLevel)
| |
| :css('text-align', 'center')
| |
| :tag("td"):wikitext(dlcIcon .. Icons.Icon({herbItem.name, type='item'}))
| |
| :tag("td"):wikitext(Items.getValueText(herbItem))
| |
| :tag('td'):wikitext(ItemSourceTables._getItemSources(herbItem, false, nil, ' '))
| |
| :done()
| |
| end
| |
|
| |
| return tostring(tbl)
| |
| end
| |
|
| |
| function p.getHerbloreHerbTable(frame)
| |
| local args = frame:getParent().args
| |
| local realmName = args.realm
| |
| local realm = Skills.getRealmFromName(realmName)
| |
| if realm == nil then
| |
| return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil'))
| |
| end
| |
| return p._getHerbloreHerbTable(realm.id)
| |
| end
| |
|
| |
| function p.getPotionTable(frame)
| |
| local potionName = frame.args ~= nil and frame.args[1] or frame
| |
|
| |
| local recipe = GameData.getEntityByName(SkillData.Herblore.recipes, potionName)
| |
| if recipe == nil then
| |
| return Shared.printError('No potion named "' .. potionName .. '" was found')
| |
| end
| |
|
| |
| local html = mw.html.create('table')
| |
| :addClass('wikitable')
| |
|
| |
| html:tag('tr')
| |
| :tag('th'):attr('colspan', 4)
| |
| :wikitext('[[' .. potionName ..']]')
| |
| :tag('tr')
| |
| :tag('th'):wikitext('Potion')
| |
| :tag('th'):wikitext('Tier')
| |
| :tag('th'):wikitext('Charges')
| |
| :tag('th'):wikitext('Effect')
| |
|
| |
| for i, potionID in ipairs(recipe.potionIDs) do
| |
| local tier = tierSuffix[i]
| |
| local potion = Items.getItemByID(potionID)
| |
| if potion ~= nil then
| |
| html:tag('tr')
| |
| :tag('td'):wikitext(Icons.getExpansionIcon(potion.id))
| |
| :wikitext(Icons.Icon({potion.name, type='item', notext=true, size='25'}))
| |
| :css('text-wrap', 'nowrap')
| |
| :tag('td'):wikitext(Icons.Icon({potion.name, tier, type='item', noicon=true}))
| |
| :tag('td'):wikitext(potion.charges)
| |
| :tag('td'):wikitext(p._getPotionDescription(potion))
| |
| end
| |
| end
| |
|
| |
| return tostring(html)
| |
| end
| |
|
| |
| function p.getRunecraftingTable(frame)
| |
| local category = frame.args ~= nil and frame.args[1] or frame
| |
| return p._getRecipeTable('Runecrafting', category, {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'Currency', 'Ingredients', 'SkillXPSec', 'CurrencySec'})
| |
| end
| |
|
| |
| function p.getFletchingTable(frame)
| |
| local category = frame.args ~= nil and frame.args[1] or frame
| |
| return p._getRecipeTable('Fletching', category, {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'Currency', 'Ingredients'})
| |
| end
| |
|
| |
| function p.getCraftingTable(frame)
| |
| local category = frame.args ~= nil and frame.args[1] or frame
| |
| local columns = {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'Currency', 'Ingredients'}
| |
| if category == 'Rings' or category == 'Necklaces' then
| |
| table.insert(columns, "Description")
| |
| end
| |
| return p._getRecipeTable('Crafting', category, columns)
| |
| end
| |
|
| |
| function p.getSmithingTable(frame)
| |
| local category = frame.args ~= nil and frame.args[1] or frame
| |
| local columns = {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'Currency', 'Ingredients'}
| |
| if category ~= 'Bars' and category ~= 'Abyssal Bars' then
| |
| table.insert(columns, 'CurrencyBar')
| |
| end
| |
| return p._getRecipeTable('Smithing', category, columns)
| |
| end
| |
|
| |
| -- Given a skill name, category, and column list, produces a table of recipes for that
| |
| -- skill & category combination. If categoryName is '', all recipes are returned.
| |
| -- Note: This only supports a number of skills with consistent recipe data structures, being:
| |
| -- Fletching, Crafting, and Runecrafting
| |
| -- Valid column list options are: Item, SkillLevel, SkillXP, Currency, Ingredients, SkillXPSec, CurrencySec, CurrencyBar
| |
| function p._getRecipeTable(skillName, categoryName, columnList)
| |
| -- Validation: Parameters
| |
| if type(skillName) ~= 'string' then
| |
| return Shared.printError('skillName must be a string')
| |
| elseif not Shared.contains({'string', 'nil'}, type(categoryName)) then
| |
| return Shared.printError('category must be a string or nil')
| |
| elseif type(columnList) ~= 'table' or Shared.tableIsEmpty(columnList) then
| |
| return Shared.printError('columnList must be a table with 1+ elements')
| |
| end
| |
|
| |
| local supportedSkills = {
| |
| 'Smithing',
| |
| 'Crafting',
| |
| 'Fletching',
| |
| 'Runecrafting'
| |
| }
| |
| if not Shared.contains(supportedSkills, skillName) then
| |
| return Shared.printError('The ' .. skillName .. ' skill is not supported by this function')
| |
| end
| |
|
| |
| -- Validation: Category
| |
| local category = GameData.getEntityByName(SkillData[skillName].categories, categoryName)
| |
| if category == nil then
| |
| local catNames = {}
| |
| for i, cat in pairs(SkillData[skillName].categories) do
| |
| table.insert(catNames, cat.name)
| |
| end
| |
| return Shared.printError('No such category ' .. categoryName .. ' for skill ' .. skillName .. ', the following are available: ' .. table.concat(catNames, ', '))
| |
| end
| |
| local actionInterval = SkillData[skillName].baseInterval / 1000
| |
|
| |
| -- Validation: Skill data
| |
| local recipeKey = 'recipes'
| |
| if SkillData[skillName] == nil then
| |
| return Shared.printError('Could not locate skill data for ' .. skillName)
| |
| elseif SkillData[skillName][recipeKey] == nil then
| |
| return Shared.printError('Could not locate recipe data for ' .. skillName)
| |
| end
| |
|
| |
| -- Validation: Column list
| |
| local columnDef = {
| |
| ["ItemImage"] = {["header"] = 'Item', ["altRepeat"] = false},
| |
| ["ItemName"] = {["header"] = 'Name', ["altRepeat"] = true},
| |
| ["SkillLevel"] = {["header"] = Icons.Icon({skillName, type='skill', notext=true}) .. ' Level', ["altRepeat"] = false},
| |
| ["SkillXP"] = {["header"] = 'XP', ["altRepeat"] = false},
| |
| ["Currency"] = {["header"] = 'Value', ["altRepeat"] = true},
| |
| ["Ingredients"] = {["header"] = 'Ingredients', ["altRepeat"] = true},
| |
| ["SkillXPSec"] = {["header"] = 'XP/s', ["altRepeat"] = false},
| |
| ["CurrencySec"] = {["header"] = 'Value/s', ["altRepeat"] = true},
| |
| ["CurrencyBar"] = {["header"] = 'Value/Bar', ["altRepeat"] = true },
| |
| ["Description"] = {["header"] = "Description", ["altRepeat"] = true}
| |
| }
| |
| -- Build the table header while we're here
| |
| local resultPart, barIDList = {}, {}
| |
| table.insert(resultPart, '{| class="wikitable sortable stickyHeader"\r\n|- class="headerRow-0"')
| |
| for i, colID in ipairs(columnList) do
| |
| if columnDef[colID] == nil then
| |
| return Shared.printError('Invalid column ' .. colID .. ' requested')
| |
| else
| |
| table.insert(resultPart, '\r\n! ' .. columnDef[colID].header)
| |
| if colID == 'CurrencyBar' then
| |
| -- For Smithing, a currency value per bar column is included. If this
| |
| -- is requested, then obtain a list of bar item IDs
| |
| barIDList = p.getBarItemIDs()
| |
| end
| |
| end
| |
| end
| |
|
| |
| -- Determine which recipes to include
| |
| local recipeList = GameData.getEntities(SkillData[skillName][recipeKey],
| |
| function(recipe)
| |
| return category.id == nil or recipe.categoryID == category.id
| |
| end)
| |
| if Shared.tableIsEmpty(recipeList) then
| |
| return ''
| |
| end
| |
| table.sort(recipeList, function(a, b) return a.level < b.level end)
| |
|
| |
| -- Build rows based on recipes
| |
| for i, recipe in ipairs(recipeList) do
| |
| local ns, _ = GameData.getLocalID(recipe.id)
| |
| local item = Items.getItemByID(recipe.productID)
| |
| local level = Skills.getRecipeLevel(skillName, recipe)
| |
| local baseXP = recipe.baseAbyssalExperience or recipe.baseExperience
| |
| if item ~= nil then
| |
| -- Some recipes have alternative costs, so the recipe may require multiple rows
| |
| local costList = nil
| |
| if recipe.alternativeCosts ~= nil and not Shared.tableIsEmpty(recipe.alternativeCosts) then
| |
| costList = recipe.alternativeCosts
| |
| else
| |
| costList = {{["itemCosts"] = recipe.itemCosts}}
| |
| end
| |
| local costCount = Shared.tableCount(costList)
| |
| -- Build one row per element within costList
| |
| for recipeRow, costDef in ipairs(costList) do
| |
| local rowspanStr = (recipeRow == 1 and costCount > 1 and 'rowspan="' .. costCount .. '" ') or ''
| |
| local qty = (costDef.quantityMultiplier or 1) * (recipe.baseQuantity or 1)
| |
| table.insert(resultPart, '\n|-')
| |
| for j, colID in ipairs(columnList) do
| |
| local altRepeat = columnDef[colID].altRepeat
| |
| -- All columns must be generated if this is the very first row for a recipe,
| |
| -- for subsequent rows only columns marked as altRepeat = true are generated
| |
| if recipeRow == 1 or altRepeat then
| |
| local spanStr = (not altRepeat and rowspanStr) or ''
| |
| if colID == 'ItemImage' then
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'class="table-img"| ' .. Icons.Icon({item.name, type='item', size='50', notext=true}))
| |
| elseif colID == "ItemName" then
| |
| local namePrefix = spanStr
| |
| if qty > 1 then
| |
| namePrefix = namePrefix .. 'data-sort-value="' .. item.name .. '"'
| |
| end
| |
| table.insert(resultPart, '\n|'.. (namePrefix ~= '' and namePrefix .. '| ' or ' ') .. Icons.getExpansionIcon(item.id) .. (qty > 1 and '<b>' .. qty .. 'x</b> ' or '') .. Icons.Icon({item.name, type='item', noicon=true}))
| |
| elseif colID == 'SkillLevel' then
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'style="text-align:right"| ' .. level)
| |
| elseif colID == 'SkillXP' then
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. baseXP ..'" style="text-align:right"| ' .. Shared.formatnum(baseXP))
| |
| elseif colID == 'Currency' then
| |
| local val = math.floor(item.sellsFor)
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. (val * qty) .. '"| ' .. Items.getValueText(item) .. (qty > 1 and ' (x' .. qty .. ')' or ''))
| |
| elseif colID == 'Ingredients' then
| |
| local matArray = {}
| |
| local currCost = { ["items"] = {}, ["currencies"] = recipe.currencyCosts }
| |
| local currText = Common.getCostString(currCost, nil, nil, ', ')
| |
| if currText ~= nil then
| |
| table.insert(matArray, currText)
| |
| end
| |
|
| |
| for k, mat in ipairs(costDef.itemCosts) do
| |
| local matItem = Items.getItemByID(mat.id)
| |
| if matItem ~= nil then
| |
| table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.quantity}))
| |
| end
| |
| end
| |
| table.insert(resultPart, '\n|' .. (spanStr ~= '' and spanStr .. '| ' or ' ') .. table.concat(matArray, ', '))
| |
| elseif colID == 'SkillXPSec' then
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'style="text-align:right"| ' .. string.format('%.2f', recipe.baseExperience / actionInterval))
| |
| elseif colID == 'CurrencySec' then
| |
| local saleCurrency = item.sellsForCurrency or 'melvorD:GP'
| |
| local val = math.floor(item.sellsFor) * qty / actionInterval
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. val .. '"| ' .. Icons._Currency(saleCurrency, string.format('%.2f', val)))
| |
| elseif colID == 'CurrencyBar' then
| |
| local barQty = 0
| |
| for k, mat in ipairs(costDef.itemCosts) do
| |
| if Shared.contains(barIDList, mat.id) then
| |
| barQty = barQty + mat.quantity
| |
| end
| |
| end
| |
| if barQty > 0 then
| |
| local saleCurrency = item.sellsForCurrency or 'melvorD:GP'
| |
| local barVal = Shared.round(math.floor(item.sellsFor) * qty / barQty, 1, 1)
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. barVal .. '"| ' .. Icons._Currency(saleCurrency, barVal))
| |
| else
| |
| table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="0" class="table-na"| N/A')
| |
| end
| |
| elseif colID == 'Description' then
| |
| local descrip = Items._getItemStat(item, 'description')
| |
| if descrip == 'No Description' and item.modifiers ~= nil and not Shared.tableIsEmpty(item.modifiers) then
| |
| descrip = Modifiers.getModifiersText(item.modifiers, false)
| |
| end
| |
| table.insert(resultPart, '\n| '..spanStr..'|'..descrip)
| |
| else
| |
| table.insert(resultPart, '\n| ')
| |
| end
| |
| end
| |
| end
| |
| end
| |
| end
| |
| end
| |
| table.insert(resultPart, '\n|}')
| |
| return table.concat(resultPart)
| |
| end
| |
|
| |
| function p.getBarItemIDs()
| |
| local barCategories = {
| |
| ['melvorD:Bars'] = true,
| |
| ['melvorItA:AbyssalBars'] = true
| |
| }
| |
| local barIDList = {}
| |
| for i, recipe in ipairs(SkillData.Smithing.recipes) do
| |
| if barCategories[recipe.categoryID] then
| |
| table.insert(barIDList, recipe.productID)
| |
| end
| |
| end
| |
| return barIDList
| |
| end
| |
|
| |
| return p
| |