Module:Autoability

-- -- Imports -- local getArgs = require("Module:Arguments").getArgs local yesno = require("Module:Yesno") local quote = require("Module:Quote")._quote local cargo = require("Module:Cargo")

local p = {} local lang = mw.language.new('en') -- - -- Strings -- - local i18n = { CELR = "Cumulative effect limit reached.", inf = "&#8734;", icons = { red = "File:Icon Auto-Abilities Red.png", blue = "File:Icon Auto-Abilities Blue.png", green = "File:Icon Auto-Abilities Green.png", yellow = "File:Icon Auto-Abilities Yellow.png", },   -- Called "Category" ingame. Refer to skill card filter in deck editor. categories = { red = "Multi-Skill", blue = "Auto-Skill", green = "Enhance/Resist", yellow = "Attributes", },   errors = { minimum_not_numeric = "Provided minimum value is not a number (%s)", minimum_not_unique = "Provided minimum value is not unique (%s)", } }

local styles = { clear = { ["clear"] = "both", ["height"] = "5px", },   infobox = { ["float"] = "right", ["position"] = "relative", ["width"] = "250px", ["background"] = "#FFF", ["font-size"] = ".923em", ["border"] = "1px solid #AAA", ["margin"] = "0 0 1em 1em", ["padding"] = "0", },   heading = { ["font-weight"] = "700", ["text-align"] = "center", ["border"] = "1px solid rgba(0,0,0,0.25)", ["border-bottom-width"] = "0", ["position"] = "relative", ["z-index"] = "1", ["margin"] = "-1px -1px 5px!important", ["font-size"] = "1.417em!important", ["color"] = "#fff!important", ["background-color"] = "#444", ["text-shadow"] = "rgba(0,0,0,0.75) 0 0 .25em", ["line-height"] = "1.176em", ["font-size-adjust"] = ".43", ["padding"] = ".5em!important", },   wrapper = { ["clear"] = "both", ["padding"] = "0", },   dt = { ["float"] = "left", ["text-align"] = "right", ["width"] = "78px", ["line-height"] = "1em", ["font-weight"] = "700", ["clear"] = "left", ["border-right"] = "2px solid #999", ["margin"] = "0 -2px 0 0", ["padding"] = "2px 8px 2px 3px", ["line-height"] = "1.667em", },   dd = { ["float"] = "left", ["width"] = "125px", ["font-weight"] = "400", ["border-left"] = "2px solid #999", ["margin"] = "0", ["padding"] = "2px 7px", ["line-height"] = "1.667em", }, }

function p.parse_min_infos(info, minimum, maximum) local infos = info or "" if infos == "" then infos = {} elseif type(infos) == "string" then infos = mw.text.split(infos, "%s*;%s*") end for i=#infos,1,-1 do       if infos[i] ~= "" then break end infos[i] = nil end local mins = minimum or "" if mins == "" then mins = {} elseif type(mins) == "string" then mins = mw.text.split(mins, "%s*;%s*") end for i=#mins,1,-1 do       if mins[i] ~= "" then break end mins[i] = nil end

if #mins == 0 and #infos == 0 then return {} elseif #mins == #infos then local keys = {} local items = {} for i,min in ipairs(mins) do           local key = tonumber(min) if not key then error(string.format(i18n.errors.minimum_not_numeric, min)) end if key <= maximum then keys[#keys+1] = key -- Ensure that all keys are unique. if items[key] then error(string.format(i18n.errors.minimum_not_unique, min)) end items[key] = infos[i] end end table.sort(keys) local min_infos = {} for i=1,#keys do           local from = keys[i] local to = keys[i+1] if to then to = to - 1 else to = maximum end local v = mw.text.trim(items[from]) if v:sub(-#i18n.CELR) == i18n.CELR then -- v:endswith(i18n.CELR) v = mw.text.trim(v:sub(1, -#i18n.CELR - 1)) end if from == maximum then v = v.." "..i18n.CELR end min_infos[i] = {info=mw.text.trim(v), from=from, to=to} end return min_infos elseif #mins == 0 then -- Minimum is empty, assume that infos is sorted. -- "", "A;B;C" = [A,B,C]. -- "", "A;C;B" = [A,C,B]. local min_infos = {} for i,v in ipairs(infos) do           min_infos[#min_infos+1] = {info=v} end return min_infos elseif #infos == 0 then -- No description provided. What to do? return {} elseif #mins < #infos then -- There are not enough minimums provided. What to do? return {} elseif #infos < #mins then -- There are not enough descriptions provided. What to do? return {} end end

-- Implements function p.infobox(frame) local args = getArgs(frame) local name = args.name or mw.title.getCurrentTitle.fullText local id = (args.id or name):lower:gsub("%W+", "_") local color = args.color or "" local icon = i18n.icons[color:lower] local category = i18n.categories[color:lower] local category_icon = icon and ("link=|16px "..category) local is_rewards_based = yesno(args.rewards_based, false) local value_type = (args.value_type or ""):lower local is_value_hidden = yesno(args.hide_value, false) local info = args.info or args.description or "" local minimum = args.minimum or "" local maximum = tonumber(args.maximum) or math.huge local min_infos = p.parse_min_infos(info, minimum, maximum) -- Build view local content = mw.html.create("div") content :addClass("infobox auto-ability"):addClass(color) :css(styles.infobox) :tag("p") :addClass("heading") :css(styles.heading) :wikitext(name) :done :tag("div") :addClass("wrapper") :css(styles.wrapper) :tag("dl") :tag("dt") :css(styles.dt) :wikitext("Value type") :done :tag("dd") :css(styles.dd) :wikitext(lang:ucfirst(value_type)) :done :tag("dt") :css(styles.dt) :wikitext("Hidden value") :done :tag("dd") :css(styles.dd) :wikitext(is_value_hidden and "Yes" or "No") :done :tag("dt") :css(styles.dt) :wikitext("Category") :done :tag("dd") :css(styles.dd) :wikitext(category_icon) :done :tag("dt") :css(styles.dt) :wikitext("Main only") :done :tag("dd") :css(styles.dd) :wikitext(is_rewards_based and "Yes" or "No") :done :tag("dt") :css(styles.dt) :wikitext("Maximum") :done :tag("dd") :css(styles.dd) :wikitext(maximum == math.huge and i18n.inf or maximum) :done :done :tag("div") :addClass("clear") :css(styles.clear) :done :done local quotation = mw.html.create("") for _,row in ipairs(min_infos) do       local from = row.from local to = row.to       if to and from == to then to = nil end if to and to == math.huge then to = "&#8734;" end local interval = table.concat({from, to}, "~") if interval ~= "" then interval = mw.html.create("small") :wikitext("["..interval.."]: ") :done else interval = nil end local info = row.info quotation :tag("p") :node(interval) :wikitext(info) :done:newline end local description_box = quote{ text = tostring(quotation), source = "In-game description", }   mw.logObject(quotation) local infobox = mw.html.create("") :node(content) :node(description_box) local out = tostring(infobox)

--    -- Category handling --    local cats = {} if category then cats[#cats+1] = lang:ucfirst(category:lower) .. " auto-abilities" end if is_rewards_based then cats[#cats+1] = "Rewards-based auto-abilities" end if maximum and maximum < math.huge then cats[#cats+1] = "Auto-abilities with cumulative effect limits" end for i, cat in ipairs(cats) do       cats[i] = string.format("", cat) end out = out..table.concat(cats) --    -- Store cargo data --    --cargo.store("autoabilities", {        id = id,        name = name,        color = color,        icon = icon,        category = category,        is_rewards_based = is_rewards_based and 1 or 0,        value_type = value_type,        is_value_hidden = is_value_hidden and 1 or 0,        maximum = maximum,    }) for _,row in ipairs(min_infos) do       local from = row.from local to = row.to or maximum to = math.min(to + 1, maximum) local info = row.info --cargo.attach("autoabilities_min_infos", {           from = from,            to = to,            info = info,        }) mw.log(from, to, info) end --mw.log(out) return out end

function p.test p.infobox{ name = "Crystal Seeker", description = Ever so slightly raises the chance to obtain crystals as drops.;       Slightly raises the chance to obtain crystals as drops.;        Raises the chance to obtain crystals as drops.;, minimum = 5; 15; 40, value_type = "number", hide_value = "n", color = "blue", }   p.infobox{ name = "Crystal Seeker", description = Ever so slightly raises the chance to obtain crystals as drops.;       Slightly raises the chance to obtain crystals as drops.;        Raises the chance to obtain crystals as drops.;, minimum = 5; 15; 40, maximum = 100, value_type = "number", hide_value = "n", color = "blue", }   p.infobox{ name = "Job Change Recast", description =        Job Change recast: 4 turns. ;        Job Change recast: 3 turns. ;        Job Change recast: 2 turns. Cumulative effect limit reached. ;, minimum = 0; 1; 2, --maximum = "2", value_type = "number", hide_value = "y", color = "blue", }   p.infobox{ name = "Job Change Recast", description =        Job Change recast: 4 turns. ;        Job Change recast: 3 turns. ;        Job Change recast: 2 turns. ;, minimum = 0; 1; 2, maximum = "2", value_type = "number", hide_value = "y", color = "blue", } end

return p