Module:Rocky Horror/Sandbox

From RuneRealm Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Rocky Horror/Sandbox/doc

-- Rewrite of Template:RockLine and Template:Mine locations,
-- which were originally made by Towelcat and Jakesterwars.

local p = {}

local yesno = require('Module:Yesno')
local pt = require('Module:Paramtest')

-- Table format: argument = page, name, picture, level, experience
local rocks = {
    ['clay']         = { 'Clay rock', 'Clay', 'Clay', '1', '5' }, 
    ['rune essence'] = { 'Rune Essence (rock)', 'Rune Essence', 'Rune essence', '1', '5' }, 
    ['copper']       = { 'Copper rock', 'Copper', 'Copper ore', '1', '17.5' }, 
    ['tin']          = { 'Tin rock', 'Tin', 'Tin ore', '1', '17.5' }, 
    ['limestone']    = { 'Pile of Rock', 'Limestone', 'Limestone', '10', '26.5' },

    ['blurite']   = { 'Blurite rock', 'Blurite', 'Blurite ore', '10', '17.5' }, 
    ['iron']      = { 'Iron rock', 'Iron', 'Iron ore', '15', '35' }, 
    ['elemental'] = { 'Elemental rock', 'Elemental', 'Elemental ore', '20', '0' }, 
    ['daeyalt']   = { 'Daeyalt vein', 'Daeyalt', 'Daeyalt ore', '20', '17' }, 
    ['silver']    = { 'Silver rock', 'Silver', 'Silver ore', '20', '40' },

    ['volcanic ash']  = { 'Ash pile', 'Volcanic ash', 'Volcanic ash', '22', '10' }, 
    ['coal']          = { 'Coal rock', 'Coal', 'Coal', '30', '50' }, 
    ['ore vein']      = { 'Ore vein', 'Ore vein', 'Pay-dirt', '30', '60' }, 
    ['sandstone']     = { 'Sandstone rock', 'Sandstone', 'Sandstone (10kg)', '35', '30-60' }, 
    ['dense essence'] = { 'Dense runestone', 'Dense essence', 'Dense essence block', '38', '12' },

    ['gem']              = { 'Gem rock', 'Gem', 'Uncut red topaz', '40', '65' }, 
    ['gold']             = { 'Gold rock', 'Gold', 'Gold ore', '40', '65' }, 
    ['volcanic sulphur'] = { 'Volcanic sulphur (rock)', 'Volcanic sulphur', 'Volcanic sulphur', '42', '25' }, 
    ['granite']          = { 'Granite rock', 'Granite', 'Granite (5kg)', '45', '50-75' }, 
    ['mithril']          = { 'Mithril rock', 'Mithril', 'Mithril ore', '55', '80' },

    ['lunar']      = { 'Lunar rock', 'Lunar', 'Lunar ore', '60', '0' }, 
    ['lovakite']   = { 'Lovakite rock', 'Lovakite', 'Lovakite ore', '65', '10' }, 
    ['adamantite'] = { 'Adamantite rock', 'Adamantite', 'Adamantite ore', '70', '95' }, 
    ['soft clay']  = { 'Soft clay rock', 'Soft clay', 'Soft clay', '70', '5' }, 
    ['salt']       = { 'Salt Mine', 'Salt', 'Basalt', '72', '5' },

    ['runite']   = { 'Runite rock', 'Runite', 'Runite ore', '85', '125' }, 
    ['amethyst'] = { 'Amethyst crystals', 'Amethyst', 'Amethyst', '92', '240' }
}

function p.rocktable(frame)
    local args = frame:getParent().args
    return p._rocktable(args)
end

-- Renders a list of rocks and quantities thereof present in the mine.
function p._rocktable(args)
    -- Fetch and validate input parameters
    local quantity = {}
    local namenotes = nil
    local members = nil
    for k, v in pairs(args) do
        lk = k:lower()
        if rocks[lk] ~= nil then
            quantity[lk] = v
        elseif lk == 'namenotes' then
            namenotes = mw.text.trim(args[k])
        elseif lk == 'members' then
            members = yesno(args[k])
        else
            error(string.format('Unrecognized argument: %s', k))
        end
    end

    local curtitle = mw.title.getCurrentTitle()

    -- Export data to SMW
    local rockdata = {}
    for k, v in pairs(quantity) do
        rockdata[rocks[k][2]] = v 
    end
    if namenotes ~= nil then
    	rockdata['Name notes'] = namenotes
    end
    if members ~= nil then
        rockdata['Is members only'] = members
    end
    local smwdata = {
        ['Rocks JSON'] = mw.text.jsonEncode(rockdata, 0)
    }
    if curtitle:inNamespace('') then
        mw.smw.set(smwdata)
    end

    -- Render the page
    local restbl = mw.html.create('table')
        :addClass('wikitable sortable align-center-1')
        :tag('tr')
        :node('<th rowspan="2" colspan="2">Rock</th>')
        :node('<th colspan="2">[[File:Mining icon.png|21x21px|link=Mining|alt=Mining]] [[Mining]]</th>')
        :node('<th rowspan="2">Quantity</th>')
        :done()
        :tag('tr')
        :node('<th>Level</th>')
        :node('<th>Exp</th>')
        :done()

    -- Render rows
    for k, v in pairs(quantity) do
        local tr = restbl:tag('tr')
            :tag('td'):wikitext(string.format('[[File:%s.png|link=%s]]', rocks[k][3], rocks[k][1])):done()
            :tag('td'):wikitext(string.format('[[%s|%s]]', rocks[k][1], rocks[k][2])):done()
            :tag('td'):wikitext(rocks[k][4]):done()
            :tag('td'):wikitext(rocks[k][5]):done()
            :tag('td'):wikitext(quantity[k]):done()
    end

    return restbl
end

function p.minelocations(frame)
    local args = frame:getParent().args
    return p._minelocations(args)
end

-- Renders a list of mine locations for the specified rock.
function p._minelocations(args)
    local rock = pt.default_to(args[1], nil)
    assert(rock ~= nil and rocks[rock:lower()] ~= nil, 'You need to specify a valid rock')

    local rockdata = rocks[rock:lower()]

    -- Fetch data
    query = {
        '[[Rocks JSON::+]]',
        '?=#-',
        '?Rocks JSON #- = json',
        '?Is members only #- = members'
    }
    query.offset = 0
    query.limit = 1000

    smwdata = mw.smw.ask(query)
    assert(smwdata ~= nil and #smwdata > 0, 'Failed to fetch SMW data')

    -- Post-process
    local data = {}
    for _, e in ipairs(smwdata) do
        if type(e['json']) == 'table' then
            for _, f in ipairs(e['json']) do
                table.insert(data, {
                    name = e[1],
                    rockline =  mw.text.jsonDecode(f),
                    members = e['members']
                })
            end
        else
            table.insert(data, {
                name = e[1],
                rockline = mw.text.jsonDecode(e['json']),
                members = e['members']
            })
        end
    end
    smwdata = nil

    -- Render the page
    local restbl = mw.html.create('table')
        :addClass('wikitable sortable')
        :tag('tr')
        :tag('th'):wikitext('Location'):done()
        :tag('th'):wikitext('Rocks'):done()
        :tag('th'):wikitext('Members'):done()
        :done()

    -- Render rows
    for _, row in ipairs(data) do
        local rockname = rockdata[2]
        local rockline = row['rockline']

        if rockline[rockname] ~= nil then
            local qty = tonumber(rockline[rockname])

            if qty ~= nil then
            	local members = row['members']
            	if rockline['Is members only'] ~= nil then
                    members = rockline['Is members only']
            	end

                local tr = restbl:tag('tr')
                    :tag('td'):wikitext(string.format('[[%s|%s%s]]', row['name'], row['name'], rockline['Name notes'] and ' ' .. rockline['Name notes'] or '')):done()
                    :tag('td'):wikitext(qty):done()
                    :tag('td'):wikitext(members and '[[File:Member icon.png|link=|Members]]' or '[[File:Free-to-play icon.png|link=|Free-to-play]]'):done()
            else
                error(string.format('Non-numeric quantity of rock %s in mine %s', rockname, row['name']))
            end
        end
    end

    return restbl
end

--[[ DEBUG COPYPASTA
= p._rocktable({namenotes='Test notes', copper=4, tin=3, Iron=2, ['volcanic ash']=10})
= p._minelocations({'Iron'})
--]]

return p