Module:Items
Jump to navigation
Jump to search
This is a programming module, do not invoke it directly. |
Documentation
[purge]
Module Structure
- All items must have an entry in Module:Items/Data. This provides the basic attributes.
- If an item is Edible, it must also have an entry in Module:Items/Data/Edible
- If an item is Crafted, it must also have an entry in Module:Items/Data/Crafted
- If an item is Equipment, it must also have an entry in Module:Items/Data/Equipment
- If an item can be Enchanted, it must also have an entry in Module:Items/Data/Reagents TODO
Description
This Module will be used for items.
Use: Module:Items/Data, Module:Items/Data/Crafted, Module:Items/Data/Edible, Module:Items/Data/Equipment, Module:Items/Data/Reagents
The above documentation is transcluded from Module:Items/doc. (edit | history)
local TableTools = require("Module:TableTools")
local Utils = require("Module:Utils")
local Pagelist = require("Module:Pagelist")
local List = require("Module:List")
local mw = mw
local gsub = string.gsub
local tinsert = table.insert
local pagelist = Pagelist._main
local keysToList = TableTools.keysToList
local shallowClone = TableTools.shallowClone
local table_size = TableTools.size
local sortedPairs = TableTools.sortedPairs
local formatNum = Utils.formatNum
local pageExists = Utils.pageExists
local sprintf = Utils.sprintf
local strlen = Utils.strlen
local upper = Utils.upper
local tableSort = Utils.tableSort
local makeList = List.makeList
--[[------------------------------------------------]]
--[[--------------- MODULE FUNCTIONS ---------------]]
--[[------------------------------------------------]]
local p = require("Module:BaseModule"):newModule()
local module_data = p:getModuleData("Module:Items/Data")
local main_args = {
parentFirst = true,
wrappers = {
"Template:ItemTable",
"Template:ItemHeader",
"Template:ItemRecipeTable",
"Template:ItemIngredientOf",
"Template:EquipmentByAttribute",
"Template:CookingList",
}
}
p.makeItemTable = p:makeInvokeFunc("_makeItemTable", main_args)
p.makeItemRecipeTable = p:makeInvokeFunc("_makeItemRecipeTable", main_args)
p.getItemHeader = p:makeInvokeFunc("_getItemHeader", main_args)
p.listItemIngredientOf = p:makeInvokeFunc("_listItemIngredientOf", main_args)
p.tableEquipmentByAttribute = p:makeInvokeFunc("_tableEquipmentByAttribute", main_args)
p.listCooking = p:makeInvokeFunc("_listCooking", main_args)
p.generateLootMobTable = p:makeInvokeFunc('_generateLootMobTable', main_args)
p.generateReagentTable = p:makeInvokeFunc("_generate_reagent_table", main_args)
p.ItemIcon = p:makeInvokeFunc("_ItemIcon", main_args)
p.ItemWeight = p:makeInvokeFunc("_ItemWeight", main_args)
--[[------------------------------------------------]]
--[[---------------- PAGE FUNCTIONS ----------------]]
--[[------------------------------------------------]]
----------------------------
-- Make Item Recipe table
----------------------------
function p._makeItemRecipeTable(args, frame) -- luacheck: ignore
local item_name = args[1]
local item_crafted_data = p:getModuleData("Module:Items/Data/Crafted", item_name)
local item_equipment_data = p:getModuleData("Module:Items/Data/Equipment", item_name)
if item_crafted_data == nil then
return sprintf("ERROR: '''%s''' doesn't exist in the [[Module:Items/Data/Crafted|Crafted]] data module!", item_name)
end
local item_material_stats = item_equipment_data and item_equipment_data["Material Stats"] or {}
local item_materials_needed = item_crafted_data["Materials Needed"] or {}
local num_material_stats = table_size(item_material_stats)
local quantity_crafted = item_crafted_data["Quantity Crafted"] or "??"
local time_required = item_crafted_data["Time Required"] or "??"
local stations = shallowClone(item_crafted_data["Station"])
if #stations > 0 then
stations["conjunction"] = " or "
stations["nspace"] = "all"
stations = gsub(pagelist(stations), "%[%[:Hand|Hand%]%]", "Hand")
else
stations = "UNKNOWN"
end
local recipeWikitext = mw.html.create("p"):wikitext(sprintf("%s is crafted via %s.<br><br>", item_name, stations))
local craftingStatsTable = mw.html.create("table")
:addClass("wikitable")
:cssText("text-align: center")
:tag("tr")
:tag("th")
:cssText("text-align: left; width: 130px")
:wikitext("Quantity Crafted")
:done()
:tag("td")
:cssText("width: 20px")
:wikitext(quantity_crafted)
:done()
:done()
:tag("tr")
:tag("th")
:cssText("text-align: left; width: 130px")
:wikitext("Time Required")
:done()
:tag("td")
:cssText("width: 20px")
:wikitext(time_required)
:done()
:done()
:done()
local itemsNode
local itemsNode_leftCellCss = "width:75%;"
local itemsNode_rightCellCss = "width:25%;"
local bonusStatsNode
local stats
local num_stats
local count
local name
local row
local itemTable_leftCellCss = "text-align: left; width: 100%"
local itemTable_rightCellCss = "text-align: center"
local itemTableWidth = "300px"
if num_material_stats > 0 then
itemsNode_leftCellCss = "width:50%;"
itemsNode_rightCellCss = "width:50%;"
itemTable_leftCellCss = "text-align: left; width: 65%"
itemTableWidth = "550px"
end
local itemTable = mw.html.create("table")
:addClass("wikitable")
:cssText(sprintf("width: %s", itemTableWidth))
:tag("caption")
:addClass("game-item-table")
:cssText("caption-side:bottom; font-size:90%; text-align:left; font-weight:normal; padding-left:5px")
:wikitext("*One recipe per row")
:done()
local itemTableHeaderRow = mw.html.create("tr")
:tag("th")
:cssText(itemTable_leftCellCss)
:wikitext("Recipes")
:done()
if num_material_stats > 0 then
itemTableHeaderRow
:tag("th")
:cssText(itemTable_rightCellCss)
:wikitext("Bonus Stats")
:done()
end
itemTable:node(itemTableHeaderRow:done())
for idx, recipe in ipairs(item_materials_needed) do
-- Create wikitext for recipe items and bonus stats
itemsNode = mw.html.create("table"):cssText("width: 100%")
bonusStatsNode = mw.html.create("div"):cssText("text-align: center")
for _, item in ipairs(recipe) do
name = item["name"]
itemsNode:tag("tr")
:tag("td")
:cssText(sprintf("text-align: left; background-color:inherit; border:none;%s", itemsNode_leftCellCss))
:wikitext(sprintf("[[%s]]", name))
:done()
:tag("td")
:cssText(sprintf("text-align: center; background-color:inherit; border:none;%s", itemsNode_rightCellCss))
:tag("div")
:cssText("display: inline-block; vertical-align: middle; margin-right: 4px")
:wikitext(item["quantity"])
:done()
:tag("div")
:cssText("display: inline-block")
:wikitext(sprintf("[[File:%s|20px|alt=%s|link=]]", item["image"], name))
:done()
:done()
:done()
end
-- Get material stats
stats = item_material_stats[idx] or {}
num_stats = table_size(stats)
count = 1
for k, v in pairs(stats) do
k = pageExists(k) and sprintf("[[%s]]", k) or k
bonusStatsNode:tag("div")
:cssText("display: inline-block; vertical-align: middle; margin-right: 4px")
:wikitext(k)
:done()
bonusStatsNode:tag("div")
:cssText("display: inline-block")
:wikitext(v)
:done()
if count < num_stats then
bonusStatsNode:wikitext("<br>")
end
count = count + 1
end
itemsNode:done()
bonusStatsNode:done()
row = mw.html.create("tr")
:tag("td")
:cssText("vertical-align:middle")
:node(itemsNode)
:done()
if num_material_stats > 0 then
row:tag("td")
:cssText("vertical-align:middle")
:node(bonusStatsNode)
:done()
end
itemTable:node(row:done())
end
recipeWikitext
:node(craftingStatsTable)
:wikitext("<br>")
:node(itemTable:done())
return sprintf("%s", tostring(recipeWikitext:allDone()))
end
------------------------
-- Make horizontal table
------------------------
local function make_htable(targetTable)
local horizontalTable = mw.html.create("table")
:addClass("wikitable")
:attr("style"," margin-left: auto; margin-right: auto")
:cssText("text-align: center")
:tag("tr")
for k, v in sortedPairs(targetTable) do
horizontalTable
:tag("th")
:wikitext(k)
:done()
end
horizontalTable
:tag("tr")
for k, v in sortedPairs(targetTable) do
horizontalTable
:tag("td")
:wikitext(v)
:done()
end
horizontalTable
:done()
return sprintf("%s", tostring(horizontalTable:allDone()))
end
----------------------------
-- Make Item Table
----------------------------
function p._makeItemTable(args, frame) -- luacheck: ignore
local item_name = args[1]
local item_data = module_data[item_name]
local item_image = ""
if item_data == nil then
--local helpstring = ""
--for k,v in pairs(mw.title.getCurrentTitle()) do
-- helpstring = string.format("%s, %s -> %s", helpstring, tostring(k), tostring(v))
--end
item_name = tostring(mw.title.getCurrentTitle()["basePageTitle"])
item_data = module_data[item_name]
if item_data == nil then
--return sprintf("<br>%s<br>%s<br>ERROR: %s HAS NO HEADER! [[Category:Item HAS NO HEADER]]", t, helpstring, item_name)
return sprintf("<br>ERROR: %s HAS NO TABLE! [[Category:Item HAS NO TABLE]]", item_name)
else
item_image = item_data["image"]
end
else
item_image = item_data["image"]
end
if item_data == nil or strlen(item_data) == 0 then
return sprintf("%s DOES NOT EXIST!", item_name)
end
if item_image == nil or strlen(item_image) == 0 or not pageExists(sprintf("File:%s", item_image)) then
item_image = "Icon Unknown.jpg"
end
-- Need to modify values for formatting consistency
item_data = shallowClone(item_data)
-- CSS is set below after the local functions
local itemTable = mw.html.create("table")
-- CSS for left and right table columns
local leftCellCss = "text-align:center; width:50%"
local rightCellCss = leftCellCss
-- Each section can order its own keys
local data_key_order
-- Adds a section header to table row
local function add_section_header(name)
itemTable
:tag("tr")
:tag("th")
:attr("class", "section-header")
:attr("colspan", "2")
:attr("style", "background-color:DimGrey; padding: 2px 0")
:cssText("text-align: center;")
:wikitext(sprintf("%s", name))
:done()
:done()
end
-- Add a common table row to table
local function add_basic_row(left_data, right_data)
if pageExists(left_data) then
left_data = sprintf("[[%s]]", left_data)
end
if type(right_data) == "table" then
itemTable
:tag("tr")
:tag("th")
:cssText(leftCellCss)
:wikitext(left_data)
:done()
:tag("td")
:cssText(rightCellCss)
:wikitext(make_htable(right_data))
:done()
:done()
else
itemTable
:tag("tr")
:tag("th")
:cssText(leftCellCss)
:wikitext(left_data)
:done()
:tag("td")
:cssText(rightCellCss)
:wikitext(right_data)
:done()
:done()
end
end
-- Add a common table row to table without Link
local function add_basic_row_nolink(left_data, right_data)
if type(right_data) == "table" then
itemTable
:tag("tr")
:tag("th")
:cssText(leftCellCss)
:wikitext(left_data)
:done()
:tag("td")
:cssText(rightCellCss)
:wikitext(make_htable(right_data))
:done()
:done()
else
itemTable
:tag("tr")
:tag("th")
:cssText(leftCellCss)
:wikitext(left_data)
:done()
:tag("td")
:cssText(rightCellCss)
:wikitext(right_data)
:done()
:done()
end
end
-- Add several common table rows to table
local function add_basic_rows(key_order, row_data)
local right_data
for _, left_data in ipairs(key_order) do
right_data = row_data[left_data]
if right_data ~= nil then
add_basic_row(left_data, right_data)
end
end
end
-- Name header, Image
itemTable
:attr("class", "game-item-table")
:cssText("float: left; background-color:inherit; border: 2px solid dimgrey; border-collapse: separate; border-radius: 25px; width: 350px; margin-left: 15px; margin-right: 15px;")
:done()
:tag("tr")
:tag("th")
:attr("colspan", "2")
:cssText("color:#fff; text-align: center; font-size: 18px; font-weight: bold; font-style: italic; width: 110%")
:wikitext(sprintf("[[%s]]", item_name))
:done()
:done()
:tag("tr")
:tag("td")
:attr("colspan", "2")
:wikitext(sprintf("[[File:%s|frameless|center|class=section-header]]", item_image))
:done()
:done()
-- Some editors may use a comma and others a dot for number decimals
-- Replace comma with dot to avoid tonumber() and lang.formatNum issues
if item_data["Weight"] ~= nil then
item_data["Weight"] = sprintf("%s kg", formatNum(item_data["Weight"]))
end
-- Enforce order of keys for base data
data_key_order = {"Source", "Max Stack", "Weight"}
add_basic_rows(data_key_order, item_data)
-- Guarantee the order these appear in the table for consistency
local item_edible_data = p:getModuleData("Module:Items/Data/Edible", item_name)
local item_reagent_data = p:getModuleData("Module:Items/Data/Reagents", item_name)
local item_equipment_data = p:getModuleData("Module:Items/Data/Equipment", item_name)
-- Process Edible data
if item_edible_data ~= nil then
add_section_header("[[Edible]]")
for k, v in pairs(item_edible_data) do
add_basic_row(k, v)
end
end
-- Process Enchanting Reagent data
if item_reagent_data ~= nil then
add_section_header("[[:Category:Reagents|Enchanting Reagent]]")
for _, name in ipairs(keysToList(item_reagent_data)) do
for _, ele in ipairs(item_reagent_data[name]) do
add_basic_row_nolink(name, ele)
end
end
end
-- Process Equipment stats
if item_equipment_data ~= nil then
add_section_header("[[:Category:Game_mechanics|Stats]]")
data_key_order = {
"Armor Type", "Weapon Type", "Durability", "Slot", "Physical Armor", "Magical Armor", "Slash Armor", "Pierce Armor", "Crush Armor", "Magic Resistance", "Cold Resistance", "Poison Resistance", "Acid Resistance", "Fire Resistance", "Shock Resistance", "Cold Insulation", "Heat Insulation", "Encumbrance",
"Damage Type", "Damage Attribute", "Versatile", "Attack Speed", "Accuracy", "Evasion", "Range",
"Physical Damage Increase", "Shock Damage Increase", "Acid Damage Increase", "Spell Damage Increase", "Ice Damage Increase", "Energy Damage Increase", "Fire Damage Increase",
"Corrosion Stacks On Hit", "Warm Stacks On Hit", "Chilled Stacks On Hit", "Poison Stacks On Hit", "Shocked Stacks On Hit",
"Weapon Damage", "Spell Damage", "Luck", "Willpower", "Fortitude", "Health", "Mana Regeneration", "Health Regeneration",
"Strength", "Intelligence", "Dexterity", "Perception", "Charisma","Constitution",
"Damage"
}
add_basic_rows(data_key_order, item_equipment_data)
end
-- Native properties
------
data_key_order = {
"Armor Penetration", "Bashing", "Block Chance", "Cooldown Reduction", "Critical Damage", "Lower Mana Cost", "Poison Chance", "Special Properties", "Critical Chance"
}
-- Check if equipment has native properties
local nativeCheck = false
if item_equipment_data ~= nil then
for stat, data in pairs(item_equipment_data) do
for key, nativeProperty in pairs(data_key_order) do
if stat == nativeProperty then nativeCheck = true end
if nativeCheck == true then break end
end
if nativeCheck == true then break end
end
-- create section header and rows with data
if nativeCheck == true then
add_section_header("Native properties")
add_basic_rows(data_key_order, item_equipment_data)
end
end
return sprintf("%s", tostring(itemTable:allDone()))
end
----------------------------
-- Get Item Header
----------------------------
function p._getItemHeader(args, frame) -- luacheck: ignore
local item_name = args[1]
local item_data = module_data[item_name]
-- Removed Item Image Link in front of Description, because Item Image is in the Item Info Box
--local item_image = ""
if item_data == nil then
--local helpstring = ""
--for k,v in pairs(mw.title.getCurrentTitle()) do
-- helpstring = string.format("%s, %s -> %s", helpstring, tostring(k), tostring(v))
--end
item_name = tostring(mw.title.getCurrentTitle()["basePageTitle"])
item_data = module_data[item_name]
if item_data == nil then
--return sprintf("<br>%s<br>%s<br>ERROR: %s HAS NO HEADER! [[Category:Item HAS NO HEADER]]", t, helpstring, item_name)
return sprintf("<br>ERROR: %s HAS NO HEADER! [[Category:Item HAS NO HEADER]]", item_name)
--else
--item_image = item_data["image"]
end
--else
--item_image = item_data["image"]
end
--if item_image == nil or strlen(item_image) == 0 or not pageExists(sprintf("File:%s", item_image)) then
-- item_image = "Icon Unknown.jpg"
--end
local res = {}
local description = item_data["description"]
--local image = item_data["envImage"]
--if image ~= nil then
-- if strlen(image) > 0 and pageExists(sprintf("File:%s", image)) then
-- table.insert(res, sprintf('[[File:%s|left|200px]]\n', image))
-- else
-- table.insert(res, sprintf('[[File:%s|left|200px]]\n', item_image))
-- end
--end
if description ~= nil and strlen(description) > 0 then
local desc_linky = string.gsub(description, "<style=gold>", "[[")
desc_linky = string.gsub(desc_linky, "</style>", "]]")
table.insert(res,sprintf('%s\n', desc_linky))
else
table.insert(res,sprintf("[[Category:Items with missing Description]]", item_name))
end
return table.concat(res,'')
end
----------------------------
-- Return items where args is an ingredient
----------------------------
function p._listItemIngredientOf(args, frame) -- luacheck: ignore
local item_name = args[1]
local item_crafted_data = p:getModuleData("Module:Items/Data/Crafted")
local list = {}
local res = {}
for name, _ in pairs(item_crafted_data) do
local item_data = item_crafted_data[name]
local recipe_list = item_data["Materials Needed"]
for _, materials_info in ipairs(recipe_list) do
for _, item_info in ipairs(materials_info) do
if item_info["name"] == item_name then
list[#list + 1] = name
end
end
end
end
if #list ~= 0 then
table.insert(res, sprintf("%s is used in the following recipes:\n",item_name))
for _, v in pairs(TableTools.removeDuplicates(Utils.tableSort(list))) do
table.insert(res,sprintf('* [[%s]]\n',v))
end
else
table.insert(res,"There are no known recipes, which this item is part of.")
end
return table.concat(res,'')
end
----------------------------
-- Return items that go in a given character slot (i.e. Head, Chest, Hands)
----------------------------
local function getEquipmentInSlot(slot)
local item_equipment_data = p:getModuleData("Module:Items/Data/Equipment")
local data
if not slot then
data = item_equipment_data
else
data = {}
for item_name, item_data in pairs(item_equipment_data) do
if upper(slot) == upper(item_data["Slot"]) then
data[item_name] = item_data
end
end
end
return data
end
----------------------------
-- Return items where args is a property (i.e. Evasion, Melee Damage)
----------------------------
function p._tableEquipmentByAttribute(args, frame) -- luacheck: ignore
local item_attribute = args[1]
local item_equipment_data = getEquipmentInSlot(args[2])
local item_crafted_data = p:getModuleData("Module:Items/Data/Crafted")
local found_items = false
local itemTable = mw.html.create("table")
:addClass("wikitable sortable")
:cssText("text-align: center; width: 50%")
itemTable
:tag("tr")
:tag("th"):wikitext("Item Name"):done()
:tag("th"):wikitext("Slot"):done()
:tag("th"):wikitext(item_attribute):done()
:tag("th"):wikitext(sprintf("%s from Recipes", item_attribute)):done()
:done()
local slot
local material_stats_data
local material_stats_value
local item_crafted
local materials_needed_data
local armor_types = {"Physical Armor","Slash Armor", "Pierce Armor", "Crush Armor"}
local physical_armor_value
local slash_armor_value
local pierce_armor_value
local crush_armor_value
for item_name, item_attributes in sortedPairs(item_equipment_data) do
local attribute_value = ""
local materials_needed_names = {}
slot = item_attributes["Slot"]
material_stats_data = item_attributes["Material Stats"]
item_crafted = item_crafted_data[item_name]
physical_armor_value = item_attributes["Physical Armor"]
slash_armor_value = item_attributes["Slash Armor"]
pierce_armor_value = item_attributes["Pierce Armor"]
crush_armor_value = item_attributes["Crush Armor"]
-- Special case for Armor to get all types
if item_attribute == "Armor" and ((physical_armor_value and physical_armor_value ~= 0) or (slash_armor_value and slash_armor_value ~= 0) or (pierce_armor_value and pierce_armor_value ~= 0) or (crush_armor_value and crush_armor_value ~= 0)) then
local armor_type_values = {
physical_armor_value or 0,
slash_armor_value or 0,
pierce_armor_value or 0,
crush_armor_value or 0,
}
for idx, armor_type_value in ipairs(armor_type_values) do
if armor_type_value > 0 then
attribute_value = sprintf("%s<br>[[%s]]: %s", attribute_value, armor_types[idx], armor_type_value)
end
end
-- remove leading and trailing line breaks
attribute_value = gsub(attribute_value, "^<br>", "")
attribute_value = gsub(attribute_value, "<br>$", "")
else
attribute_value = item_attributes[item_attribute]
end
-- Check if any recipes offer the attribute we're looking for
local armorString = " "
if material_stats_data ~= nil then
for idx, stats in ipairs(material_stats_data) do
for k, v in pairs(stats) do
if (k == item_attribute) or (item_attribute == "Armor" and (k == "Physical Armor" or k == "Slash Armor" or k == "Pierce Armor" or k == "Crush Armor")) then
-- Get the value for the attribute
material_stats_value = v
armorString = " " .. k .. " "
-- Find what materials are needed to acquire the attribute on the item
materials_needed_data = item_crafted and item_crafted["Materials Needed"]
if materials_needed_data ~= nil then
local materials_needed_idx = materials_needed_data[idx] or {}
for _, craft_items in ipairs(materials_needed_idx) do
tinsert(materials_needed_names, craft_items["name"])
end
end
end
end
end
end
-- Check if the item itself has the attribute
if attribute_value ~= nil or #materials_needed_names > 0 then
local recipe_str = "----"
if material_stats_value ~= nil and #materials_needed_names > 0 then
recipe_str = sprintf("%s%sif made with %s", material_stats_value, armorString, pagelist(materials_needed_names))
end
if type(attribute_value) == "table" then
itemTable
:tag("tr")
:tag("td"):wikitext(sprintf("[[%s]]", item_name)):done()
:tag("td"):wikitext(slot or ""):done()
:tag("td"):wikitext(make_htable(attribute_value)):done()
:tag("td"):wikitext(recipe_str):done()
:done()
else
itemTable
:tag("tr")
:tag("td"):wikitext(sprintf("[[%s]]", item_name)):done()
:tag("td"):wikitext(slot or ""):done()
:tag("td"):wikitext(attribute_value or "----"):done()
:tag("td"):wikitext(recipe_str):done()
:done()
end
found_items = true
end
end
if found_items == false then
itemTable
:tag("tr")
:tag("td")
:attr("colspan", "4")
:wikitext(sprintf("No items with [[%s]] found", item_attribute))
:done()
:done()
end
return sprintf("%s", tostring(itemTable:allDone()))
end
----------------------------
------------------------------------------
----- Cooking - list
------------------------------------------
function p._listCooking(args, frame) -- luacheck: ignore
local module_crafted = p:getModuleData("Module:Items/Data/Crafted")
local module_edible = p:getModuleData("Module:Items/Data/Edible")
local cookingList = {}
for craftedName,_ in pairs(module_crafted) do
if module_edible[craftedName] ~= nil then
cookingList[#cookingList + 1] = sprintf("[[%s]]", craftedName)
end
end
return makeList("bulleted",tableSort(cookingList))
end
--[[------------------------------------------------]]
--[[------------- Item Page Functions --------------]]
--[[------------------------------------------------]]
function p._ItemIcon(args, frame) -- luacheck: ignore
if module_data[args[1]] == nil or module_data[args[1]]['image'] == nil then return "ERROR: NOT FOUND" end
if module_data[args[1]]['image'] == "" then return "Icon Unknown.jpg" else return module_data[args[1]]['image'] end
end
function p._ItemWeight(args, frame) -- luacheck: ignore
if module_data[args[1]] == nil or module_data[args[1]]['Weight'] == nil then return "ERROR: NOT FOUND" else return module_data[args[1]]['Weight'] end
end
function dict_to_sorted_list(data)
local result = {}
for entry_name,_ in pairs(data) do
table.insert(result, entry_name)
end
table.sort(result)
return result
end
function get_icon(item_table, item_name)
local reagent_entry = item_table[item_name]
if reagent_entry == nil then
return nil
end
local reagent_icon = reagent_entry["image"]
if strlen(reagent_icon) > 0 and pageExists(string.format("File:%s", reagent_icon)) then
return reagent_icon
else
return nil
end
end
local SandBoxTools = require("Module:Sandbox/Maltos")
local reagent_table = p:getModuleData("Module:Items/Data/Reagents")
local item_table = p:getModuleData("Module:Items/Data")
function p._generate_reagent_table(args, frame) -- luacheck: ignore
--function generate_reagent_table(args, frame) -- luacheck:
local rare_icon_str = string.format("[[File:RarityIcon.png|16px|link=]]")
local aspect_dict = {}
for reagent_name, reagent_aspects in pairs(reagent_table) do
for aspect_name, aspect_value in pairs(reagent_aspects) do
aspect_dict[aspect_name] = true
end
end
aspect_dict["Rarity"] = nil
local aspect_list = dict_to_sorted_list(aspect_dict)
local reagent_list = dict_to_sorted_list(reagent_table)
local result_entries = {}
for _, reagent_name in pairs(reagent_list) do
local reagent_aspects = reagent_table[reagent_name]
local reagent_aspect_data = {}
for aspect_idx, aspect_name in pairs(aspect_list) do
reagent_aspect_entry = reagent_aspects[aspect_name]
if reagent_aspect_entry == nil then
reagent_aspect_entry = ""
else
reagent_aspect_entry = reagent_aspect_entry[1]
end
table.insert(reagent_aspect_data, reagent_aspect_entry)
end
result_entries[reagent_name] = reagent_aspect_data
end
local aspect_list_icons = {}
for _, aspect_name in pairs(aspect_list) do
local aspect_entry_icon = string.format("[[File:Icon_Aspects_%s.png|30px|alt=%s|link=]]", aspect_name, aspect_name)
local aspect_entry_header_html = string.format("<th><div class='tooltip'>%s<span class='tooltiptext'>%s</span></div></th>", aspect_entry_icon, aspect_name)
table.insert(aspect_list_icons, aspect_entry_header_html)
end
local table_header = "<table id='reagentTable' class='wikitable sortable' style='text-align: center><tr><th>Reagent</th><th>Mobs</th><th>Rarity</th>" .. table.concat(aspect_list_icons) .. "</tr>"
local table_data_list = {}
local table_footer = "</table>"
for _, reagent_name in pairs(reagent_list) do
local reagent_data = result_entries[reagent_name]
local reagent_rarity = reagent_table[reagent_name]["Rarity"][1]
local reagent_icon = get_icon(item_table, reagent_name)
-- local reagent_source_table = SandBoxTools.generateLootMobTable({reagent_name})
--local reagent_source_table = SandBoxTools.generateLootMobTable("Animal Bones")
local reagent_source_table = p._generateLootMobTable({reagent_name},{})
-- dummy data to test memory consumption
--local reagent_source_table = "dummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumptiondummy data to test memory consumption"
--local reagent_source_table = "Animal Bones"
local reagent_icon_string = ""
if reagent_icon ~= nil then
reagent_icon_string = string.format("[[File:%s|30px|alt=%s|class=smoothBorderImage]]", reagent_icon, reagent_name)
end
--table.insert(reagent_data, 1, string.format("[[%s]]", reagent_name))
--for x,y in pairs(reagent_data) do
-- print(string.format("%s %s %s",reagent_name,aspect_list[x], y))
--end
--print(reagent_data)
local row_id = string.gsub(reagent_name, "%s+", "")
row_id = string.gsub(reagent_name, "'", "")
local title = string.gsub(reagent_name, "'", "")
local reagent_aspect_entries = {}
for i,aspect_value in pairs(reagent_data) do
local reagent_aspect_cell_html = ""
if aspect_value ~= "" then
local aspect_tooltip_entries = {}
for reagent_aspect_idx, av in pairs(reagent_data) do
if av ~= "" then
local aspect_tooltip_entry = string.format("%s %s", av, aspect_list[reagent_aspect_idx])
table.insert(aspect_tooltip_entries, aspect_tooltip_entry)
end
end
local reagent_tooltip_aspect_description = table.concat(aspect_tooltip_entries, "<br>")
reagent_aspect_cell_html = string.format("<td><div class='tooltip'>%s<span class='tooltiptext'>%s<br>%s<br>%s %s<br>%s</span></div></td>", aspect_value, reagent_icon_string, reagent_name, rare_icon_str, reagent_rarity, reagent_tooltip_aspect_description)
else
reagent_aspect_cell_html = string.format("<td>%s</td>",aspect_value)
end
table.insert(reagent_aspect_entries, reagent_aspect_cell_html)
end
local reagent_entry_line = string.format("<tr style='white-space: nowrap;' id='%s'><td>[[%s]] %s</td><td>%s</td><td>%s</td>", row_id, reagent_name, reagent_icon_string, reagent_source_table, reagent_rarity) .. table.concat(reagent_aspect_entries) .. "</tr>"
--local reagent_entry_line = string.format("<tr style='white-space: nowrap;' id='%s' title='%s'><td>[[%s]] %s</td><td>", row_id, title, reagent_name, reagent_icon_string) .. table.concat(reagent_data, "</td><td>") .. "</td></tr>"
table.insert(table_data_list, reagent_entry_line)
end
local table_string = table_header .. table.concat(table_data_list) .. table_footer
--print(table_string)
--return table_string
return mw.getCurrentFrame():preprocess(table_string)
end
local data_module_creature = p:getModuleData("Module:Creature/data")
local data_module_creature_loot = p:getModuleData("Module:Creature/data/Loot")
function check_mob_as_loot(mob_name, loot_name) -- luacheck: ignore
local mob_loot = data_module_creature_loot[mob_name]
if mob_loot == nil then
return false
end
local has_loot = false
for idx, loot_entry in mob_loot["Item Drops"] do
local loot_entry_name = loot_entry["Item Name"]
if loot_entry_name ~= nil and loot_entry_name == loot_name then
has_loot = true
end
end
return has_loot
end
function p._generateLootMobTable(args, frame) -- luacheck: ignore
local reagent_name = args[1]
local gem_types = {"Chipped", "Fine", "Flawless"}
local gem_names = {"Amethyst", "Diamond", "Ruby", "Emerald", "Sapphire", "Topaz"}
local loot_dict = {}
loot_dict["Gold"] = {}
for mob_entry_idx, mob_entry in pairs(data_module_creature_loot) do
local mob_name = mob_entry["Monster Name"]
if mob_name ~= nil and #mob_name > 3 then
--if reagent_name == nil or reagent_name == "" or check_mob_as_loot(mob_name, reagent_name) then
if true then
-- different loot items
for loot_entry_idx, loot_entry in pairs(mob_entry["Item Drops"]) do
local loot_name = loot_entry["Item Name"]
if loot_name ~= nil and #loot_name > 2 then
if loot_dict[loot_name] == nil then
loot_dict[loot_name] = {}
end
-- shouldnt happen
--if loot_dict[loot_name][mob_name] ~= nil then
-- loot_dict[loot_name][mob_name] = {}
--end
local mob_loot_entry = {}
mob_loot_entry["Minimum Quantity"] = loot_entry["Minimum Quantity"]
mob_loot_entry["Maximum Quantity"] = loot_entry["Maximum Quantity"]
mob_loot_entry["Drop Probability"] = loot_entry["Drop Probability"]
loot_dict[loot_name][mob_name] = mob_loot_entry
end
end
-- gold here
if tonumber(mob_entry["Minimum Gold"]) > 0 then
local gold_entry = {}
gold_entry["Minimum Quantity"] = mob_entry["Minimum Gold"]
gold_entry["Maximum Quantity"] = mob_entry["Maximum Gold"]
gold_entry["Drop Probability"] = "1.0"
loot_dict["Gold"][mob_name] = gold_entry
end
-- gems here
for gem_name_idx=1,#gem_names do
local gem_name = gem_names[gem_name_idx]
if mob_entry["Drops " .. gem_name] == "True" then
for gem_type_idx=1,#gem_types do
gem_type = gem_types[gem_type_idx]
gem_prob = mob_entry[gem_type .. " Chance"]
if gem_prob ~= "0" then
gem_entry = {}
gem_entry["Minimum Quantity"] = 0
gem_entry["Maximum Quantity"] = mob_entry["Maximum Gems"]
gem_entry["Drop Probability"] = gem_prob
if loot_dict[gem_type .. " " .. gem_name] == nil then
loot_dict[gem_type .. " " .. gem_name] = {}
end
loot_dict[gem_type .. " " .. gem_name][mob_name] = gem_entry
end
end
end
end
end
end
end
-- generate the table rows
local res = {}
if reagent_name ~= nil and reagent_name ~= "" then
local loot_data = loot_dict[reagent_name]
if loot_data == nil then
return ""
end
local loot_name = reagent_name
local small_table_string = "<table class='wikitable sortable mw-collapsible mw-collapsed mw-collapsible-toggle-default' id='loot_" .. loot_name .. "' style='margin: auto; text-align: center;'><caption></caption><tr style='background-color: #1c3464;'><th data-sort-type=text>Mob Name</th><th data-sort-type=text>Mob CR</th><th data-sort-type=number>Loot Min</th><th data-sort-type=number>Loot Max</th><th data-sort-type=number>Loot Probability</th></tr>"
for mob_name, loot_details in pairs(loot_data) do
local mob_cr = data_module_creature[mob_name]["ChallengeRating"]
small_table_string = small_table_string .. sprintf("<tr><td>[[%s]]</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>", mob_name, mob_cr, loot_details["Minimum Quantity"], loot_details["Maximum Quantity"], loot_details["Drop Probability"])
end
small_table_string = small_table_string .. "</table>"
return small_table_string
end
for loot_name, loot_data in pairs(loot_dict) do
local loot_string = "<tr><td>" .. sprintf("<span id=\"%s\">[[%s]]</span>", loot_name, loot_name) .."</td><td><table class='wikitable sortable' id='loot_" .. loot_name .. "' style='margin: auto; text-align: center;'><tr style='background-color: #1c3464;'><th data-sort-type=text>Mob Name</th><th data-sort-type=text>Mob CR</th><th data-sort-type=number>Loot Min</th><th data-sort-type=number>Loot Max</th><th data-sort-type=number>Loot Probability</th></tr>"
for mob_name, loot_details in pairs(loot_data) do
mob_cr = data_module_creature[mob_name]["ChallengeRating"]
loot_string = loot_string .. sprintf("<tr><td>[[%s]]</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>", mob_name, mob_cr, loot_details["Minimum Quantity"], loot_details["Maximum Quantity"], loot_details["Drop Probability"])
end
loot_string = loot_string .. "</table></tr>"
table.insert(res, loot_string)
end
--if true then
-- return string.format("end of loop for: '%s'", reagent_name)
--end
return mw.getCurrentFrame():preprocess("<table class='wikitable sortable' id='lootMobTable' style='margin: auto; text-align: center;'><caption>Loot Mob Listing</caption><tr style='background-color: #1c3464;'><th data-sort-type=text>Loot Name</th><th>Monster Data</th></tr>" .. table.concat(res,"") .. "</table>")
end
------------------------------------------
return p