Module:ItemData/nav: Difference between revisions
m testing ordering by soul count first again |
m get_slot_color now automatically prefixes the hex with # |
||
(8 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
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 | --With debug_mode on, it outputs unprocessed wikitext | ||
Line 23: | Line 25: | ||
return 'slot must be Weapon, Armor (Vitality), or Tech (Spirit)' | return 'slot must be Weapon, Armor (Vitality), or Tech (Spirit)' | ||
end | end | ||
local min_souls = tonumber(min_souls) | local min_souls = tonumber(min_souls) | ||
local max_souls = tonumber(max_souls) | local max_souls = tonumber(max_souls) | ||
Line 29: | Line 32: | ||
--Retrieve all items that fit the bounds | --Retrieve all items that fit the bounds | ||
local items = {} | local items = {} | ||
for item_key, item_data in pairs(items_data) do | for item_key, item_data in pairs(items_data) do | ||
--future proofing; Disabled will be renamed to IsDisabled soon | |||
if item_data['Disabled'] == nil and item_data['IsDisabled'] ~= nil then | if item_data['Disabled'] == nil and item_data['IsDisabled'] ~= nil then | ||
return "REMINDER: 'Disabled' was renamed to 'IsDisabled'" | return "REMINDER: 'Disabled' was renamed to 'IsDisabled'" | ||
Line 38: | Line 40: | ||
local this_cost = tonumber(item_data["Cost"]) | local this_cost = tonumber(item_data["Cost"]) | ||
local this_slot = item_data["Slot"] | local this_slot = item_data["Slot"] | ||
if item_data["Name"] ~= nil and item_data["Disabled"] == false and this_cost ~= nil and this_slot ~= nil then | if item_data["Name"] ~= nil and item_data["Disabled"] == false and this_cost ~= nil and this_slot ~= nil then | ||
if slot == this_slot and this_cost>=min_souls and this_cost<max_souls then | if slot == this_slot and this_cost>=min_souls and this_cost<max_souls then | ||
table.insert(items, lang_module.get_string(item_key)) | |||
table.insert(items | |||
end | end | ||
end | end | ||
end | end | ||
--Order | --Order list alphabetically | ||
table.sort(items) --O(nlogn) | |||
--Add each item to output | --Add each item to output | ||
-- Each item is surrounded by left and right wrap, and separated by sep | |||
local ret = '' | local ret = '' | ||
for index, item_name in ipairs(items) do | |||
ret = ret .. left_wrap .. item_name .. right_wrap .. sep | |||
end | end | ||
Line 73: | Line 64: | ||
-- for [[Template:Item Navbox]] | -- for [[Template:Item Navbox]] | ||
function p.get_item_nav_bulletpoints(frame) | function p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode) | ||
-- If called internally (direct Lua call), args will be passed directly. | |||
-- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`. | |||
-- Handle the case where it's called via #invoke (i.e., from wikitext) | |||
if type(slot) == "table" and slot.args then | |||
local frame = slot | |||
slot = frame.args[1] | |||
min_souls = frame.args[2] | |||
max_souls = frame.args[3] | |||
debug_mode = frame.args["debug_mode"] | |||
end | |||
local left_wrap = '{{ItemIcon|' | local left_wrap = '{{ItemIcon|' | ||
local right_wrap = '}}' | local right_wrap = '}}' | ||
Line 88: | Line 87: | ||
-- for [[Template:Infobox ShopItems]] | -- for [[Template:Infobox ShopItems]] | ||
function p.get_item_nav_cards(frame) | function p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode) | ||
-- If called internally (direct Lua call), args will be passed directly. | |||
-- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`. | |||
-- Handle the case where it's called via #invoke (i.e., from wikitext) | |||
if type(slot) == "table" and slot.args then | |||
local frame = slot | |||
slot = frame.args[1] | |||
min_souls = frame.args[2] | |||
max_souls = frame.args[3] | |||
debug_mode = frame.args["debug_mode"] | |||
end | |||
local left_wrap = '{{ItemBox|item_name=' | local left_wrap = '{{ItemBox|item_name=' | ||
local right_wrap = '}}' | local right_wrap = '}}' | ||
Line 100: | Line 107: | ||
return process_debug_mode(item_list, debug_mode) | return process_debug_mode(item_list, debug_mode) | ||
end | |||
function p.write_item_slot_subgroup(frame) | |||
local slot = frame.args[1] | |||
local type = frame.args[2] | |||
local debug_mode = frame.args['debug_mode'] | |||
if slot == nil then return "'slot' parameter is required" end | |||
-- Define base args | |||
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() | |||
for i, souls in ipairs(prices) do | |||
--Determine lower bound for soul | |||
min_souls = souls | |||
--Skip 0 to i1 as no items cost less than 500 | |||
if min_souls ~= 0 then | |||
-- Determine upper bound | |||
max_souls = prices[i+1] | |||
if max_souls == nil then | |||
max_souls = min_souls * 10 --essentially have no upper bound | |||
end | |||
--Create the subgroup | |||
template_args["group" .. (i-1)] = frame:expandTemplate{title="Souls", args={[1] = min_souls, ["Shadow"] = soul_style}} | |||
local list | |||
if type=='get_item_nav_cards' then | |||
list = p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode) | |||
elseif type=='get_item_nav_bulletpoints' then | |||
list = p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode) | |||
else | |||
return "'type' should be get_item_nav_cards or get_item_nav_bulletpoints" | |||
end | |||
template_args["list" .. (i-1)] = list | |||
end | |||
end | |||
return frame:expandTemplate{title=template_title, args=template_args} | |||
end | end | ||
return p | return p |
Latest revision as of 21:10, 1 November 2024
Overview[edit source]
Functions for creating navigation boxes/lists for items, grouped by a slot/category and souls
Functions[edit source]
[edit source]
Gets a list of items that are each sent to the Template:ItemIcon template, separated by bullet points.
Filters down to a slot/specific category, and within a range of souls.
Parameters[edit source]
- slot - Slot/category that the items should be, should be Weapon, Armor, or Tech
- min_souls - Minimum souls that the items should have
- max_souls - Maximum souls that the items should have
- debug_mode - (OPTIONAL) - if set to 'true', the wikitext is unprocessed, allowing for it to be read more clearly. Also used for showcasing the documentation examples more clearly.
Examples[edit source]
With debug_mode on (for illustration purposes)
{{#invoke:ItemData/nav|get_item_nav_bulletpoints|Armor|1250|3000|debug_mode=true}}
{{ItemIcon|Bullet Armor}} • {{ItemIcon|Bullet Lifesteal}} • {{ItemIcon|Combat Barrier}} • {{ItemIcon|Debuff Reducer}} • {{ItemIcon|Divine Barrier}} • {{ItemIcon|Enchanter's Barrier}} • {{ItemIcon|Enduring Speed}} • {{ItemIcon|Healbane}} • {{ItemIcon|Healing Booster}} • {{ItemIcon|Healing Nova}} • {{ItemIcon|Reactive Barrier}} • {{ItemIcon|Restorative Locket}} • {{ItemIcon|Return Fire}} • {{ItemIcon|Spirit Armor}} • {{ItemIcon|Spirit Lifesteal}}
With debug_mode off
{{#invoke:ItemData/nav|get_item_nav_bulletpoints|Armor|1250|3000}}
Bullet Armor • Bullet Lifesteal • Combat Barrier • Debuff Reducer • Divine Barrier • Enchanter's Barrier • Enduring Speed • Healbane • Healing Booster • Healing Nova • Reactive Barrier • Restorative Locket • Return Fire • Spirit Armor • Spirit Lifesteal
[edit source]
Gets a list of items that are each sent to the Template:ItemBox template, separated by space.
Filters down to a specific slot/category, and within a range of souls.
Parameters[edit source]
Same as get_item_nav_bulletpoints
Examples[edit source]
With debug_mode on (for illustration purposes)
{{#invoke:ItemData/nav|get_item_nav_bulletpoints|Armor|1250|3000|debug_mode=true}}
{{ItemBox|item_name=Bullet Armor}} {{ItemBox|item_name=Bullet Lifesteal}} {{ItemBox|item_name=Combat Barrier}} {{ItemBox|item_name=Debuff Reducer}} {{ItemBox|item_name=Divine Barrier}} {{ItemBox|item_name=Enchanter's Barrier}} {{ItemBox|item_name=Enduring Speed}} {{ItemBox|item_name=Healbane}} {{ItemBox|item_name=Healing Booster}} {{ItemBox|item_name=Healing Nova}} {{ItemBox|item_name=Reactive Barrier}} {{ItemBox|item_name=Restorative Locket}} {{ItemBox|item_name=Return Fire}} {{ItemBox|item_name=Spirit Armor}} {{ItemBox|item_name=Spirit Lifesteal}}
With debug_mode off
{{#invoke:ItemData/nav|get_item_nav_bulletpoints|Armor|1250|3000}}
1,250 |
---|
Bullet Armor |
1,250 |
---|
Bullet Lifesteal |
1,250 |
---|
Combat Barrier |
1,250 |
---|
Debuff Reducer |
1,250 |
---|
ACTIVE |
Divine Barrier |
1,250 |
---|
Enchanter's Barrier |
1,750 |
---|
Enduring Speed |
1,250 |
---|
Healbane |
1,250 |
---|
Healing Booster |
1,750 |
---|
ACTIVE |
Healing Nova |
1,250 |
---|
Reactive Barrier |
1,250 |
---|
ACTIVE |
Restorative Locket |
1,250 |
---|
ACTIVE |
Return Fire |
1,250 |
---|
Spirit Armor |
1,250 |
---|
Spirit Lifesteal |
write_item_slot_subgroup[edit source]
Writes a sub group for the navbox on Template:Item Navbox and Template:Infobox ShopItems. The sub group contains all items in each price range from "ItemPricePerTier" in Data:GenericData.json
Parameters[edit source]
- slot - Slot/category to create the subgroup for, ie Weapon, Armor, or Tech
- type - The subfunction to call that determines the list formatting style. Options are 'get_item_nav_bulletpoints' or 'get_item_nav_cards'
- debug_mode - (OPTIONAL) - if set to 'true', the wikitext is unprocessed, allowing for it to be read more clearly. Also used for showcasing the documentation examples more clearly.
Examples[edit source]
With debug_mode on (for illustration purposes)
{{#invoke:ItemData/nav|write_item_slot_subgroup|Weapon|get_item_nav_bulletpoints|debug_mode=true}}
{{ItemIcon|Basic Magazine}} • {{ItemIcon|Close Quarters}} • {{ItemIcon|Headshot Booster}} • {{ItemIcon|High-Velocity Mag}} • {{ItemIcon|Hollow Point Ward}} • {{ItemIcon|Monster Rounds}} • {{ItemIcon|Rapid Rounds}} • {{ItemIcon|Restorative Shot}} | |
{{ItemIcon|Active Reload}} • {{ItemIcon|Berserker}} • {{ItemIcon|Fleetfoot}} • {{ItemIcon|Kinetic Dash}} • {{ItemIcon|Long Range}} • {{ItemIcon|Melee Charge}} • {{ItemIcon|Mystic Shot}} • {{ItemIcon|Slowing Bullets}} • {{ItemIcon|Soul Shredder Bullets}} • {{ItemIcon|Swift Striker}} | |
{{ItemIcon|Alchemical Fire}} • {{ItemIcon|Burst Fire}} • {{ItemIcon|Escalating Resilience}} • {{ItemIcon|Headhunter}} • {{ItemIcon|Heroic Aura}} • {{ItemIcon|Hunter's Aura}} • {{ItemIcon|Intensifying Magazine}} • {{ItemIcon|Point Blank}} • {{ItemIcon|Pristine Emblem}} • {{ItemIcon|Sharpshooter}} • {{ItemIcon|Tesla Bullets}} • {{ItemIcon|Titanic Magazine}} • {{ItemIcon|Toxic Bullets}} • {{ItemIcon|Warp Stone}} | |
{{ItemIcon|Crippling Headshot}} • {{ItemIcon|Frenzy}} • {{ItemIcon|Glass Cannon}} • {{ItemIcon|Lucky Shot}} • {{ItemIcon|Ricochet}} • {{ItemIcon|Shadow Weave}} • {{ItemIcon|Silencer}} • {{ItemIcon|Spiritual Overflow}} • {{ItemIcon|Vampiric Burst}} |
With debug_mode off
{{#invoke:ItemData/nav|write_item_slot_subgroup|Weapon|get_item_nav_bulletpoints}}
Recall that it creates subgroup parameters for the mentioned templates.
local p = {}
local items_data = mw.loadJsonData("Data:ItemData.json")
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
--With debug_mode off/unspecified, it processes the wikitext
local function process_debug_mode(wikitext, debug_mode)
if debug_mode == 'true' then
return wikitext
elseif debug_mode == 'false' or debug_mode == nil then
return mw.getCurrentFrame():preprocess(wikitext)
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
-- Each item is wrapped and separated. For example of wrapping/separator, see
-- get_item_nav_bulletpoints. 'sep' should not be combined with 'right_wrap',
-- as the trailing separator should also be removed from the string
local function write_wrapped_item_list(slot, min_souls, max_souls, left_wrap, right_wrap, sep)
if slot ~= 'Weapon' and slot ~= 'Armor' and slot ~= 'Tech' then
return 'slot must be Weapon, Armor (Vitality), or Tech (Spirit)'
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
--future proofing; Disabled will be renamed to IsDisabled soon
if item_data['Disabled'] == nil and item_data['IsDisabled'] ~= nil then
return "REMINDER: 'Disabled' was renamed to 'IsDisabled'"
end
local this_cost = tonumber(item_data["Cost"])
local this_slot = item_data["Slot"]
if item_data["Name"] ~= nil and item_data["Disabled"] == false and this_cost ~= nil and this_slot ~= nil then
if slot == this_slot and this_cost>=min_souls and this_cost<max_souls then
table.insert(items, lang_module.get_string(item_key))
end
end
end
--Order list alphabetically
table.sort(items) --O(nlogn)
--Add each item to output
-- Each item is surrounded by left and right wrap, and separated by sep
local ret = ''
for index, item_name in ipairs(items) do
ret = ret .. left_wrap .. item_name .. right_wrap .. sep
end
--Remove the last separator thats trailing after the last item
ret = string.sub(ret, 1, -(string.len(sep))-1)
return ret
end
-- for [[Template:Item Navbox]]
function p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode)
-- If called internally (direct Lua call), args will be passed directly.
-- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`.
-- Handle the case where it's called via #invoke (i.e., from wikitext)
if type(slot) == "table" and slot.args then
local frame = slot
slot = frame.args[1]
min_souls = frame.args[2]
max_souls = frame.args[3]
debug_mode = frame.args["debug_mode"]
end
local left_wrap = '{{ItemIcon|'
local right_wrap = '}}'
local sep = ' • '
local item_list = write_wrapped_item_list(slot, min_souls, max_souls, left_wrap, right_wrap, sep)
return process_debug_mode(item_list, debug_mode)
end
-- for [[Template:Infobox ShopItems]]
function p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode)
-- If called internally (direct Lua call), args will be passed directly.
-- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`.
-- Handle the case where it's called via #invoke (i.e., from wikitext)
if type(slot) == "table" and slot.args then
local frame = slot
slot = frame.args[1]
min_souls = frame.args[2]
max_souls = frame.args[3]
debug_mode = frame.args["debug_mode"]
end
local left_wrap = '{{ItemBox|item_name='
local right_wrap = '}}'
local sep = ' '
local item_list = write_wrapped_item_list(slot, min_souls, max_souls, left_wrap, right_wrap, sep)
return process_debug_mode(item_list, debug_mode)
end
function p.write_item_slot_subgroup(frame)
local slot = frame.args[1]
local type = frame.args[2]
local debug_mode = frame.args['debug_mode']
if slot == nil then return "'slot' parameter is required" end
-- Define base args
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()
for i, souls in ipairs(prices) do
--Determine lower bound for soul
min_souls = souls
--Skip 0 to i1 as no items cost less than 500
if min_souls ~= 0 then
-- Determine upper bound
max_souls = prices[i+1]
if max_souls == nil then
max_souls = min_souls * 10 --essentially have no upper bound
end
--Create the subgroup
template_args["group" .. (i-1)] = frame:expandTemplate{title="Souls", args={[1] = min_souls, ["Shadow"] = soul_style}}
local list
if type=='get_item_nav_cards' then
list = p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode)
elseif type=='get_item_nav_bulletpoints' then
list = p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode)
else
return "'type' should be get_item_nav_cards or get_item_nav_bulletpoints"
end
template_args["list" .. (i-1)] = list
end
end
return frame:expandTemplate{title=template_title, args=template_args}
end
return p