Module:Quest reward/sandbox: Difference between revisions

From Path of Exile Wiki
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
 
(10 intermediate revisions by the same user not shown)
Line 49: Line 49:
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------


function p._shared.reward_tbl_head(class)
function p._shared.reward_tbl_head(class, reward_map)
     local tbl = mw.html.create('table')
     local tbl = mw.html.create('table')
     tbl:attr('class', 'wikitable sortable')
     tbl:attr('class', 'wikitable sortable')
     local tr = tbl:tag('tr')
     local tr1 = tbl:tag('tr')
     tr:tag('th')
     tr1:tag('th')
            :attr('class', 'unsortable')
        :attr('class', 'unsortable')
             :wikitext(i18n.quest_reward.character_class)
             :wikitext(i18n.quest_reward.character_class)
     tr:tag('th')
     tr1:tag('th')
         :attr('rowspan', 1)
         :attr('rowspan', 1)
        :attr('colspan', 8)
         :wikitext(string.format('[[%s]]', class))
         :wikitext(string.format('[[%s]]', class))
     tbl:tag('tr')
     local tr2 = tbl:tag('tr')
        :tag('th')
    tr2:tag('th')
                :wikitext(i18n.quest_reward.quest)
    :wikitext(i18n.quest_reward.quest)
    tr2:tag('th')
        :attr('rowspan', 1)
        :attr('colspan', 4)
        :wikitext(string.format('[[%s]]', reward_map[1]))
    tr2:tag('th')
        :attr('rowspan', 1)
        :attr('colspan', 4)
        :wikitext(string.format('[[%s]]', reward_map[2]))
     return tbl
     return tbl
end
end
Line 169: Line 178:
     -- Build output table
     -- Build output table
     -- ------------------------------------------------------------------------
     -- ------------------------------------------------------------------------
     local tbl = p._shared.reward_tbl_head(tpl_args.class)
    local reward_map = {"vendor","quest"}
     local tbl = p._shared.reward_tbl_head(tpl_args.class, reward_map)
      
      
     local data_pure = {}
     local data_pure = {}
Line 189: Line 199:
     end
     end


     local quest_order = {}
     local quest_in_order = {}
     local quests = {}
     local quests = {}
     local pages = {}
     local pages = {}
Line 196: Line 206:
     -- remap data to quests[questid].classes[class]
     -- remap data to quests[questid].classes[class]
     --
     --
    local reward_map = {"vendor","quest"}
     local class_to_attribute_map = {
     local class_to_attribute_map = {
    Duelist = "StrDex",
    Duelist = "StrDex",
Line 206: Line 215:
Witch = "Int"
Witch = "Int"
}
}
   
local data_types = {}
local reward_type = string.gsub(tpl_args.type, "all", reward_map[reward_type_index])
if tpl_args.type == 'vendor_rewards' or  tpl_args.type == "all_rewards" then
    for _, row in ipairs(data) do
table.insert(data_types, "vendor_rewards")
        local classes = quests[row[reward_type .. '.quest']]
end
        if classes == nil then
if tpl_args.type == 'quest_rewards' or  tpl_args.type == "all_rewards" then
            table.insert(quest_order, row[reward_type .. '.quest'])
table.insert(data_types, "quest_rewards")
            classes = {}
end
            quests[row[reward_type .. '.quest']] = classes
for reward_type_index, reward_type in ipairs(data_types) do
        end
for _, data in ipairs(data_pure[reward_type_index]) do
 
        local classes = quests[data[reward_type .. '.quest']]
        if row[reward_type .. '.classes'] then
        if quest_in_order[reward_type_index] == nil then
            classes[-1] = {}
            table.insert(quest_in_order[reward_type_index], data[reward_type .. '.quest'])
            for _, class in ipairs(m_util.string.split(row[reward_type .. '.classes'], ',')) do
            classes = {}
                if classes[class] == nil then
            quests[reward_type_index][data[reward_type .. '.quest']] = classes
                    classes[class] = {}
        end
                end
        if data[reward_type .. '.classes'] then
               
            for _, class in ipairs(m_util.string.split(data[reward_type .. '.classes'], ',')) do
                if class == tpl_args.class then
                if classes[reward_type_index][class] == nil then
                table.insert(classes[class], row)
                    classes[reward_type_index][class] = {}
                end
                end
            end
               
        else
                if class == tpl_args.class then
            if classes[0] == nil then
                table.insert(classes[reward_type_index][class], data)
                classes[0] = {}
                end
            end
            end
            table.insert(classes[0], row)
        else
        end
            if classes[reward_type_index][0] == nil then
 
                classes[reward_type_index][0] = {}
        pages[row[reward_type .. '._pageName']] = true
            end
            table.insert(reward_map[reward_type_index][reward_type_index], data)
        end
        pages[data[reward_type .. '._pageName']] = true
end
     end
     end
      
      
Line 296: Line 309:
     end
     end


     for _, quest_key in ipairs(quest_order) do
     for _, quest_key in ipairs(quest_in_order) do
         local classes = quests[quest_key]
         local classes = quests[quest_key]



Latest revision as of 16:19, 18 August 2023

This is the module sandbox page for Module:Quest reward (diff).

--
-- Module for bestiary templates
--

local m_game = require('Module:Game')
local m_util = require('Module:Util')
local f_item_link = require('Module:Item link').item_link
local getArgs = require('Module:Arguments').getArgs
local m_cargo = require('Module:Cargo')

local p = {}
p._shared = {}

-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------

local i18n = {
    errors = {
        invalid_table = 'Invalid table selected. Valid choices are either quest or vendor',
        invalid_type = 'type must be either quest_rewards or vendor_rewards',
    },
    messages = {
        storage = 'Attempted to store rows %s to %s in "%s_rewards" table',
    },
    quest_reward = {
        character_class = 'Class →',
        quest = 'Quest ↓',
        row_header = '[[%s]]<br>Act %s',
        item_level = 'iLvl %s',
        links = '%s-linked',
    },
}

-- ----------------------------------------------------------------------------
-- Cargo
-- ----------------------------------------------------------------------------

local tables = {}

-- ----------------------------------------------------------------------------
-- Helper functions and globals
-- ----------------------------------------------------------------------------

local h = {}

-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------

function p._shared.reward_tbl_head(class, reward_map)
    local tbl = mw.html.create('table')
    tbl:attr('class', 'wikitable sortable')
    local tr1 = tbl:tag('tr')
    tr1:tag('th')
        :attr('class', 'unsortable')
            :wikitext(i18n.quest_reward.character_class)
    tr1:tag('th')
        :attr('rowspan', 1)
        :attr('colspan', 8)
        :wikitext(string.format('[[%s]]', class))
    local tr2 = tbl:tag('tr')
    tr2:tag('th')
    	:wikitext(i18n.quest_reward.quest) 
    tr2:tag('th')
        :attr('rowspan', 1)
        :attr('colspan', 4)
        :wikitext(string.format('[[%s]]', reward_map[1]))
    tr2:tag('th')
        :attr('rowspan', 1)
        :attr('colspan', 4)
        :wikitext(string.format('[[%s]]', reward_map[2]))
    return tbl
end

function p._shared.reward_tbl_row_head(tr, rtbl, row)
    local npc = ''
    if row[rtbl .. '.npc'] then
        npc = string.format('<br>[[%s]]', row[rtbl .. '.npc'])
    end

    tr
        :tag('th')
            :wikitext(string.format(i18n.quest_reward.row_header, row[rtbl .. '.quest'], row[rtbl .. '.act']))
            :wikitext(npc)
end

function p._shared.reward_tbl_extra_info(row)
    local value = {}
    if row['quest_rewards.item_level'] and row['quest_rewards.item_level'] ~= 0 then
        value[#value+1] = string.format(i18n.quest_reward.item_level, row['quest_rewards.item_level'])
    end
    -- TODO: i18n rarity name?
    if row['quest_rewards.rarity'] then
        value[#value+1] = m_util.html.poe_color(string.lower(row['quest_rewards.rarity']), row['quest_rewards.rarity'])
    end
    if row['quest_rewards.sockets'] and row['quest_rewards.sockets'] ~= 0 then
        value[#value+1] = string.format(i18n.quest_reward.links, row['quest_rewards.sockets'])
    end

    return table.concat(value, ', ')
end

function p.quest_reward_table(frame)
    --[[
    Displays a table of quest rewards from a certain quest.

    Examples
    --------
    = p.quest_reward_table{type='vendor_rewards', q_where='quest="A Fixture of Fate"'}
    ]]

    -- Get args
    local tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
    if tpl_args.item_link then
        tpl_args.item_link = m_util.cast.boolean(tpl_args.item_link)
    else
        tpl_args.item_link = true
    end

    local valid_type = false
    local vendor_rewards = {}
    if tpl_args.type == 'vendor_rewards' or tpl_args.type == 'all_rewards' then
    	local q_where = tpl_args.q_where
        if q_where and tpl_args.type == 'all_rewards' then
        	q_where = string.gsub(q_where, "all", "vendor")
    	end
        vendor_rewards = m_cargo.query(
            {'vendor_rewards'},
            {
                'vendor_rewards.quest',
                'vendor_rewards.act',
                'vendor_rewards.classes',
                'vendor_rewards.npc',
                'vendor_rewards._pageName',
            },
            {
                where=q_where,
                orderBy='vendor_rewards.act ASC, vendor_rewards.quest_id ASC, vendor_rewards._pageName ASC',
                limit=5000,
            }
        )
        valid_type = true;
    end
    local quest_rewards = {}
    if tpl_args.type == 'quest_rewards' or tpl_args.type == 'all_rewards' then
    	local q_where = tpl_args.q_where
        if q_where and tpl_args.type == 'all_rewards' then
        	q_where = string.gsub(q_where, "all", "quest")
    	end
        quest_rewards = m_cargo.query(
            {'quest_rewards'},
            {
                'quest_rewards.quest',
                'quest_rewards.act',
                'quest_rewards.classes',
                'quest_rewards.sockets',
                'quest_rewards.item_level',
                'quest_rewards.rarity',
                'quest_rewards._pageName',
            },
            {
                where=q_where,
                orderBy='quest_rewards.act ASC, quest_rewards.quest_id ASC, quest_rewards._pageName ASC',
                limit=5000,
            }
        )
        valid_type = true;
    end
    if not valid_type then
        error(i18n.errors.invalid_type, tpl_args.type)
    end

    -- ------------------------------------------------------------------------
    -- Build output table
    -- ------------------------------------------------------------------------
    local reward_map = {"vendor","quest"}
    local tbl = p._shared.reward_tbl_head(tpl_args.class, reward_map)
    
    local data_pure = {}
    
    if tpl_args.type == 'vendor_rewards' or tpl_args.type == 'all_rewards' then
    	if #vendor_rewards == 0 then
        	return tostring(tbl)
    	else
    		table.insert(data_pure, vendor_rewards)
	    end
    end

    if tpl_args.type == 'quest_rewards' or tpl_args.type == 'all_rewards' then
    	if #quest_rewards == 0 then
        	return tostring(tbl)
		else
		    table.insert(data_pure, quest_rewards)
	    end
    end

    local quest_in_order = {}
    local quests = {}
    local pages = {}

    --
    -- remap data to quests[questid].classes[class]
    --
    local class_to_attribute_map = {
	    Duelist = "StrDex",
		Marauder = "Str",
		Ranger = "Dex",
		Scion = "StrDexInt",
		Shadow = "DexInt",
		Templar = "StrInt",
		Witch = "Int"
	}
	local data_types = {}
	if tpl_args.type == 'vendor_rewards' or  tpl_args.type == "all_rewards" then
		table.insert(data_types, "vendor_rewards")
	end
	if tpl_args.type == 'quest_rewards' or  tpl_args.type == "all_rewards" then
		table.insert(data_types, "quest_rewards")
	end
	for reward_type_index, reward_type in ipairs(data_types) do
		for _, data in ipairs(data_pure[reward_type_index]) do
        	local classes = quests[data[reward_type .. '.quest']]
	        if quest_in_order[reward_type_index] == nil then
	            table.insert(quest_in_order[reward_type_index], data[reward_type .. '.quest'])
	            classes = {}
	            quests[reward_type_index][data[reward_type .. '.quest']] = classes
	        end
	        if data[reward_type .. '.classes'] then
	            for _, class in ipairs(m_util.string.split(data[reward_type .. '.classes'], ',')) do
	                if classes[reward_type_index][class] == nil then
	                    classes[reward_type_index][class] = {}
	                end
	                
	                if class == tpl_args.class then
	                	table.insert(classes[reward_type_index][class], data)
	                end
	            end
	        else
	            if classes[reward_type_index][0] == nil then
	                classes[reward_type_index][0] = {}
	            end
	            table.insert(reward_map[reward_type_index][reward_type_index], data)
	        end
	        pages[data[reward_type .. '._pageName']] = true
		end
    end
    
    --
    -- Cache item data
    --
    local item_data
    if tpl_args.item_link then
        local pages_array = {}
        for page, _ in pairs(pages) do
            pages_array[#pages_array+1] = page
        end

        local fields = {
            'items.name',
            'items.inventory_icon',
        }

        if m_util.cast.boolean(tpl_args.no_html) ~= true then
            fields[#fields+1] = 'items.html'
        end

        item_data = m_cargo.map_results_to_id{
            results=m_cargo.array_query{
                tables={'items'},
                fields=fields,
                id_field='items._pageName',
                id_array=pages_array,
                query={
                    limit=5000,
                },
            },
            field='items._pageName',
        }
    end
    --
    -- Output rows
    --

    local function element(rows)
        if rows == nil then
            return ''
        end
        local out = {}
        for _, row in ipairs(rows) do
            local reward = row[tpl_args.type .. '._pageName']
            if tpl_args.item_link then
                local idata = item_data[reward][1]
                reward = f_item_link{page=reward, name=idata['items.name'], inventory_icon=idata['items.inventory_icon'] or '', html=idata['items.html'] or '', skip_query=true}
            else
                reward = string.format('[[%s]]', reward)
            end
            local info = p._shared.reward_tbl_extra_info(row)
            if info ~= '' then
                out[#out+1] = string.format('%s (%s)', reward, info)
            else
                out[#out+1] = reward
            end
        end
        return table.concat(out, '<br>')
    end

    for _, quest_key in ipairs(quest_in_order) do
        local classes = quests[quest_key]

        if classes[0] then
            local tr = tbl:tag('tr')
            for _, class in pairs(classes) do
                if class[1] then
                    p._shared.reward_tbl_row_head(tr, tpl_args.type, class[1])
                    break
                end
            end
            tr:tag('td')
                :attr('colspan', 4)
                :attr('style', 'text-align: center;')
                :wikitext(element(classes[0]))
        end
        if classes[-1] then
            local tr = tbl:tag('tr')
            for _, class in pairs(classes) do
                if class[1] then
                    p._shared.reward_tbl_row_head(tr, tpl_args.type, class[1])
                    break
                end
            end
            for _, class in ipairs(m_game.constants.characters_order) do
            	if class == tpl_args.class then
                	tr:tag('td')
                    	:wikitext(element(classes[m_game.constants.characters[class].name]))
                end
            end
        end
    end

    return tostring(tbl)
end

-- ----------------------------------------------------------------------------
-- End
-- ----------------------------------------------------------------------------

return p