Module:Quest reward/sandbox: Difference between revisions

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


function p._shared.reward_tbl_head()
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
     tr1:tag('th')
        :tag('th')
        :attr('class', 'unsortable')
            :attr('class', 'unsortable')
             :wikitext(i18n.quest_reward.character_class)
             :wikitext(i18n.quest_reward.character_class)
     for _, class in ipairs(m_game.constants.characters_order) do
     tr1:tag('th')
        tr:tag('th')
        :attr('rowspan', 1)
            :attr('rowspan', 2)
        :attr('colspan', 8)
            :wikitext(string.format('[[%s]]', m_game.constants.characters[class].name))
        :wikitext(string.format('[[%s]]', class))
     end
    local tr2 = tbl:tag('tr')
 
    tr2:tag('th')
    tbl
    :wikitext(i18n.quest_reward.quest)  
         :tag('tr')
    tr2:tag('th')
            :tag('th')
        :attr('rowspan', 1)
                :wikitext(i18n.quest_reward.quest)
        :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 118: Line 122:
     end
     end


    local reward_map = {"quest_rewards","vendor_rewards"}
     local valid_type = false
     local valid_type = false
    local p_where = tpl_args.q_where
     local vendor_rewards = {}
     local vendor_rewards = {}
     if tpl_args.type == 'vendor_rewards' or tpl_args.type == 'all_rewards' then
     if tpl_args.type == 'vendor_rewards' or tpl_args.type == 'all_rewards' then
     local q_where = ""
     local q_where = tpl_args.q_where
         if p_where and tpl_args.type == 'all_rewards' then
         if q_where and tpl_args.type == 'all_rewards' then
         q_where = string.gsub(p_where, "quest", "vendor")
         q_where = string.gsub(q_where, "all", "vendor")
     end
     end
         vendor_rewards = m_cargo.query(
         vendor_rewards = m_cargo.query(
Line 146: Line 148:
     local quest_rewards = {}
     local quest_rewards = {}
     if tpl_args.type == 'quest_rewards' or tpl_args.type == 'all_rewards' then
     if tpl_args.type == 'quest_rewards' or tpl_args.type == 'all_rewards' then
     local q_where = ""
     local q_where = tpl_args.q_where
         if p_where and tpl_args.type == 'all_rewards' then
         if q_where and tpl_args.type == 'all_rewards' then
         q_where = string.gsub(p_where, "vendor", "quest")
         q_where = string.gsub(q_where, "all", "quest")
     end
     end
         quest_rewards = m_cargo.query(
         quest_rewards = m_cargo.query(
Line 176: Line 178:
     -- Build output table
     -- Build output table
     -- ------------------------------------------------------------------------
     -- ------------------------------------------------------------------------
     local tbl = p._shared.reward_tbl_head()
    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') and #quest_rewards == 0 then
     if tpl_args.type == 'quest_rewards' or tpl_args.type == 'all_rewards' then
        return tostring(tbl)
    if #quest_rewards == 0 then
    end
        return tostring(tbl)
   
else
    if (tpl_args.type == 'vendor_rewards' or tpl_args.type == 'all_rewards') and #vendor_rewards == 0 then
    table.insert(data_pure, quest_rewards)
        return tostring(tbl)
    end
     end
     end


     local quest_order = {}
     local quest_in_order = {}
     local quests = {}
     local quests = {}
     local pages = {}
     local pages = {}
Line 193: Line 206:
     -- remap data to quests[questid].classes[class]
     -- remap data to quests[questid].classes[class]
     --
     --
      
     local class_to_attribute_map = {
    for reward_type, data in ipairs(data_pure) do
    Duelist = "StrDex",
    for _, row in ipairs(data) do
Marauder = "Str",
        local classes = quests[row[reward_map[reward_type] .. '.quest']]
Ranger = "Dex",
        if classes == nil then
Scion = "StrDexInt",
            table.insert(quest_order, row[reward_map[reward_type] .. '.quest'])
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 = {}
            classes = {}
            quests[row[reward_map[reward_type] .. '.quest']] = classes
            quests[reward_type_index][data[reward_type .. '.quest']] = classes
        end
        end
        if data[reward_type .. '.classes'] then
        if row[reward_map[reward_type] .. '.classes'] then
            for _, class in ipairs(m_util.string.split(data[reward_type .. '.classes'], ',')) do
            classes[-1] = {}
                if classes[reward_type_index][class] == nil then
            for _, class in ipairs(m_util.string.split(row[reward_map[reward_type] .. '.classes'], ',')) do
                    classes[reward_type_index][class] = {}
                if classes[class] == nil or p_where:match("class_ids") then
                end
                    classes[class] = {}
               
                if class == tpl_args.class then
                table.insert(classes[reward_type_index][class], data)
                end
                end
                table.insert(classes[class], row)
            end
            end
        else
        else
            if classes[0] == nil then
            if classes[reward_type_index][0] == nil then
                    classes[0] = {}
                classes[reward_type_index][0] = {}
                end
            end
            table.insert(classes[0], row)
            table.insert(reward_map[reward_type_index][reward_type_index], data)
        end
        end
        pages[data[reward_type .. '._pageName']] = true
        pages[row[reward_map[reward_type] .. '._pageName']] = true
end
    end
     end
     end
      
      
Line 281: 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]


Line 293: Line 321:
             end
             end
             tr:tag('td')
             tr:tag('td')
                 :attr('colspan', 7)
                 :attr('colspan', 4)
                 :attr('style', 'text-align: center;')
                 :attr('style', 'text-align: center;')
                 :wikitext(element(classes[0]))
                 :wikitext(element(classes[0]))
Line 306: Line 334:
             end
             end
             for _, class in ipairs(m_game.constants.characters_order) do
             for _, class in ipairs(m_game.constants.characters_order) do
                tr:tag('td')
            if class == tpl_args.class then
                    :wikitext(element(classes[m_game.constants.characters[class].name]))
                tr:tag('td')
                    :wikitext(element(classes[m_game.constants.characters[class].name]))
                end
             end
             end
         end
         end

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