Difference between revisions of "Module:Sandbox/Broono/Item Recipes"

From Idlescape Wiki
Jump to navigation Jump to search
m (Attempt #2)
m (Get ready for testing)
 
(2 intermediate revisions by the same user not shown)
Line 8: Line 8:
 
data.craftingAugmenting = mw.loadData('Module:CraftingAugmenting/data')
 
data.craftingAugmenting = mw.loadData('Module:CraftingAugmenting/data')
 
data.items = mw.loadData('Module:Items/data')
 
data.items = mw.loadData('Module:Items/data')
 +
  
 
local COLLAPSIBLE = 7
 
local COLLAPSIBLE = 7
 
local COLLAPSED = 15
 
local COLLAPSED = 15
 +
local SORTABLE = 7
  
  
Line 16: Line 18:
 
     return s:match('^%s*(.-)%s*$')
 
     return s:match('^%s*(.-)%s*$')
 
end
 
end
 
  
 
local function split(s, sep)
 
local function split(s, sep)
Line 28: Line 29:
 
   return t
 
   return t
 
end
 
end
 
  
 
function table.length(t)
 
function table.length(t)
Line 35: Line 35:
 
     return count
 
     return count
 
end
 
end
 
  
 
local function addItemIds(t, names)
 
local function addItemIds(t, names)
Line 46: Line 45:
 
                 table.insert(t, {['id'] = id})
 
                 table.insert(t, {['id'] = id})
 
             else
 
             else
                 table.insert(t, {['id'] = id, ['name'] = name})
+
                 table.insert(t, {['error'] = {'name', name}})
 
             end
 
             end
 
         end
 
         end
 
     end
 
     end
 
end
 
end
 
  
 
local function addOtherItemFields(t)
 
local function addOtherItemFields(t)
 
     for i in pairs(t) do
 
     for i in pairs(t) do
         if type(t[i].id) == 'number' then
+
         if t[i].id then
 
             local id = tostring(t[i].id)
 
             local id = tostring(t[i].id)
 
             local craftingStats
 
             local craftingStats
             if data.items[id].craftingStats then
+
             if data.items[id] and data.items[id].craftingStats then
 
                 craftingStats = data.items[id].craftingStats
 
                 craftingStats = data.items[id].craftingStats
 +
            elseif data.items[id] then
 +
                craftingStats = data.items[id]
 
             else
 
             else
                 craftingStats = data.items[id]
+
                 t[i].error = { 'id', t[i].id }
 +
            end
 +
            if not t[i].error then
 +
                t[i].name = data.items[id].name
 +
                t[i].level = craftingStats.level
 +
                t[i].experience = craftingStats.experience
 +
                t[i].category = craftingStats.category
 
             end
 
             end
             t[i].name = data.items[id].name
+
        else
            t[i].level = craftingStats.level
+
             t[i].error = {'id', 'nil'}
            t[i].experience = craftingStats.experience
 
            t[i].category = craftingStats.category
 
 
         end
 
         end
 
     end
 
     end
 
end
 
end
 
  
 
local function addRecipes(t)
 
local function addRecipes(t)
 
     for i in pairs(t) do
 
     for i in pairs(t) do
        if type(t[i].id) == 'number' then
+
    local id = tostring(t[i].id)
            local id = tostring(t[i].id)
+
        if data.craftingAugmenting[id] and not t[i].error then
 
             t[i].recipes = {}
 
             t[i].recipes = {}
 
             if data.craftingAugmenting[id].crafting then
 
             if data.craftingAugmenting[id].crafting then
Line 92: Line 95:
 
                 t[i].skill = 'Smithing'
 
                 t[i].skill = 'Smithing'
 
             end
 
             end
 +
        elseif not t[i].error then
 +
            t[i].error = {'recipe', id .. ' (' .. t[i].name .. ')'}
 
         end
 
         end
 
     end
 
     end
 
end
 
end
  
 
local function renderRecipes(t)
 
    local recipes = {}
 
    for _, r in pairs(t) do
 
        local ingredients = {}
 
        for id, amt in pairs(r) do
 
            local ingredient = addSeparator._addSeparator({amt}) .. 'x'
 
            ingredient = ingredient .. ' {{Img|' .. data.items[id].name .. '|30}}'
 
            table.insert(ingredients, ingredient)
 
        end
 
        table.insert(recipes, table.concat(ingredients, ', '))
 
    end
 
    return '\n| ' .. table.concat(recipes, '\n|-\n| ')
 
end
 
 
--[[
 
{ {
 
    category = "Melee",
 
    experience = 20800,
 
    id = 1022,
 
    level = 50,
 
    name = "Runite Daggers",
 
    recipes = { {
 
        ["206"] = 100,
 
        ["306"] = 50
 
      } },
 
    skill = "Crafting"
 
  }, {
 
    experience = 25,
 
    id = 511,
 
    level = 1,
 
    name = "Earth Rune",
 
    recipes = { {
 
        ["113"] = 1,
 
        ["4"] = 400
 
      } },
 
    skill = "Runecrafting"
 
  }, {
 
    id = "id not found",
 
    name = "buuurp"
 
  }, {
 
    experience = 4200,
 
    id = 1601,
 
    level = 61,
 
    name = "Scroll of Embers",
 
    recipes = { {
 
        ["111"] = 700,
 
        ["1600"] = 1,
 
        ["512"] = 70,
 
        ["517"] = 70
 
      } },
 
    skill = "Scrollcrafting"
 
  }, {
 
    experience = 1500,
 
    id = 207,
 
    level = 60,
 
    name = "Stygian Bar",
 
    recipes = { {
 
        ["114"] = 15,
 
        ["2"] = 500,
 
        ["800"] = 5
 
      } },
 
    skill = "Smithing"
 
  }, {
 
    category = "Farming",
 
    experience = 750,
 
    id = 4510,
 
    level = 6,
 
    name = "Worm Composting Bin",
 
    recipes = { {
 
        ["150"] = 1,
 
        ["2034"] = 150
 
      }, {
 
        ["150"] = 1,
 
        ["2039"] = 150
 
      }, {
 
        ["150"] = 1,
 
        ["2040"] = 150
 
      }, {
 
        ["150"] = 1,
 
        ["2043"] = 150
 
      } },
 
    skill = "Crafting"
 
  } }
 
]]
 
 
local function generateTableRecipe(t)
 
local function generateTableRecipe(t)
 
     local ingredients = {}
 
     local ingredients = {}
Line 186: Line 106:
 
         local name = data.items[id].name
 
         local name = data.items[id].name
 
         local image = img._img({name, 30})
 
         local image = img._img({name, 30})
        --table.insert(ingredients, addSeparator._addSeparator({amt}) .. 'x ' .. image)
 
 
         table.insert(ingredients, image .. ' x'.. addSeparator._addSeparator({amt}))
 
         table.insert(ingredients, image .. ' x'.. addSeparator._addSeparator({amt}))
 
     end
 
     end
 
     return table.concat(ingredients, ', ')
 
     return table.concat(ingredients, ', ')
 
end
 
end
 
  
 
local function generateTableBody(t)
 
local function generateTableBody(t)
Line 202: Line 120:
 
         local rowspan = 0
 
         local rowspan = 0
  
         if type(t[i].id) ~= 'number' then
+
         if t[i].error then
             local text = '\'\'Could not find item: \'\'\'' .. t[i].name .. '\'\'\'.'
+
            local e
            text = text .. ' Please check spelling or update data module.'
+
            if t[i].error[1] == 'recipe' then
 +
                e = 'Could not find a recipe for item with id: ' .. t[i].error[2]
 +
             else           
 +
                e = '\'\'Could not find item with ' .. t[i].error[1] .. ': '
 +
                e = e ..'\'\'\'' .. t[i].error[2] .. '\'\'\'.'
 +
                if t[i].error[1] == 'name' then
 +
                    e = e .. ' Please check spelling or update data modules.'
 +
                end
 +
            end
  
 
             row:tag('td')
 
             row:tag('td')
 
                 :css('text-align', 'center')
 
                 :css('text-align', 'center')
 
                 :attr('colspan', 5)
 
                 :attr('colspan', 5)
                 :wikitext(text)
+
                 :wikitext(e)
 
         else
 
         else
 
             rowspan = table.length(t[i].recipes)
 
             rowspan = table.length(t[i].recipes)
Line 233: Line 159:
 
             local skill
 
             local skill
 
             if t[i].category then
 
             if t[i].category then
                 skill = '[[' .. t[i].skill .. ']] (' .. t[i].category .. '): ' .. t[i].level
+
                 skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ' (' .. t[i].category .. '): ' .. t[i].level
 
             else
 
             else
                 skill = '[[' .. t[i].skill .. ']]: ' .. t[i].level
+
                 skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ': ' .. t[i].level
 
             end
 
             end
 
             row:node(mw.html.create('td')
 
             row:node(mw.html.create('td')
Line 266: Line 192:
 
     return tbody
 
     return tbody
 
end
 
end
 
  
 
local function generateTableHead()
 
local function generateTableHead()
Line 299: Line 224:
 
     return thead
 
     return thead
 
end
 
end
 
  
 
local function generateTable(t)
 
local function generateTable(t)
Line 306: Line 230:
 
     tbl
 
     tbl
 
     :addClass('wikitable')
 
     :addClass('wikitable')
     :addClass('sortable')
+
     if table.length(t) > SORTABLE then tbl:addClass('sortable') end
 
     if table.length(t) > COLLAPSIBLE then tbl:addClass('mw-collapsible') end
 
     if table.length(t) > COLLAPSIBLE then tbl:addClass('mw-collapsible') end
 
     if table.length(t) > COLLAPSED then tbl:addClass('mw-collapsed') end
 
     if table.length(t) > COLLAPSED then tbl:addClass('mw-collapsed') end
Line 315: Line 239:
 
     return tbl
 
     return tbl
 
end
 
end
 
  
 
function p.itemRecipes(frame)
 
function p.itemRecipes(frame)
Line 321: Line 244:
 
end
 
end
  
 +
--[[
 +
    If item ids are supplied through the named argument 'ids', the table must
 +
    be in the following form:
 +
 +
    {
 +
        { ['id'] = value_1 },
 +
        { ['id'] = value_2 },
 +
        .
 +
        .
 +
        .
 +
        { ['id'] = value_n }
 +
    }
  
 +
    The actual id values can be either numbers or strings.
 +
]]
 
function p._itemRecipes(args)
 
function p._itemRecipes(args)
 +
 +
    local items = {}
  
 
     if not args[1] or args[1] == '' then
 
     if not args[1] or args[1] == '' then
Line 328: Line 267:
 
     end
 
     end
  
     local items = {}
+
     if args['ids'] and type(args['ids']) == 'table' then
 +
        items = args['ids']
 +
    else
 +
        addItemIds(items, args[1])
 +
    end
  
    addItemIds(items, args[1])
 
 
     addOtherItemFields(items)
 
     addOtherItemFields(items)
 
     addRecipes(items)
 
     addRecipes(items)

Latest revision as of 05:11, 25 April 2025

Documentation for this module may be created at Module:Sandbox/Broono/Item Recipes/doc

local p = {}

local addSeparator = require('Module:AddSeparator')
local findId = require('Module:FindId')
local img = require('Module:Img')

local data = {}
data.craftingAugmenting = mw.loadData('Module:CraftingAugmenting/data')
data.items = mw.loadData('Module:Items/data')


local COLLAPSIBLE = 7
local COLLAPSED = 15
local SORTABLE = 7


local function strip(s)
    return s:match('^%s*(.-)%s*$')
end

local function split(s, sep)
   local t = {}
   if sep == nil or sep == '' then
      sep = '%s'
   end
   for m in s:gmatch('([^' .. sep .. ']+)') do
      table.insert(t, m)
   end
   return t
end

function table.length(t)
    local count = 0
    for _ in pairs(t) do count = count + 1 end
    return count
end

local function addItemIds(t, names)
    local _names = split(names, ';')
    for _, name in pairs(_names) do
        name = strip(name)
        if name ~= '' then
            local id = findId._findId({name, 'item'})
            if type(id) == 'number' then
                table.insert(t, {['id'] = id})
            else
                table.insert(t, {['error'] = {'name', name}})
            end
        end
    end
end

local function addOtherItemFields(t)
    for i in pairs(t) do
        if t[i].id then
            local id = tostring(t[i].id)
            local craftingStats
            if data.items[id] and data.items[id].craftingStats then
                craftingStats = data.items[id].craftingStats
            elseif data.items[id] then
                craftingStats = data.items[id]
            else
                t[i].error = { 'id', t[i].id }
            end
            if not t[i].error then
                t[i].name = data.items[id].name
                t[i].level = craftingStats.level
                t[i].experience = craftingStats.experience
                t[i].category = craftingStats.category
            end
        else
            t[i].error = {'id', 'nil'}
        end
    end
end

local function addRecipes(t)
    for i in pairs(t) do
    local id = tostring(t[i].id)
        if data.craftingAugmenting[id] and not t[i].error then
            t[i].recipes = {}
            if data.craftingAugmenting[id].crafting then
                for _, recipe in pairs(data.craftingAugmenting[id].crafting) do
                    table.insert(t[i].recipes, recipe.recipe)
                    t[i].skill = 'Crafting'
                end
            elseif data.craftingAugmenting[id].scrollcrafting then
                table.insert(t[i].recipes, data.craftingAugmenting[id].scrollcrafting)
                t[i].skill = 'Scrollcrafting'
            elseif data.craftingAugmenting[id].runecrafting then
                table.insert(t[i].recipes, data.craftingAugmenting[id].runecrafting)
                t[i].skill = 'Runecrafting'
            elseif data.craftingAugmenting[id].smithing then
                table.insert(t[i].recipes, data.craftingAugmenting[id].smithing)
                t[i].skill = 'Smithing'
            end
        elseif not t[i].error then
            t[i].error = {'recipe', id .. ' (' .. t[i].name .. ')'}
        end
    end
end

local function generateTableRecipe(t)
    local ingredients = {}
    for id, amt in pairs(t) do
        local name = data.items[id].name
        local image = img._img({name, 30})
        table.insert(ingredients, image .. ' x'.. addSeparator._addSeparator({amt}))
    end
    return table.concat(ingredients, ', ')
end

local function generateTableBody(t)

    local tbody = mw.html.create(nil)

    for i = 1, table.length(t) do

        local row = mw.html.create('tr')
        local rowspan = 0

        if t[i].error then
            local e
            if t[i].error[1] == 'recipe' then
                e = 'Could not find a recipe for item with id: ' .. t[i].error[2]
            else            
                e = '\'\'Could not find item with ' .. t[i].error[1] .. ': '
                e = e ..'\'\'\'' .. t[i].error[2] .. '\'\'\'.'
                if t[i].error[1] == 'name' then
                    e = e .. ' Please check spelling or update data modules.'
                end
            end

            row:tag('td')
                :css('text-align', 'center')
                :attr('colspan', 5)
                :wikitext(e)
        else
            rowspan = table.length(t[i].recipes)
            -- Icon
            row:node(mw.html.create('td')
                :attr('rowspan', rowspan)
                :css('text-align', 'center')
                :wikitext(img._img({t[i].name, 30, alt=''})))

            -- Name
            local name
            if t[i].name == mw.title.getCurrentTitle().fullText then
                name = '\'\'\'' .. t[i].name .. '\'\'\''
            else
                name = '\'\'\'[[' .. t[i].name .. ']]\'\'\''
            end
            row:node(mw.html.create('td')
                :attr('rowspan', rowspan)
                :attr('scope', 'row')
                :wikitext(name))

            -- Skill: Level
            local skill
            if t[i].category then
                skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ' (' .. t[i].category .. '): ' .. t[i].level
            else
                skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ': ' .. t[i].level
            end
            row:node(mw.html.create('td')
                :attr('rowspan', rowspan)
                :wikitext(skill))

            -- Experience
            row:node(mw.html.create('td')
                :attr('rowspan', rowspan)
                :css('text-align', 'center')
                :wikitext(addSeparator._addSeparator({t[i].experience})))

            -- Recipe
            row:node(mw.html.create('td')
                :wikitext(generateTableRecipe(t[i].recipes[1])))
        end
        tbody:node(row)

        -- More recipes if item has more than one
        if rowspan > 1 then
            for j = 2, rowspan do
            tbody
            :tag('tr')
                :tag('td')
                    :wikitext(generateTableRecipe(t[i].recipes[j]))
            end
        end
    end

    return tbody
end

local function generateTableHead()

    local thead = mw.html.create(nil)
    local row = mw.html.create('tr')

    row
    :tag('th')
        :attr('scope', 'col')
        :wikitext('Icon')
    :done()
    :tag('th')
        :attr('scope', 'col')
        :wikitext('Name')
    :done()
    :tag('th')
        :attr('scope', 'col')
        :wikitext('Skill: Level')
    :done()
    :tag('th')
        :attr('scope', 'col')
        :wikitext('Experience')
    :done()
    :tag('th')
        :attr('scope', 'col')
        :wikitext('Recipe')
    :done()

    thead:node(row)

    return thead
end

local function generateTable(t)
    local tbl = mw.html.create('table')

    tbl
    :addClass('wikitable')
    if table.length(t) > SORTABLE then tbl:addClass('sortable') end
    if table.length(t) > COLLAPSIBLE then tbl:addClass('mw-collapsible') end
    if table.length(t) > COLLAPSED then tbl:addClass('mw-collapsed') end

    tbl:node(generateTableHead())
    tbl:node(generateTableBody(t))

    return tbl
end

function p.itemRecipes(frame)
    return p._itemRecipes(frame:getParent().args)
end

--[[
    If item ids are supplied through the named argument 'ids', the table must
    be in the following form:

    {
        { ['id'] = value_1 },
        { ['id'] = value_2 },
        .
        .
        .
        { ['id'] = value_n }
    }

    The actual id values can be either numbers or strings.
]]
function p._itemRecipes(args)

    local items = {}

    if not args[1] or args[1] == '' then
        args[1] = mw.title.getCurrentTitle().fullText
    end

    if args['ids'] and type(args['ids']) == 'table' then
        items = args['ids']
    else
        addItemIds(items, args[1])
    end

    addOtherItemFields(items)
    addRecipes(items)

    return generateTable(items)
end

return p