- merchant - Merchant of interest.
- item - Singular item for which to create a table.
- ingredient - Ingredient name. Used to filter the provided merchant's crafts for those which use the ingredient.
From Dark and Darker Wiki
(Added invoke-able functions to generate filtered ingredient and filtered crafting tables.) |
(Merged two invoke-able functions into one.) |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 6: | Line 6: | ||
local function iconbox(wt,name,amount,rarity,has_caption) | local function iconbox(wt,name,amount,rarity,has_caption) | ||
wt[#wt+1] = "<div class='iconbox' style='width:max-content;align-items:center'><div class='rarity"..rarity.." rounded relative'>" | wt[#wt+1] = "<div class='iconbox' style='width:max-content;align-items:center'><div class='rarity"..rarity.." rounded relative'>" | ||
wt[#wt+1] = | wt[#wt+1] = "[[File:"..name..".png|x80px|link="..name.."]]" | ||
wt[#wt+1] = | if amount then | ||
wt[#wt+1] = | wt[#wt+1] = "<span class='iconamount' style='pointer-events:none;color:#EEEA;font-size:16px'>"..amount.."</span>" | ||
if has_caption then wt[#wt+1] = "<br>[["..name.."|<b class=cr"..rarity..">"..name.."</b>]]" end | end | ||
wt[#wt+1] = "</div>" | |||
if has_caption then | |||
wt[#wt+1] = "<br>[["..name.."|<b class=cr"..rarity..">"..name.."</b>]]" | |||
end | |||
wt[#wt+1] = "</div>" | wt[#wt+1] = "</div>" | ||
end | end | ||
| Line 37: | Line 41: | ||
if is_header then wt[#wt+1] = "<th style='width:2%'>Merchant</th>" return end | if is_header then wt[#wt+1] = "<th style='width:2%'>Merchant</th>" return end | ||
wt[#wt+1] = "<td> | wt[#wt+1] = "<td>" | ||
wt | iconbox(wt,merchant_name,false,"-1",true) | ||
wt[#wt+1] = " | wt[#wt+1] = "</td>" | ||
end | end | ||
| Line 153: | Line 157: | ||
end | end | ||
function | local function draw_ingredient_table(wt,ingredient,category,data) | ||
local | local merchants = data[category] and data[category][ingredient] and data[category][ingredient].incraftingrecipefor or {} | ||
if count(merchants) == 0 then return "" end | if count(merchants) == 0 then return "" end | ||
wt[#wt+1] = "<h2>Ingredient</h2>" | wt[#wt+1] = "<h2>Ingredient</h2>" | ||
wt[#wt+1] = ingredient | wt[#wt+1] = ingredient | ||
| Line 172: | Line 172: | ||
end | end | ||
wt[#wt+1] = BASIC_TABLE.close | wt[#wt+1] = BASIC_TABLE.close | ||
end | end | ||
function | local function draw_craftable_table(wt,item,category,data) | ||
local | local merchants = data[category] and data[category][item] and data[category][item].iscraftableby or {} | ||
if count(merchants) == 0 then return "" end | if count(merchants) == 0 then return "" end | ||
wt[#wt+1] = "<h2>Craftable</h2>" | wt[#wt+1] = "<h2>Craftable</h2>" | ||
wt[#wt+1] = item | wt[#wt+1] = item | ||
| Line 193: | Line 187: | ||
end | end | ||
wt[#wt+1] = BASIC_TABLE.close | wt[#wt+1] = BASIC_TABLE.close | ||
end | |||
function p.page(f) | |||
local category = f.args.category | |||
local item = f.args.item | |||
local data = mw.loadJsonData(CATEGORY[category].Data) | |||
local wt = {} | |||
draw_craftable_table(wt,item,category,data) | |||
draw_ingredient_table(wt,item,category,data) | |||
return table.concat(wt) | return table.concat(wt) | ||
end | end | ||
| Line 206: | Line 208: | ||
-- mw.log(p.draw_table({args={merchant="Weaponsmith",ingredient="Iron Ingot"}})) | -- mw.log(p.draw_table({args={merchant="Weaponsmith",ingredient="Iron Ingot"}})) | ||
-- mw.log(p. | -- mw.log(p.page({args={item="Void Blade",category="Weapon"}})) | ||
-- mw.log(p.page({args={item="Iron Ingot",category="Misc"}})) | |||
-- mw.log(p. | -- mw.log(p.page({args={item="Iron Ore",category="Misc"}})) | ||
Latest revision as of 00:15, 9 April 2026
Overview
Functions for making Crafting table. Data comes from Data:Merchant.json.
Functions
draw_table
Creates a table of craftables
{{#invoke:Craft|draw_table|item=Void Blade|merchant=Weaponsmith}}
| Name | Ingredients | Merchant |
|---|---|---|
{{#invoke:Craft|draw_table|merchant=Weaponsmith|ingredient=Iron Ingot}}
| Name | Ingredients | Merchant |
|---|---|---|
{{#invoke:Craft|draw_table|merchant=Weaponsmith}}
| Name | Ingredients | Merchant |
|---|---|---|
page
Creates, if possible, two tables. The first presents recipes for if the given item is craftable. The second presents recipes that use the item to create other items.
- item - Singular item for which to create a table.
- category - Item's item category. Used to lookup merchant crafting presence.
{{#invoke:Craft|page|item=Void Blade|category=Weapon}}
Craftable
Void Blade is craftable with the following crafting recipes.| Name | Ingredients | Merchant |
|---|---|---|
{{#invoke:Craft|page|category=Misc|item=Iron Ingot}}
Craftable
Iron Ingot is craftable with the following crafting recipes.| Name | Ingredients | Merchant |
|---|---|---|
Ingredient
Iron Ingot is used in the following crafting recipes.| Name | Ingredients | Merchant |
|---|---|---|
{{#invoke:Craft|page|category=Misc|item=Iron Ore}}
Ingredient
Iron Ore is used in the following crafting recipes.| Name | Ingredients | Merchant |
|---|---|---|
--Either draw table of all craftable weapons for a merchant, or a singular item table
local p = {}
local MD = mw.loadJsonData("Data:Merchant.json") --Global var holding tables from Data:Merchant.json
local function iconbox(wt,name,amount,rarity,has_caption)
wt[#wt+1] = "<div class='iconbox' style='width:max-content;align-items:center'><div class='rarity"..rarity.." rounded relative'>"
wt[#wt+1] = "[[File:"..name..".png|x80px|link="..name.."]]"
if amount then
wt[#wt+1] = "<span class='iconamount' style='pointer-events:none;color:#EEEA;font-size:16px'>"..amount.."</span>"
end
wt[#wt+1] = "</div>"
if has_caption then
wt[#wt+1] = "<br>[["..name.."|<b class=cr"..rarity..">"..name.."</b>]]"
end
wt[#wt+1] = "</div>"
end
local function name(wt,is_header,craft,merchant_name)
if is_header then wt[#wt+1] = "<th style='width:2%'>Name</th>" return end
wt[#wt+1] = "<td>"
iconbox(wt,craft.itemname,craft.quantity,craft.rarity,true)
wt[#wt+1] = "</td>"
end
local function ingredients(wt,is_header,craft,merchant_name)
if is_header then wt[#wt+1] = "<th style='width:5%'>Ingredients</th>" return end
wt[#wt+1] = "<td>"
for _,ingredient in ipairs(craft.ingredients) do
local amount = string.match(ingredient,"^(%d*)-")
local ingredient_name = string.match(ingredient,"-(.*)-")
local rarity = string.match(ingredient,"-.*-(.*)$")
iconbox(wt,ingredient_name,amount,rarity)
end
wt[#wt+1] = "</td>"
end
local function merchant(wt,is_header,craft,merchant_name)
if is_header then wt[#wt+1] = "<th style='width:2%'>Merchant</th>" return end
wt[#wt+1] = "<td>"
iconbox(wt,merchant_name,false,"-1",true)
wt[#wt+1] = "</td>"
end
local function affinity_to_unlock(wt,is_header,craft,merchant)
if is_header then wt[#wt+1] = "<th class='tooltip' style='width:2%'>[[Template:Merchant Affinity|Affinity to Unlock]]<span class='tooltiptext-left' style='left:50%; transform:translate(-50%); bottom:75%; width:100%'>Affinity values are collected manually by the community. If you spot an error, please follow the link and fix it!</span></th></tr>" return end
end
local ROW = {
["Default"] = {name,ingredients,merchant}
}
local function craft_row(wt,is_header,craft,merchant_name)
wt[#wt+1] = "<tr>"
for _,craft_td in ipairs(ROW.Default) do
craft_td(wt,is_header,craft,merchant_name)
end
wt[#wt+1] = "</tr>"
end
local function craft_table_header(wt)
craft_row(wt,true)
end
local function spairs(dict)
if not dict then return function() return nil,nil end end
local set = {}
for key,_ in pairs(dict) do
if key ~= "order" then
set[#set+1] = key
end
end
table.sort(set,function(a,b)
if type(a) ~= type(b) then
return tostring(a) < tostring(b)
else
return a < b
end
end)
local i = 0
return function()
i = i + 1
local key = set[i]
if key ~= nil then
return key, dict[key]
end
end
end
local function has_ingredient(list,ingredient)
for _,val in ipairs(list) do
if string.match(val,ingredient) then return true end
end
return false
end
local function get_craft_list(args)
local list = {}
if args.item then
list[#list+1] = args.item
else
for craft_name,craft in spairs(MD[args.merchant].crafts) do
-- if filtering for ingredients, ensure the craft requires the ingredient
if args.ingredient then
if has_ingredient(craft.ingredients,args.ingredient) then
list[#list+1] = craft_name
end
-- else include all crafts
elseif args.merchant ~= nil then
list[#list+1] = craft_name
end
end
end
return list
end
local BASIC_TABLE = { open = "<table cellspacing='0' class='wikitable sortable jquery-tablesorter' style='width:70%;min-width:500px;text-align:center;vertical-align:middle'>",
close= "</table>"}
function p.draw_table(f)
local item_list = get_craft_list(f.args)
local merchant_name = f.args.merchant
if #item_list == 0 then return "" end
local wt = {}
wt[#wt+1] = BASIC_TABLE.open
craft_table_header(wt)
for _,craft_name in ipairs(item_list) do
craft_row(wt,false,MD[merchant_name].crafts[craft_name],merchant_name)
end
wt[#wt+1] = BASIC_TABLE.close
return table.concat(wt)
end
local CATEGORY = { Weapon = {Data = "Data:Weapon.json"},
Armor = {Data = "Data:Armor.json"},
Accessory = {Data = "Data:Accessory.json"},
Utility = {Data = "Data:Utility.json"},
Misc = {Data = "Data:Misc.json"},
Monster = {Data = "Data:Monster.json"},
Prop = {Data = "Data:Prop.json"}}
local function count(t)
local c = 0
for _ in pairs(t) do c = c + 1 end
return c
end
local function draw_ingredient_table(wt,ingredient,category,data)
local merchants = data[category] and data[category][ingredient] and data[category][ingredient].incraftingrecipefor or {}
if count(merchants) == 0 then return "" end
wt[#wt+1] = "<h2>Ingredient</h2>"
wt[#wt+1] = ingredient
wt[#wt+1] = " is used in the following [[crafting]] recipes."
wt[#wt+1] = BASIC_TABLE.open
craft_table_header(wt)
for _,merchant_name in ipairs(merchants) do
for _,craft_name in ipairs(get_craft_list({ingredient=ingredient,merchant=merchant_name})) do
craft_row(wt,false,MD[merchant_name].crafts[craft_name],merchant_name)
end
end
wt[#wt+1] = BASIC_TABLE.close
end
local function draw_craftable_table(wt,item,category,data)
local merchants = data[category] and data[category][item] and data[category][item].iscraftableby or {}
if count(merchants) == 0 then return "" end
wt[#wt+1] = "<h2>Craftable</h2>"
wt[#wt+1] = item
wt[#wt+1] = " is craftable with the following [[crafting]] recipes."
wt[#wt+1] = BASIC_TABLE.open
craft_table_header(wt)
for _,merchant_name in ipairs(merchants) do
craft_row(wt,false,MD[merchant_name].crafts[item],merchant_name)
end
wt[#wt+1] = BASIC_TABLE.close
end
function p.page(f)
local category = f.args.category
local item = f.args.item
local data = mw.loadJsonData(CATEGORY[category].Data)
local wt = {}
draw_craftable_table(wt,item,category,data)
draw_ingredient_table(wt,item,category,data)
return table.concat(wt)
end
return p
-- Test on the wiki with these console inputs
-- mw.log(p.draw_table({args={item="Void Blade",merchant="Weaponsmith"}}))
-- mw.log(p.draw_table({args={merchant="Weaponsmith"}}))
-- mw.log(p.draw_table({args={merchant="Weaponsmith",ingredient="Iron Ingot"}}))
-- mw.log(p.page({args={item="Void Blade",category="Weapon"}}))
-- mw.log(p.page({args={item="Iron Ingot",category="Misc"}}))
-- mw.log(p.page({args={item="Iron Ore",category="Misc"}}))