Module:Skills/Artisan: Difference between revisions

m
Add space for separator for herb itemsources
(Undo revision 60646 by Auron956 (talk) - Reinstate changes)
Tag: Undo
m (Add space for separator for herb itemsources)
 
(6 intermediate revisions by 2 users not shown)
Line 9: Line 9:
local Items = require('Module:Items')
local Items = require('Module:Items')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local ItemSourceTables = require('Module:Items/SourceTables')


function p.getCookedItemsTable(frame)
function p.getCookedItemsTable(frame)
Line 47: Line 48:
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n!colspan="3" rowspan="2"|Cooked Item!!rowspan="2"|'..Icons.Icon({'Cooking', type='skill', notext=true})..' Level')
table.insert(resultPart, '\r\n!colspan="3" rowspan="2"|Cooked Item!!rowspan="2"|'..Icons.Icon({'Cooking', type='skill', notext=true})..' Level')
table.insert(resultPart, '!!rowspan="2"|Cook Time!!rowspan="2"|XP!!rowspan="2"|XP/s!!colspan="2"|Healing!!colspan="2"|Value!!rowspan="2"|Ingredients')
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|- class="headerRow-1"')
table.insert(resultPart, '\r\n!Normal!!' .. Icons.Icon({'Perfect', type='bonus', ext='png', notext=true, nolink=true}))
table.insert(resultPart, '\r\n!Normal!!' .. Icons.Icon({'Perfect', type='bonus', ext='png', notext=true, nolink=true}))
Line 61: Line 62:


table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|style="min-width:25px"|'..Icons.Icon({item.name, type='item', notext=true, size='50'}))
table.insert(resultPart, '\r\n|class="table-img"|'..Icons.Icon({item.name, type='item', notext=true, size='50'}))
table.insert(resultPart, '\r\n|style="min-width:25px"| ')
table.insert(resultPart, '\r\n|class="table-img"| ')
if perfectItem ~= nil then
if perfectItem ~= nil then
table.insert(resultPart, Icons.Icon({perfectItem.name, type='item', notext=true, size='50'}))
table.insert(resultPart, Icons.Icon({perfectItem.name, type='item', notext=true, size='50'}))
Line 73: Line 74:
table.insert(resultPart, Icons.Icon({item.name, type='item', noicon = true}))
table.insert(resultPart, Icons.Icon({item.name, type='item', noicon = true}))
table.insert(resultPart, '||style="text-align:right"|' .. recipe.level)
table.insert(resultPart, '||style="text-align:right"|' .. recipe.level)
table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseInterval .. '"|' .. Shared.timeString(recipe.baseInterval / 1000, true))
table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseInterval .. '"|' .. Shared.round(recipe.baseInterval / 1000, 2, 0))
table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseExperience .. '"|' .. Shared.formatnum(recipe.baseExperience))
table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseExperience .. '"|' .. Shared.formatnum(recipe.baseExperience))
local xpRate = recipe.baseExperience / (recipe.baseInterval / 1000)
local xpRate = recipe.baseExperience / (recipe.baseInterval / 1000)
Line 94: Line 95:


local tierSuffix = { 'I', 'II', 'III', 'IV' }
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 Constants.getModifiersText(potion.modifiers, false, true)
else
return ''
end
end
function p._getHerblorePotionTable(categoryName)
function p._getHerblorePotionTable(categoryName)
local categoryID = nil
local categoryID = nil
Line 116: Line 129:
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|-')
local expIcon = Icons.getExpansionIcon(potion.potionIDs[1])
local expIcon = Icons.getExpansionIcon(potion.potionIDs[1])
if potion.name == 'Bird Nests Potion' then
table.insert(resultPart, '\r\n|rowspan="4"|'..expIcon..'[['..potion.name..']]')
table.insert(resultPart, '\r\n|rowspan="4"|'..expIcon..'[[Bird Nest Potion]]')
else
table.insert(resultPart, '\r\n|rowspan="4"|'..expIcon..'[['..potion.name..']]')
end
table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.level)
table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.level)
table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.baseExperience)
table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.baseExperience)
Line 135: Line 144:
local rowTxt = {}
local rowTxt = {}
local tierPot = Items.getItemByID(potionID)
local tierPot = Items.getItemByID(potionID)
local potDesc = ''
if type(tierPot.modifiers) == 'table' and not Shared.tableIsEmpty(tierPot.modifiers) then
potDesc = Constants.getModifiersText(tierPot.modifiers, false) or ''
end
table.insert(rowTxt, Icons.Icon({tierPot.name, type='item', notext=true}))
table.insert(rowTxt, Icons.Icon({tierPot.name, type='item', notext=true}))
table.insert(rowTxt, Icons.Icon({tierPot.name, tierSuffix[j], type = 'item', noicon=true}))
table.insert(rowTxt, Icons.Icon({tierPot.name, tierSuffix[j], type = 'item', noicon=true}))
table.insert(rowTxt, '||style="text-align:right;" data-sort-value="'..tierPot.sellsFor..'"|'..Icons.GP(tierPot.sellsFor))
table.insert(rowTxt, '||style="text-align:right;" data-sort-value="'..tierPot.sellsFor..'"|'..Icons.GP(tierPot.sellsFor))
table.insert(rowTxt, '||style="text-align:right;"|'..tierPot.charges..'|| '..potDesc)
table.insert(rowTxt, '||style="text-align:right;"|'..tierPot.charges..'|| '..p._getPotionDescription(tierPot))
table.insert(tierRows, table.concat(rowTxt))
table.insert(tierRows, table.concat(rowTxt))
end
end
Line 155: Line 160:
local category = frame.args ~= nil and frame.args[1] or frame
local category = frame.args ~= nil and frame.args[1] or frame
return p._getHerblorePotionTable(category)
return p._getHerblorePotionTable(category)
end
function p._getHerbloreHerbTable(args)
local allHerbs = {}
local allPotions = GameData.getEntities(SkillData.Herblore.recipes, function() return true end)
-- 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 = potion.level
if potionCosts == nil or level == nil then
return
end
-- Find if this potion uses a herb, and which herb it is.
for _, ingredient in pairs(potionCosts) do
local ingredientID = ingredient.id
if ingredientID == nil or string.sub(ingredientID, -5) ~= "_Herb" then
return
end
-- 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
for _, potion in pairs(allPotions) 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})..' 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)
    :tag("td"):wikitext(dlcIcon .. Icons.Icon({herbItem.name, type='item'}))
    :tag("td"):wikitext(Icons.GP(herbItem.sellsFor))
    :tag('td'):wikitext(ItemSourceTables._getItemSources(herbItem, false, nil, ' '))
    :done()
    end
return tostring(tbl)
end
function p.getHerbloreHerbTable(frame)
local args = frame:getParent().args
return p._getHerbloreHerbTable(args)
end
end


Line 167: Line 242:
local resultPart = {}
local resultPart = {}
table.insert(resultPart, '{| class="wikitable"')
table.insert(resultPart, '{| class="wikitable"')
--The Bird Nest Potion specifically has the wrong name in code
table.insert(resultPart, '\r\n!colspan=4|[['..potionName..']]')
if potionName == 'Bird Nests Potion' then
table.insert(resultPart, '\r\n!colspan=4|[[Bird Nest Potion]]')
else
table.insert(resultPart, '\r\n!colspan=4|[['..potionName..']]')
end
table.insert(resultPart, '\r\n|-\r\n!Potion!!Tier!!Charges!!Effect')
table.insert(resultPart, '\r\n|-\r\n!Potion!!Tier!!Charges!!Effect')


Line 179: Line 249:
local potion = Items.getItemByID(potionID)
local potion = Items.getItemByID(potionID)
if potion ~= nil then
if potion ~= nil then
local potDesc = potion.customDescription or ''
if potDesc == '' and type(potion.modifiers) == 'table' and not Shared.tableIsEmpty(potion.modifiers) then
potDesc = Constants.getModifiersText(potion.modifiers, false) or ''
end
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n| ' .. Icons.Icon({potion.name, type='item', notext=true, size='60'}))
table.insert(resultPart, '\r\n| ' .. Icons.Icon({potion.name, type='item', notext=true, size='60'}))
table.insert(resultPart, '|| ' .. Icons.getExpansionIcon(potion.id) .. Icons.Icon({potion.name, tier, type='item', noicon=true}))
table.insert(resultPart, '|| ' .. Icons.getExpansionIcon(potion.id) .. Icons.Icon({potion.name, tier, type='item', noicon=true}))
table.insert(resultPart, '|| ' .. potion.charges .. '|| ' .. potDesc)
table.insert(resultPart, '|| ' .. potion.charges .. '|| ' .. p._getPotionDescription(potion))
end
end
end
end
Line 196: Line 262:
function p.getRunecraftingTable(frame)
function p.getRunecraftingTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local category = frame.args ~= nil and frame.args[1] or frame
return p._getRecipeTable('Runecrafting', category, {'Item', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients', 'SkillXPSec', 'GPSec'})
return p._getRecipeTable('Runecrafting', category, {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients', 'SkillXPSec', 'GPSec'})
end
end


function p.getFletchingTable(frame)
function p.getFletchingTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local category = frame.args ~= nil and frame.args[1] or frame
return p._getRecipeTable('Fletching', category, {'Item', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients'})
return p._getRecipeTable('Fletching', category, {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients'})
end
end


function p.getCraftingTable(frame)
function p.getCraftingTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local category = frame.args ~= nil and frame.args[1] or frame
local columns = {'Item', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients'}
local columns = {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients'}
if category == 'Rings' or category == 'Necklaces' then
if category == 'Rings' or category == 'Necklaces' then
table.insert(columns, "Description")
table.insert(columns, "Description")
Line 215: Line 281:
function p.getSmithingTable(frame)
function p.getSmithingTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local category = frame.args ~= nil and frame.args[1] or frame
local columns = {'Item', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients'}
local columns = {'ItemImage', 'ItemName', 'SkillLevel', 'SkillXP', 'GP', 'Ingredients'}
if category ~= 'Bars' then
if category ~= 'Bars' then
table.insert(columns, 'GPBar')
table.insert(columns, 'GPBar')
Line 268: Line 334:
-- Validation: Column list
-- Validation: Column list
local columnDef = {
local columnDef = {
["Item"] = {["header"] = 'Item\r\n!Name', ["altRepeat"] = true},
["ItemImage"] = {["header"] = 'Item', ["altRepeat"] = false},
["ItemName"] = {["header"] = 'Name', ["altRepeat"] = true},
["SkillLevel"] = {["header"] = Icons.Icon({skillName, type='skill', notext=true}) .. ' Level', ["altRepeat"] = false},
["SkillLevel"] = {["header"] = Icons.Icon({skillName, type='skill', notext=true}) .. ' Level', ["altRepeat"] = false},
["SkillXP"] = {["header"] = 'XP', ["altRepeat"] = false},
["SkillXP"] = {["header"] = 'XP', ["altRepeat"] = false},
Line 321: Line 388:
local rowspanStr = (recipeRow == 1 and costCount > 1 and 'rowspan="' .. costCount .. '" ') or ''
local rowspanStr = (recipeRow == 1 and costCount > 1 and 'rowspan="' .. costCount .. '" ') or ''
local qty = (costDef.quantityMultiplier or 1) * (recipe.baseQuantity or 1)
local qty = (costDef.quantityMultiplier or 1) * (recipe.baseQuantity or 1)
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\n|-')
for j, colID in ipairs(columnList) do
for j, colID in ipairs(columnList) do
local altRepeat = columnDef[colID].altRepeat
local altRepeat = columnDef[colID].altRepeat
Line 328: Line 395:
if recipeRow == 1 or altRepeat then
if recipeRow == 1 or altRepeat then
local spanStr = (not altRepeat and rowspanStr) or ''
local spanStr = (not altRepeat and rowspanStr) or ''
if colID == 'Item' then
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
local namePrefix = spanStr
if qty > 1 then
if qty > 1 then
namePrefix = namePrefix .. 'data-sort-value="' .. item.name .. '"'
namePrefix = namePrefix .. 'data-sort-value="' .. item.name .. '"'
end
end
table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:center;min-width:25px"| ' .. Icons.Icon({item.name, type='item', size='50', notext=true}))
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}))
table.insert(resultPart, '\r\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
elseif colID == 'SkillLevel' then
table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. recipe.level)
table.insert(resultPart, '\n|' .. spanStr .. 'style="text-align:right"| ' .. recipe.level)
elseif colID == 'SkillXP' then
elseif colID == 'SkillXP' then
table.insert(resultPart, '\r\n|' .. spanStr .. 'data-sort-value="' .. recipe.baseExperience ..'" style="text-align:right"| ' .. Shared.formatnum(recipe.baseExperience))
table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. recipe.baseExperience ..'" style="text-align:right"| ' .. Shared.formatnum(recipe.baseExperience))
elseif colID == 'GP' then
elseif colID == 'GP' then
local val = math.floor(item.sellsFor)
local val = math.floor(item.sellsFor)
table.insert(resultPart, '\r\n|' .. spanStr .. 'data-sort-value="' .. (val * qty) .. '"| ' .. Icons.GP(val) .. (qty > 1 and ' (x' .. qty .. ')' or ''))
table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. (val * qty) .. '"| ' .. Icons.GP(val) .. (qty > 1 and ' (x' .. qty .. ')' or ''))
elseif colID == 'Ingredients' then
elseif colID == 'Ingredients' then
local matArray = {}
local matArray = {}
Line 356: Line 424:
table.insert(matArray, Icons.SC(recipe.scCost))
table.insert(matArray, Icons.SC(recipe.scCost))
end
end
table.insert(resultPart, '\r\n|' .. (spanStr ~= '' and spanStr .. '| ' or ' ') .. table.concat(matArray, ', '))
table.insert(resultPart, '\n|' .. (spanStr ~= '' and spanStr .. '| ' or ' ') .. table.concat(matArray, ', '))
elseif colID == 'SkillXPSec' then
elseif colID == 'SkillXPSec' then
table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. string.format('%.2f', recipe.baseExperience / actionInterval))
table.insert(resultPart, '\n|' .. spanStr .. 'style="text-align:right"| ' .. string.format('%.2f', recipe.baseExperience / actionInterval))
elseif colID == 'GPSec' then
elseif colID == 'GPSec' then
local val = math.floor(item.sellsFor) * qty / actionInterval
local val = math.floor(item.sellsFor) * qty / actionInterval
table.insert(resultPart, '\r\n|' .. spanStr .. 'data-sort-value="' .. val .. '"| ' .. Icons.GP(string.format('%.2f', val)))
table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. val .. '"| ' .. Icons.GP(string.format('%.2f', val)))
elseif colID == 'GPBar' then
elseif colID == 'GPBar' then
local barQty = 0
local barQty = 0
Line 371: Line 439:
if barQty > 0 then
if barQty > 0 then
local barVal = Shared.round(math.floor(item.sellsFor) * qty / barQty, 1, 1)
local barVal = Shared.round(math.floor(item.sellsFor) * qty / barQty, 1, 1)
table.insert(resultPart, '\r\n|' .. spanStr .. 'data-sort-value="' .. barVal .. '"| ' .. Icons.GP(barVal))
table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="' .. barVal .. '"| ' .. Icons.GP(barVal))
else
else
table.insert(resultPart, '\r\n|' .. spanStr .. 'data-sort-value="0" class="table-na"| N/A')
table.insert(resultPart, '\n|' .. spanStr .. 'data-sort-value="0" class="table-na"| N/A')
end
end
elseif colID == 'Description' then
elseif colID == 'Description' then
Line 380: Line 448:
descrip = Constants.getModifiersText(item.modifiers, false)
descrip = Constants.getModifiersText(item.modifiers, false)
end
end
table.insert(resultPart, '\r\n| '..spanStr..'|'..descrip)
table.insert(resultPart, '\n| '..spanStr..'|'..descrip)
else
else
table.insert(resultPart, '\r\n| ')
table.insert(resultPart, '\n| ')
end
end
end
end
Line 389: Line 457:
end
end
end
end
table.insert(resultPart, '\r\n|}')
table.insert(resultPart, '\n|}')
return table.concat(resultPart)
return table.concat(resultPart)
end
end
918

edits