From Dark and Darker Wiki

(Working state)
 
(Added invoke-able functions to generate filtered ingredient and filtered crafting tables.)
Line 23: Line 23:
local function ingredients(wt,is_header,craft,merchant_name)
local function ingredients(wt,is_header,craft,merchant_name)
if is_header then wt[#wt+1] = "<th style='width:5%'>Ingredients</th>" return end
if is_header then wt[#wt+1] = "<th style='width:5%'>Ingredients</th>" return end
 
wt[#wt+1] = "<td>"
wt[#wt+1] = "<td>"
for _,ingredient in ipairs(craft.ingredients) do
for _,ingredient in ipairs(craft.ingredients) do
Line 54: Line 53:
local function craft_row(wt,is_header,craft,merchant_name)
local function craft_row(wt,is_header,craft,merchant_name)
wt[#wt+1] = "<tr>"
wt[#wt+1] = "<tr>"
for _,table_data in ipairs(ROW.Default) do
for _,craft_td in ipairs(ROW.Default) do
table_data(wt,is_header,craft,merchant_name)
craft_td(wt,is_header,craft,merchant_name)
end
end
wt[#wt+1] = "</tr>"
wt[#wt+1] = "</tr>"
Line 100: Line 99:
end
end


local function get_list(args)
local function get_craft_list(args)
local list = {}
local list = {}
if args.item then
if args.item then
Line 120: Line 119:
return list
return list
end
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)
function p.draw_table(f)
local item_list = get_list(f.args)
local item_list = get_craft_list(f.args)
local merchant = f.args.merchant
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
 
function p.draw_ingredient_table(f)
local ingredient = f.args.ingredient
local category = f.args.category
local data = mw.loadJsonData(CATEGORY[category].Data)
local merchants = data[category][ingredient].incraftingrecipefor
if count(merchants) == 0 then return "" end


local wt = {}
local wt = {}
wt[#wt+1] = "<table cellspacing='0' class='wikitable sortable jquery-tablesorter' style='width:70%;min-width:500px;text-align:center;vertical-align:middle'>"
wt[#wt+1] = "<h2>Ingredient</h2>"
if #item_list ~= 0 then
wt[#wt+1] = ingredient
craft_table_header(wt)
wt[#wt+1] = " is used in the following [[crafting]] recipes."
for _,craft_name in ipairs(item_list) do
wt[#wt+1] = BASIC_TABLE.open
craft_row(wt,false,MD[merchant].crafts[craft_name],merchant)
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
else
return "Failure"
end
end
wt[#wt+1] = "</table>"
wt[#wt+1] = BASIC_TABLE.close
 
return table.concat(wt)
end
 
function p.draw_craftable_table(f)
local item = f.args.item
local category = f.args.category
local data = mw.loadJsonData(CATEGORY[category].Data)
local merchants = data[category][item].iscraftableby
if count(merchants) == 0 then return "" end
 
local wt = {}
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


return table.concat(wt)
return table.concat(wt)
end
end


Line 143: Line 201:




-- 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={item="Void Blade",merchant="Weaponsmith"}}))
-- mw.log(p.draw_table({args={merchant="Weaponsmith"}}))
-- mw.log(p.draw_table({args={merchant="Weaponsmith"}}))
-- mw.log(p.draw_table({args={merchant="Weaponsmith",ingredient="Iron Ore"}}))
-- mw.log(p.draw_table({args={merchant="Weaponsmith",ingredient="Iron Ingot"}}))
 
-- mw.log(p.draw_ingredient_table({args={ingredient="Iron Ingot",category="Misc"}}))
 
-- mw.log(p.draw_craftable_table({args={item="Void Blade",category="Weapon"}}))

Revision as of 20:19, 8 April 2026

Overview

Functions for making Crafting table. Data comes from Data:Merchant.json.

Functions

draw_table

Creates a table of craftables

  • 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.

{{#invoke:Craft|draw_table|item=Void Blade|merchant=Weaponsmith}}
NameIngredientsMerchant
Longsword.png1
Dark Matter.png1
Gold Ingot.png3
Gold Coin.png50
Weaponsmith



{{#invoke:Craft|draw_table|merchant=Weaponsmith|ingredient=Iron Ingot}}
NameIngredientsMerchant
Coral Fragment.png2
Iron Ingot.png1
Weaponsmith
Iron Ingot.png1
Weaponsmith
Iron Ingot.png2
Weaponsmith
Iron Ingot.png1
Weaponsmith
Iron Ingot.png1
Weaponsmith
Iron Ingot.png1
Bavin.png2
Weaponsmith
Longsword.png1
Spectral Hilt.png1
Cobalt Ingot.png3
Iron Ingot.png3
Gold Coin.png50
Weaponsmith
Iron Ingot.png2
Weaponsmith
Iron Ingot.png1
Weaponsmith



{{#invoke:Craft|draw_table|merchant=Weaponsmith}}
NameIngredientsMerchant
Coral Fragment.png2
Iron Ingot.png1
Weaponsmith
Sterling Axe.png1
Silver Ingot.png1
Weaponsmith
Iron Ingot.png1
Weaponsmith
Sterling Blade.png1
Silver Ingot.png1
Weaponsmith
Club.png1
Cyclops's Club.png1
Grave Essence.png1
Bone.png3
Gold Coin.png50
Weaponsmith
Sterling Bow.png1
Silver Ingot.png1
Weaponsmith
Recurve Bow.png1
Centaur Horn.png1
Bowstring.png5
Gold Coin.png50
Weaponsmith
Cobalt Ore.png3
Weaponsmith
Copper Ore.png3
Weaponsmith
Crystal Ball.png1
Cyclops Eye.png1
Grave Essence.png3
Gold Coin.png50
Weaponsmith
Sterling Dagger.png1
Silver Ingot.png1
Weaponsmith
Rapier.png1
Demon Blood.png1
Bone.png2
Gold Ingot.png3
Gold Coin.png50
Weaponsmith
Axe of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Blade of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Bow of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Dagger of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Rod of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Short Sword of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Staff of Righteousness.png1
Silver Ingot.png2
Weaponsmith
Falchion.png1
Token of Honor.png1
Rusty Broken Sword.png2
Gold Ingot.png3
Gold Coin.png50
Weaponsmith
Iron Ingot.png2
Weaponsmith
Crystal Sword.png1
Froststone Ingot.png1
Weaponsmith
Lantern Shield.png1
Froststone Ingot.png1
Weaponsmith
Spear.png1
Froststone Ingot.png1
Weaponsmith
War Maul.png1
Froststone Ingot.png1
Weaponsmith
Froststone Ore.png3
Weaponsmith
Gold Ore.png3
Weaponsmith
Felling Axe.png1
Gold Ingot.png2
Weaponsmith
Spellbook.png1
Gold Ingot.png1
Weaponsmith
Viking Sword.png1
Gold Ingot.png2
Weaponsmith
Zweihander.png1
Warlord's Broken Sword Blade.png1
Rubysilver Ingot.png2
Silver Ingot.png2
Gold Coin.png50
Weaponsmith
Iron Ingot.png1
Weaponsmith
Castillon Dagger.png1
Frost Wyvern's Claws.png1
Froststone Ingot.png2
Gold Coin.png50
Weaponsmith
Iron Ore.png3
Weaponsmith
Flanged Mace.png1
Firefly's Abdomen.png1
Broken Skull.png3
Gold Ingot.png3
Gold Coin.png50
Weaponsmith
Iron Ingot.png1
Weaponsmith
Crystal Ball.png1
Captured Mana Flakes.png1
Intact Skull.png2
Gold Coin.png50
Weaponsmith
Bardiche.png1
Obsidian Ingot.png2
Weaponsmith
Cutlass.png1
Obsidian Ingot.png1
Weaponsmith
Obsidian Ore.png3
Weaponsmith
Morning Star.png1
Obsidian Ingot.png1
Weaponsmith
Stiletto Dagger.png1
Obsidian Ingot.png1
Weaponsmith
War Hammer.png1
Obsidian Ingot.png1
Weaponsmith
Iron Ingot.png1
Bavin.png2
Weaponsmith
Spellbook.png1
Banshee Sonnet.png1
Broken Skull.png3
Intact Skull.png6
Gold Coin.png50
Weaponsmith
Sterling Rod.png1
Silver Ingot.png1
Weaponsmith
Halberd.png1
Rubysilver Ingot.png2
Weaponsmith
Rubysilver Ore.png3
Weaponsmith
Sterling Short Sword.png1
Silver Ingot.png1
Weaponsmith
Silver Coin.png60
Weaponsmith
Crystal Sword.png1
Ghostly Essence.png1
Rubysilver Ingot.png3
Grave Essence.png3
Gold Coin.png50
Weaponsmith
Spear.png1
Rotten Fluids.png2
Moldy Bread.png5
Gold Ingot.png3
Gold Coin.png50
Weaponsmith
Longsword.png1
Spectral Hilt.png1
Cobalt Ingot.png3
Iron Ingot.png3
Gold Coin.png50
Weaponsmith
Wendigo's Antler Fragment.png1
Mimic Tongue.png1
Maggots.png3
Gold Coin.png50
Weaponsmith
Sterling Staff.png1
Silver Ingot.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Silver Powder.png1
Weaponsmith
Iron Ingot.png2
Weaponsmith
Crystal Ball.png1
Tidestone Ingot.png1
Weaponsmith
Falchion.png1
Tidestone Ingot.png1
Weaponsmith
Kris Dagger.png1
Tidestone Ingot.png1
Weaponsmith
Tidestone Ore.png3
Weaponsmith
Spellbook.png1
Volcanic Ash.png1
Demon Blood.png1
Gold Coin.png50
Weaponsmith
Iron Ingot.png1
Weaponsmith
Troll's Club.png1
Wolf Claw.png5
Bone.png2
Gold Coin.png50
Weaponsmith
Longsword.png1
Dark Matter.png1
Gold Ingot.png3
Gold Coin.png50
Weaponsmith

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

Script error: The function "page" does not exist.



{{#invoke:Craft|page|category=Misc|item=Iron Ingot}}

Script error: The function "page" does not exist.



{{#invoke:Craft|page|category=Misc|item=Iron Ore}}

Script error: The function "page" does not exist.


--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.."]]"
	wt[#wt+1] = 		"<span class='iconamount' style='pointer-events:none;color:#EEEA;font-size:16px'>"..amount.."</span>"
	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>[["
	wt[#wt+1] = merchant_name
	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

function p.draw_ingredient_table(f)
	local ingredient = f.args.ingredient
	local category = f.args.category
	local data = mw.loadJsonData(CATEGORY[category].Data)
	local merchants = data[category][ingredient].incraftingrecipefor
	if count(merchants) == 0 then return "" end

	local wt = {}
	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

	return table.concat(wt)
end

function p.draw_craftable_table(f)
	local item = f.args.item
	local category = f.args.category
	local data = mw.loadJsonData(CATEGORY[category].Data)
	local merchants = data[category][item].iscraftableby
	if count(merchants) == 0 then return "" end

	local wt = {}
	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

	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.draw_ingredient_table({args={ingredient="Iron Ingot",category="Misc"}}))

-- mw.log(p.draw_craftable_table({args={item="Void Blade",category="Weapon"}}))