Module:ItemData/nav: Difference between revisions

From Deadlock Wiki
Jump to navigation Jump to search
Sur (talk | contribs)
m testing ordering by soul count first again
Sur (talk | contribs)
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 = {}
--1st layer: souls
--2nd layer: list of items with that soul count
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
if items[this_cost] == nil then
table.insert(items, lang_module.get_string(item_key))
items[this_cost] = {} --list, ensure it exists before inserting to it
end
table.insert(items[this_cost], lang_module.get_string(item_key))
end
end
end
end
end
end
--Order each list of items for that cost by item name alphabetically
--Order list alphabetically
for cost, items_within_souls in pairs(items) do
table.sort(items) --O(nlogn)
table.sort(items[cost])
end
--Order the lists by souls
table.sort(items)
--2 level hash is now ordered first by cost, second by name alphabetically
--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 cost, items_within_souls in pairs(items) do
for index, item_name in ipairs(items) do
for index, item_name in ipairs(items_within_souls) do
ret = ret .. left_wrap .. item_name .. right_wrap .. sep
ret = ret .. left_wrap .. item_name .. right_wrap .. sep
end
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)
local slot = frame.args[1]
-- If called internally (direct Lua call), args will be passed directly.
local min_souls = frame.args[2]
    -- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`.
local max_souls = frame.args[3]
 
local debug_mode = frame.args["debug_mode"]
    -- 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)
local slot = frame.args[1]
-- If called internally (direct Lua call), args will be passed directly.
local min_souls = frame.args[2]
    -- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`.
local max_souls = frame.args[3]
 
local debug_mode = frame.args["debug_mode"]
    -- 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]

get_item_nav_bulletpoints[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

get_item_nav_cards[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}}


Souls1,250
Bullet Armor
Souls1,250
Bullet Lifesteal
Souls1,250
Combat Barrier
Souls1,250
Debuff Reducer
Souls1,250
ACTIVE
Divine Barrier
Souls1,750

Enduring Speed
Souls1,250
Healbane
Souls1,250
Healing Booster
Souls1,750
ACTIVE

Healing Nova
Souls1,250
Reactive Barrier
Souls1,250
ACTIVE
Restorative Locket
Souls1,750
ACTIVE

Return Fire
Souls1,250
Spirit Armor
Souls1,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}}


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 = ' &bull; '
	
	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