Module:Item
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Item/doc
local p = {}
local func = require('Module:Func')
local data = mw.loadData('Module:Item/data')
local function resolveAlias(alias)
if alias == nil then return nil end
return data.aliases[alias] or alias
end
local function getStat(item, stat)
return data.stats[item][stat]
end
local function getExtraStat(item, stat)
extraStats = data.extraStats[item]
return extraStats and extraStats[stat] or nil
end
local function getPrice(item, priceType)
local tradeable = not func.has_value(cats, "NoDropNoTrade")
if not tradeable then
return ""
end
local value = tonumber(data.stats[item].value)
local arcademod = tonumber(data.stats[item].arcademod) or 1
if not value then
return ""
end
local extraStats = data.extraStats[item]
local tags = extraStats and extraStats.tags or {}
local cats = data.stats[item].cat
local inStory = not func.has_value(tags, "NotInStory")
local inArcade = not func.has_value(tags, "NotInArcade")
local storyMerchant = func.has_value(tags, "StoryBuy")
local arcadeMerchant = func.has_value(tags, "ArcadeBuy")
local buyOnly = func.has_value(tags, "BuyOnly")
local equippable = (
func.has_value(cats, "Weapon") or
func.has_value(cats, "Shoes") or
func.has_value(cats, "Shield") or
func.has_value(cats, "Hat") or
func.has_value(cats, "Facegear") or
func.has_value(cats, "Armor") or
func.has_value(cats, "Accessory")
)
if inStory then
if priceType == "storybuy" then
return storyMerchant and value or "No Merchant"
elseif priceType == "storysell" then
return buyOnly and "Bought Only" or math.floor(value / 2)
elseif priceType == "storybuyback" then
return buyOnly and "Bought Only" or value * 2
end
end
if inArcade then
if priceType == "arcadebuy" then
return arcadeMerchant and value * arcademod or "No Merchant"
elseif priceType == "arcadesell" then
-- Equipment has an additional 50% sell penalty in Arcade
return buyOnly and "Bought Only" or math.floor(0.5 * math.floor(value * arcademod) * (equippable and 0.5 or 1))
end
end
return ""
end
local getters = {
name = getStat,
desc = getStat,
sprite = function(item)
-- Some items might not have a sprite uploaded yet
return getExtraStat(item, 'sprite') or "Placeholder.png"
end,
type = function(item)
return data.typeToLink[data.stats[item].type] or "Unknown Type"
end,
class = function(item)
return data.typeToClass[data.stats[item].type] or "Unknown Class"
end,
bowdmg = getExtraStat,
atk = getStat,
matk = getStat,
aspd = getStat,
cspd = getStat,
maxhp = getStat,
maxep = getStat,
epreg = getStat,
def = getStat,
shldhp = getStat,
crit = getStat,
critdmg = getStat,
special = function(item)
return data.effects[data.stats[item].special]
end,
foodtype = getExtraStat,
foodexp = getExtraStat,
pricestory = getExtraStat,
pricearcade = getExtraStat,
storybuy = getPrice,
storysell = getPrice,
storybuyback = getPrice,
arcadebuy = getPrice,
arcadesell = getPrice,
storyAvailable = function(item)
local extraStats = data.extraStats[item]
local exists = not func.has_value(extraStats and extraStats.tags or {}, "NotInStory")
return exists and "Yes" or "No"
end,
arcadeAvailable = function(item)
local extraStats = data.extraStats[item]
local exists = not func.has_value(extraStats and extraStats.tags or {}, "NotInArcade")
return exists and "Yes" or "No"
end
}
function p.data(frame)
local alias = frame.args[1]
local stat = frame.args[2]
local item = resolveAlias(frame.args[1])
local softErrors = (frame.args.softErrors ~= nil)
local function err(msg)
return softErrors and "Error" or ("Error: " .. msg)
end
if not item then return err("Missing item") end
if not stat then return err("Invalid stat") end
if not data.stats[item] then
if alias == item then
return err("Item " .. item .. " does not exist")
else
return err("Item " .. alias .. " (" .. item .. ") does not exist")
end
end
local getter = getters[stat]
if not getter then
return err("Stat " .. stat .. " does not exist")
end
return getter(item, stat) or ""
end
--[[
Random Item function
Returns a random item's ID.
The function will try to find a random item that is not nil (i.e. its Template:Itembox renders at least partially correct).
If it cannot do so in X tries, it will default to Wooden Sword's ID.
--]]
-- Item ban list
-- All matching keys will be skipped
-- Used for problematic items, or items that may spoil story elements by accident
local randomBanList = {
"default",
-- Additional Stuff
"arrowquiver",
"silverpoint",
"goldpoint",
"talentpoint",
"threetalentpoints",
"healthorb",
"biggoldcoin",
-- Furniture
"wisp_furniture"
}
function p.randomitem(frame)
-- This function is potentially expensive
mw.incrementExpensiveFunctionCount()
math.randomseed(os.time())
-- Build key table
local keys = {}
local size = 1
for key, value in pairs(data) do
if not func.has_value(randomBanList, key) then
keys[size] = key
size = size + 1
end
end
local tries = 0
local maxTries = 20
while tries < maxTries do
tries = tries + 1
local nextkey = keys[math.random(size - 1)]
local next = data.stats[resolveAlias(nextKey)]
if next then
-- OK
return nextkey
end
end
-- Failed
return 'woodensword'
end
--[[
Featured Item function
Returns a random item's ID from the attached featuredItems list.
--]]
-- List created by Marioalexsan at 28 Dec 2020
local featuredItems = {
"bladeofechoes",
"toyaxe",
"laserclaymore",
"staffofslimes",
"marinosrapier",
"promo_shield",
"solemshield",
"energyshield",
"crystalshield",
"hauntedblindfold",
"daisyarmor",
"crabbyhelm",
"purplepetalgarland",
"crystalpumps",
"rollerblades",
"eazsunring",
"mysteriouscube",
"kobestag",
"triskele",
"magicbattery",
"skullring",
"hoodofdarkness",
"redslimekinghat"
}
function p.featureditem(frame)
-- This function is potentially expensive
mw.incrementExpensiveFunctionCount()
math.randomseed(os.time())
local size = #featuredItems + 1
local tries = 0
local maxTries = 20
while tries < maxTries do
tries = tries + 1
local nextkey = featuredItems[math.random(size - 1)]
local next = data.stats[resolveAlias(nextKey)]
if next then
-- OK
return nextkey
end
end
-- Failed
return 'woodensword'
end
-- Merchant item list
-- Creates a table with
function p.merchantitems(frame)
local title = func.nil_if_empty(frame.args['title']) or 'Shop sell prices'
local doGroups = func.nil_if_empty(frame.args['groups']) ~= nil
local groups = {}
local trueIndex = 1
if doGroups then
for i = 1,8 do
-- Grab group text and size
local text = func.nil_if_empty(frame.args["group" .. i])
local size = func.nil_if_empty(frame.args["group" .. i .. "size"])
if text ~= nil and size ~= nil then
groups[trueIndex] = { text, size }
trueIndex = trueIndex + 1
end
end
end
local cols = 2
local result = mw.html.create('table')
:addClass('SoG-table')
:css('max-width', '400px')
:attr('border', '1')
:attr('align', 'center')
result
:tag('tr')
:tag('th')
:css('text-align', 'center')
:attr('colspan', tostring(cols))
:wikitext(title)
:done()
:done()
if not doGroups then
local headers = result
:tag('tr')
:tag('th')
:wikitext('Item')
:done()
:tag('th')
:wikitext('Price')
:done()
end
local groupCounter = 1
local group = 1
for i = 1,32 do
-- Grab 2 elements
local item = func.nil_if_empty(resolveAlias(frame.args[i]))
if not item then break end
item = mw.text.trim(item)
-- Create group row if needed
if doGroups then
if group < trueIndex then
if groupCounter == 1 then
result
:tag('tr')
:tag('td')
:attr('colspan', cols)
:css('font-size', '1.25em')
:css('text-align', 'center')
:css('padding', '20px')
:tag('span')
:wikitext(groups[group][1])
result
:tag('tr')
:tag('th')
:wikitext('Item')
:done()
:tag('th')
:wikitext('Price')
:done()
end
groupCounter = groupCounter + 1
if groupCounter > tonumber(groups[group][2]) then
groupCounter = 1
group = group + 1
end
elseif groupCounter == 1 then
groupCounter = 0
result
:tag('tr')
:tag('td')
:attr('colspan', cols)
:css('font-size', '1.25em')
:css('text-align', 'center')
:css('padding', '20px')
:tag('span')
:wikitext('Other')
result
:tag('tr')
:tag('th')
:wikitext('Item')
:done()
:tag('th')
:wikitext('Price')
:done()
end
end
-- Create data row
local datarow = result
:tag('tr')
:tag('td')
:css('padding-left', '16px')
:css('width', '100%')
:wikitext(frame:expandTemplate{ title = 'ItemLink', args = { id = item } })
:done()
:tag('td')
:css('white-space', 'nowrap')
:css('padding-left', '10px')
:wikitext('[[File:Interface goldicon.png|16x17px]] ')
:wikitext(p.data({["args"] = {item, "storybuy", ["softErrors"] = true}}))
:done()
end
return result
end
return p