Module:Gear/Table

From Fantasy Life Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Gear/Table/doc

-- Module Gear/Table contains functions to create a table for each type of Gear
-- Uses Data stored in Module Gear/xxxxx/Data

local gear = {
    'Longswords', 'Greatswords', 'Bows', 'Staves', 'Daggers',
    'Pickaxes', 'Axes', 'FishingRods', 'FryingPans', 'Hammers', 'Saws', 'Needles', 'Flasks',
    'Head', 'Shields', 'Accessories', 'Body', 'Legs', 'Hand', 'Feet' 
}

-- Function to fill in the right lives usable by the item
--    @function        usableList
--    @param            {v} Item data
--    @param            {row} Table Row string
--    @returns        {row} Table Row string with an aditional cell for Usable Lifes
local function usableList(v, row)
    if (v.Usable[1] == "All") then
        return row..('| style="text-align:center" | All\n')
    end
    
    row = row..('| style="text-align:center; padding:3px" | ')
    for i, live in pairs(v.Usable) do
        row = row..'<sup>[[File:'..live..' icon 1.png|link='..live..']]</sup>'
    end
    return row..('\n')
end

--Function to calculate the Stat1Value value of an item depending on its quality
--	@param			{value} the default Stat1Value value
--	@param			{quality} the quality of the item, between 1 (good) and 4 (Divine)
--	@returns		{value} return the calculated value if the input value was an int, the unmodified input value otherwise
local function calculateStat1Value(value, quality)
    if tonumber(value) then
        return math.floor(value*(1+(quality)/10)) + quality
    else
        return value
    end
end

-- Function to fill first stat values
--    @function        stat1Value
--    @param            {v} Item data
--    @param            {row} Table Row string
--    @returns        {row} Table Row string with aditional cell/s for item Attack/Power
local function stat1Value(v, row)
    if (v.CraftClass == nil) then
        row = row..('| style="opacity:0" | '..v.Stat1Value..'\n'
            ..'| style="opacity:0" | '..v.Stat1Value..'\n'
            ..'| style="text-align:center"  | '..v.Stat1Value..'\n'
            ..'| style="opacity:0" | '..v.Stat1Value..'\n'
            ..'| style="opacity:0" | '..v.Stat1Value..'\n')
        return row
    end
    row = row..('| style="text-align:center" | '..v.Stat1Value..'\n'
        ..'| style="text-align:center" | '..calculateStat1Value(v.Stat1Value, 1)..'\n'
        ..'| style="text-align:center" | '..calculateStat1Value(v.Stat1Value, 2)..'\n'
        ..'| style="text-align:center" | '..calculateStat1Value(v.Stat1Value, 3)..'\n'
        ..'| style="text-align:center" | '..calculateStat1Value(v.Stat1Value, 4)..'\n')
    return row
end

-- Function to fill in the right Gear Type by the item
--    @function        gearType
--    @param            {c} Item Type String
--    @param            {row} Table Row string
--    @returns        {row} Table Row string with an aditional cell for Gear Type
local function gearType(c, row)
    row = row..('|<sup>[[File:')
    if ( string.find(c, 'Longswords') ) then row = row..('Paladin icon 1.png|link=Longswords') end
    if ( string.find(c, 'Greatswords') ) then row = row..('Mercenary icon 1.png|link=Greatswords') end
    if ( string.find(c, 'Bows') ) then row = row..('Hunter icon 1.png|link=Bows') end
    if ( string.find(c, 'Staves') ) then row = row..('Magician icon 1.png|link=Staves') end
    if ( string.find(c, 'Daggers') ) then row = row..('Dagger Icon 1.png|link=Daggers') end
    if ( string.find(c, 'Pickaxes') ) then row = row..('Miner icon 1.png|link=Pickaxes') end
    if ( string.find(c, 'Axes') ) then row = row..('Woodcutter icon 1.png|link=Axes') end
    if ( string.find(c, 'Fishing Rods') ) then row = row..('Angler icon 1.png|link=Fishing Rods') end
    if ( string.find(c, 'Frying Pans') ) then row = row..('Cook icon 1.png|link=Frying Pans') end
    if ( string.find(c, 'Hammers') ) then row = row..('Blacksmith icon 1.png|link=Hammers') end
    if ( string.find(c, 'Saws') ) then row = row..('Carpenter icon 1.png|link=Saws') end
    if ( string.find(c, 'Needles') ) then row = row..('Tailor icon 1.png|link=Needles') end
    if ( string.find(c, 'Flasks') ) then row = row..('Alchemist icon 1.png|link=Flasks') end
    return row..(']]</sup>\n')
end

-- Function to build each row of the table / Main Tr in Table
--    @function        buildrow
--    @param            {row} Table Row string
--    @param            {v} All data of specific row/item at the current cicle
--    @param            {k} Name of the item
--    @param            {Armour} Boolean used to add adcitional cells for Armour and Shields Table
--    @param            {Shield} Boolean used to add adcitional cells for Shields Table
--    @param            {Category} Boolean used to add adcitional cells for type of all Tools and Weapons Table
--    @returns        {row} Table Row with all that needs.
local function buildrow(row, v, k, Armour, Shield, Category)
    row = row..('|- \n| style="padding:4px" | [[File:'..k..'.png|60x54px|center]]\n| [[')
    
    -- Adding extra lines in Item Name column if item is special (Password, lunares Coins or a DLC exclusive Item) (And for Body the Full tag)    
    if ( string.find(v.Sold, 'Pass') and string.find(v.Sold, 'Coins') ) then
        row = row..k..']] <sup>[[Passwords|PWD]]/[[Lunares Coins|LC]]</sup>\n'
    elseif ( string.find(v.Sold, 'Pass') ) then
        row = row..k..']] <sup>[[Passwords|PWD]]</sup>\n'
    elseif ( string.find(v.Sold, 'Coins') ) then 
        row = row..k..']] <sup>[[Lunares Coins|LC]]</sup>\n'
    elseif ( v.DLC ) then
        row = row..k..']] <sup>[[Origin Island|OI]]</sup>\n'
    elseif ( (v.Subtype ~= nil) and string.find(v.Subtype, 'full') ) then 
        row = row..k..']] <sup>Full</sup>\n'
    else 
        row = row..k..']]\n'
    end
    
    -- Adding extra column for tools and weapons in All tools and All weapons table
    if ( Category and not(Armour)) then row = gearType(v.Type, row)    end
    
    row = row..('| [[File:'..v.Rarity..' Stars.png]]\n| style="text-align:center" | ')
    
    if( v.SkillLvl == 0 ) then row = row..'--\n'
    else row = row..v.SkillLvl..'\n' end
    
    row = stat1Value(v, row)
    
    if Armour then row = row..'| style="text-align:center" | '..v.Stat2Value..'\n' end
    
    if(v.Special == nil) then
        row = row..('| '.."------"..'\n')
    else
        row = row..('| '..v.Special..'\n')
    end
    
    row = usableList(v, row)
    
    -- Only armour has different gender, excluding Shields
    if ( Armour and not(Shield) ) then
        if (v.Gender ~= nil) then
            row = row..'| style="text-align:center" | [[File:'..v.Gender..' only.png]]\n'
        else
            row = row..'|\n'
        end
    end
    return row
end

-- Fucntion use to create all Rows
--    @function        cicle
--    @param            {data} All data of specific Gear Type (All Longswords or all Hammers, etc ...)
--    @param            {Armour} Boolean used to add adcitional cells for Armour and Shields Table
--    @returns        {row} Table Row with all mandatory cells filled.
local function cicle(data, Armour, Shield, Category, Filter)
    local ordered_keys = {}
    local row = ''
    
    -- k = array keys
    for k in pairs(data) do
        table.insert(ordered_keys, k)
    end
    
    -- lua pairs function doesn't iterate with any order
    -- Default sort order -> Rarity > Skill Level > Item Power
    table.sort(ordered_keys, function(a,b) 

        --First sort by Rarity
        return (data[a].Rarity < data[b].Rarity) or

        --If Rarity is the same sorts by Skill Level
       (data[a].Rarity == data[b].Rarity and data[a].SkillLvl < data[b].SkillLvl) or
       
       --If both Rarity and Skill Level is the same shorts by Stat1Value (the power of the item)
       (data[a].Rarity == data[b].Rarity and data[a].SkillLvl == data[b].SkillLvl and
        (tonumber(data[a].Stat1Value) or 0) < (tonumber(data[b].Stat1Value) or 0))

        end)
    
    -- k = array keys (item name) , v = array values (item values)
    for i = 1, #ordered_keys do
        local k, v = ordered_keys[i], data[ ordered_keys[i] ]
        
        --Building each row of the table
        if ( not(Filter) or string.find(v.Sold, Filter) ~= nil ) then
            row = buildrow(row, v, k, Armour, Shield, Category) end
        
        if ( Filter and v.Subtype ~= nil ) then
            -- This second if can only be execute if v.Subtype ins't null
            if ( string.find(v.Subtype, Filter) ~= nil ) then
                row = buildrow(row, v, k, Armour, Shield, Category) end
        end
        
        if ( Filter == 'DLC' and v.DLC ) then
            row = buildrow(row, v, k, Armour, Shield, Category) end
        
        if ( Filter == 'Main' and not(v.DLC) ) then
            row = buildrow( row, v, k, Armour, Shield, Category) end

    end
    return row
end

-- Main function that creates the Gear Table
--    @function        buildTable
--    @param            {data} All data of specific Gear Type (All Longswords or all Hammers, etc ... Data store in M:Gear/xxxxx/Data)
--    @param[opt]        {Armour} Boolean used to add adcitional collumns for Armour and Shields Table. By default is false
--    @param[opt]        {Sortable} Boolean used to add option to short table by each Collumn. By default is false
--    @returns        {result} Fully build html Table with all needed info.
return {
buildTable = function(frame)
    --Initialization of entry arguments
    local args = frame.args;
    local Category = mw.text.decode(args['Data'])
    
    local data = {}
    if ( Category == 'Weapons' or Category == 'Tools' or Category == 'Armour') then
        local i = 1
        for k = 1, #gear do
            local datatemp = mw.loadData('Module:Gear/'..gear[k]..'/Data')
            for key in pairs(datatemp) do
                if ( string.find(datatemp[key].Type, Category) ~= nil ) then
                    data[i] = datatemp
                    i = i + 1
                end
                break
            end
        end
    else
        data = mw.loadData('Module:Gear/'..Category..'/Data')
        Category = false
    end
    
    local Filter = false
    if args['Filter'] ~= nil then
        Filter = args['Filter'] end
    
    local Armour = false
    if ( args['Armour'] == 'true' or args['Armour'] == 'True' or args['Armour'] == 1) then
        Armour = true end
    
    local Sortable = false
    if ( args['Sortable'] == 'true' or args['Sortable'] == 'True' or args['Sortable'] == 1) then
        Sortable = true end
    
    local Shield = false
    if ( data["Paladin's Shield"] ~= nil ) then
        Shield = true end
    
    --Initialization of table value itself
    local result = {}
    
    --Building Table
    if Sortable then
        table.insert(result, '{| class="article-table clear sortable" style="width:100%"')
    else
        table.insert(result, '{| class="article-table clear" style="width:100%"')
    end
    table.insert(result, '|- style="font-size:small"')
    table.insert(result, '! style="width:20px" | Picture')
    table.insert(result, '! style="width:18%" | Item')
    if ( Category and not(Armour) ) then
        table.insert(result, '! style="width:20px; padding-top:3px; padding-bottom:3px" | Gear Type') end
    table.insert(result, '! style="width:20px" | Rarity')
    if Shield then
        table.insert(result, '! style="width:20px; padding-top:3px; padding-bottom:3px" | Skill Level')
        table.insert(result, '! style="width:20px" | Defense')
    elseif Armour then
        table.insert(result, '! style="width:20px" | Level')
        table.insert(result, '! style="width:20px" | Defense')
    else
        table.insert(result, '! style="width:20px; padding-top:3px; padding-bottom:3px" | Skill Level') 
        table.insert(result, '! style="width:20px" | Normal')
    end
    table.insert(result, '! style="width:50px" | [[File:Good Quality.png]]')
    table.insert(result, '! style="width:50px" | [[File:Great Quality.png]]')
    table.insert(result, '! style="width:50px" | [[File:Top Quality.png]]')
    table.insert(result, '! style="width:50px" | [[File:Divine Quality.png]]')
    if Armour then
        table.insert(result, '! style="width:20px; padding-top:3px; padding-bottom:3px" | Magic Defense') end
    table.insert(result, '! style="padding-top:3px; padding-bottom:3px" | Special Effect')
    table.insert(result, '! style="width:90px" | Lives')
    if ( Armour and not(Shield) ) then
        table.insert(result, '! style="width:20px" | Gender') end
    if Category then
        for k = 1, #data do
            table.insert(result, cicle(data[k], Armour, Shield, Category, Filter) )
        end
    else 
        table.insert(result, cicle(data, Armour, Shield, false, Filter) )
    end
    table.insert(result, '|}')
    return table.concat(result, '\n')
end
}