|
|
| Line 1: |
Line 1: |
| -- This module is a direct copy of Module:ItemData/nav, but modified to display | | -- This module generates a sortable wikitable of unreleased (disabled) items. |
| -- UNRELEASED (disabled) items instead of released (enabled) ones.
| | -- It filters data from Data:ItemData.json for items that have a Name and are marked IsDisabled: true. |
| -- It specifically filters for items that have a Name property. | |
|
| |
|
| local p = {} | | local p = {} |
| local items_data = mw.loadJsonData("Data:ItemData.json") | | local items_data = mw.loadJsonData("Data:ItemData.json") |
| local lang_module = require('Module:Lang') | | local lang_module = require('Module:Lang') |
| local generic_module = require('Module:GenericData')
| |
| local util_module = require('Module:Utilities')
| |
|
| |
|
| --With debug_mode on, it outputs unprocessed wikitext
| | function p.generate_table(frame) |
| --With debug_mode off/unspecified, it processes the wikitext
| | local itemType = frame.args[1] |
| local function process_debug_mode(wikitext, debug_mode)
| | if not itemType or itemType == '' then |
| if debug_mode == 'true' then
| | return '<strong class="error">Error: Item type (Weapon, Armor, Tech) must be specified.</strong>' |
| return wikitext
| | end |
| elseif debug_mode == 'false' or debug_mode == nil then
| | |
| return mw.getCurrentFrame():preprocess(wikitext)
| | local unreleased_items = {} |
| else
| |
| return "debug_mode must be 'true' or 'false'"
| |
| end
| |
| end
| |
|
| |
|
| --Writes list of items of a certain slot within the min and max soul bounds | | -- 1. Collect all unreleased items of the specified type that have a name |
| local function write_wrapped_item_list(slot, min_souls, max_souls, template, sep)
| | for item_key, item_data in pairs(items_data) do |
| if slot ~= 'Weapon' and slot ~= 'Armor' and slot ~= 'Tech' then
| | if item_data["Name"] ~= nil and item_data["IsDisabled"] == true and item_data["Slot"] == itemType then |
| return 'slot must be Weapon, Armor, or Tech'
| | table.insert(unreleased_items, { |
| | name = item_data["Name"], |
| | key = item_key, |
| | cost = tonumber(item_data["Cost"]) or 0, |
| | slot = item_data["Slot"] or "Unknown" |
| | }) |
| | end |
| end | | end |
|
| |
| local min_souls = tonumber(min_souls)
| |
| local max_souls = tonumber(max_souls)
| |
| if min_souls == nil or max_souls == nil then return 'Min/Max souls must be numerical' end
| |
|
| |
| -- Retrieve all items that fit the bounds
| |
| local items = {}
| |
| for item_key, item_data in pairs(items_data) do
| |
| local this_cost = tonumber(item_data["Cost"])
| |
| local this_slot = item_data["Slot"]
| |
|
| |
| -- ##################################################################
| |
| -- ## CRITICAL FILTERING LOGIC IS HERE: ##
| |
| -- ## 1. item_data["Name"] ~= nil : Ignores test/placeholder items. ##
| |
| -- ## 2. item_data["IsDisabled"] == true : Shows ONLY unreleased. ##
| |
| -- ##################################################################
| |
| if item_data["Name"] ~= nil and item_data["IsDisabled"] == true and this_cost ~= nil and this_slot ~= nil then
| |
| if slot == this_slot and this_cost >= min_souls and this_cost < max_souls then
| |
| -- The item_key is the internal name, e.g., "upgrade_ablative_coat"
| |
| -- The item_data["Name"] is the display name, e.g., "Ablative Coat"
| |
| -- Your ItemBox template uses the display name for the image and link, which is correct.
| |
| local display_name = item_data["Name"]
| |
|
| |
|
| -- Your module uses item_key for translation, but ItemBox uses the Name. We will stick to Name.
| | -- If no items found, return a simple message |
| local item_name_english = display_name
| | if #unreleased_items == 0 then |
| local lang_code = lang_module.get_lang_code()
| | return "''No unreleased " .. itemType .. " items found in the data files.''" |
| local item_name_local = lang_module.get_string(item_key, lang_code) -- Localized name
| |
|
| |
| local item_template
| |
| if template == "ItemBox" then
| |
| if lang_code == "en" then
| |
| -- For English pages, item_name is enough. ItemBox will handle the rest.
| |
| item_template = "{{ItemBox|item_name=" .. item_name_english .. "}}"
| |
| else
| |
| -- For non-English pages, provide localized name and link subpage
| |
| local link = item_name_english .. "/" .. lang_code
| |
| item_template = "{{ItemBox|item_name=" .. item_name_english .. "|item_loc=" .. item_name_local .. "|link=" .. link .. "}}"
| |
| end
| |
| else
| |
| return "Invalid template type for this module"
| |
| end
| |
| table.insert(items, item_template)
| |
| end
| |
| end
| |
| end | | end |
| | |
| | -- 2. Sort them alphabetically by name for a consistent default order |
| | table.sort(unreleased_items, function(a, b) return a.name < b.name end) |
| | |
| | -- 3. Build the wikitext for the table |
| | local wikitext = '{| class="wikitable sortable" style="width:100%;"\n' |
| | wikitext = wikitext .. '! style="width:64px;" | Icon\n' |
| | wikitext = wikitext .. '! Name\n' |
| | -- The ItemType column is redundant if we are already using section headers, but can be kept for sorting. |
| | -- wikitext = wikitext .. '! style="width:100px;" | Type\n' |
| | wikitext = wikitext .. '! style="width:120px;" | Cost\n' |
| | | |
| -- Order list alphabetically | | for _, item in ipairs(unreleased_items) do |
| table.sort(items)
| | wikitext = wikitext .. '|-\n' |
| | -- Icon cell (using the display name for the image file) |
| | wikitext = wikitext .. '| [[File:' .. item.name .. '.png|64x64px|link=' .. item.name .. ']]\n' |
| | -- Name cell (linking to the image page, as a placeholder) |
| | wikitext = wikitext .. '| [[:File:'.. item.name ..'.png|' .. item.name .. ']]\n' |
| | -- Type cell (optional) |
| | -- wikitext = wikitext .. '| {{ItemType|' .. item.slot .. '|color=true}}\n' |
| | -- Cost cell (with data-sort-value for correct numerical sorting) |
| | wikitext = wikitext .. '| data-sort-value="' .. item.cost .. '" | {{Souls|' .. item.cost .. '}}\n' |
| | end |
| | |
| | wikitext = wikitext .. '|}' |
| | | |
| return table.concat(items, sep) | | return frame:preprocess(wikitext) |
| end
| |
| | |
| -- This is a private function now, called by the public function below.
| |
| local function get_item_nav_cards(slot, min_souls, max_souls, debug_mode)
| |
| local sep = ' '
| |
| local item_list = write_wrapped_item_list(slot, min_souls, max_souls, "ItemBox", sep)
| |
| return process_debug_mode(item_list, debug_mode)
| |
| end
| |
| | |
| -- This is the public function that the template will call.
| |
| function p.generate_subgroup(frame)
| |
| local slot = frame.args[1]
| |
| if slot == nil then return "'slot' parameter is required" end
| |
| local debug_mode = frame.args['debug_mode']
| |
|
| |
| local template_title = "Navbox subgroup"
| |
| local template_args = {
| |
| ["groupstyle"] = "background-color:" .. util_module.get_slot_color(slot) .. ";width:10%;min-width:70px;border-radius: 8px 0 0 8px",
| |
| ["grouppadding"] = "5px",
| |
| ["listpadding"] = "0 0.25rem",
| |
| }
| |
|
| |
| local soul_style = "font-size: 12px; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);"
| |
| local prices = generic_module.get_item_price_per_tier()
| |
| local group_index = 1
| |
| for i, souls in ipairs(prices) do
| |
| local min_souls = souls
| |
|
| |
| if min_souls ~= 0 then
| |
| local max_souls = prices[i+1]
| |
| if max_souls == nil then
| |
| max_souls = min_souls * 10 --essentially have no upper bound
| |
| end
| |
|
| |
| local list = get_item_nav_cards(slot, min_souls, max_souls, debug_mode)
| |
|
| |
| -- Only add the group if there are actually items in it
| |
| if list ~= '' then
| |
| template_args["group" .. group_index] = frame:expandTemplate{title="Souls", args={[1] = min_souls, ["Shadow"] = soul_style}}
| |
| template_args["list" .. group_index] = list
| |
| group_index = group_index + 1
| |
| end
| |
| end
| |
| end
| |
|
| |
| if group_index == 1 then
| |
| return ""
| |
| end
| |
|
| |
| return frame:expandTemplate{title=template_title, args=template_args}
| |
| end | | end |
|
| |
|
| return p | | return p |