Module:Infobox/Mechanic

--Get Required Modules local loadLib = require('Module:LoadLib')

loadLib(_G, {	infobox = 'Infobox',	templates = 'String/Templates',	{'Minimap', values = {		'getMinimapForInfobox',	}},	animate = 'Animate',	infoboxdata = 'Infobox/Data',	sprite = 'Sprite', })

mw.html.create = require('Module:Html').create local curTitle = mw.title.getCurrentTitle local allstats, MAX_INDEX, MAX_TAB = infoboxdata.allstats --D1+, infoboxdata.MAX_INDEX, infoboxdata.MAX_TAB

--Begin Exports local p = {} local yesIcon, noIcon, unknownIcon = templates.yes(1), templates.no(1), templates.unknown(1)

local function yesnodefault(val, yes, no, def) if tostring(val):sub(1, 1):lower == 'u' then return unknownIcon end local bool = yesno(val); if bool == nil then return def or val elseif bool then return yes else return no	end end

local function yesnoIcon(val, def) return yesnodefault(val, yesIcon, noIcon, def) end

local function additergroup(pref, sdata, parent) for count = 1,MAX_INDEX,1 do		local desc, name = (pref..'%d_desc'):format(count), (pref..'%d_name'):format(count) parent:addData{ sdata[desc], label = sdata[name] } end end

local function argNormalize(tb) -- Simple replacement functions for the whole table local ret = {} for oldkey, v in pairs(tb) do		local key = oldkey:gsub('[{}]', '') ret[key] = v	end return ret end

function p.infoboxCreate(frame) local args = getArgs(frame) local deftype = args.default_type -- All checkings local isNPC, isQuest, isPuzzle, isStat, isMinion, isLocation do local function checkval(v) return (deftype or ''):lower:match(v) and true or false end isNPC = checkval('npc') or checkval('character') isQuest = checkval('quest') isPuzzle = checkval('puzzle') isStat = checkval('stat') isMinion = checkval('minion') isLocation = checkval('location') end local minimalist = (isQuest or isPuzzle) and true local pagename = curTitle.text or 'Diamond' local title = args.title or ((not minimalist) and pagename or nil) if isLocation then local status, spriteAndTitle = pcall(function return sprite._locationSprite(title) end) if status then title = spriteAndTitle end elseif isNPC then local status, spriteAndTitle = pcall(function return sprite._npcSprite(title) end) if status then title = spriteAndTitle end end local category_to_add = args.category_to_add or '' local sections = {} for j = 1,MAX_TAB,1 do		local function argJ(name, default) return args[name..j] or default end local sectionExists = j == 1 or argJ('tab') if sectionExists then -- section one does have numbers after params; on 2+ do that local i = j == 1 and  or j			local _i = j == 1 and  or '_'..j -- needed for when a param ends in a number naturally local function argI(name, default) return args[name..((type(name) == 'string' and name:match('%d$')) and _i or i)] or default end -- table of all params for this section local s = {} local function additerdata(pref) for count = 1,MAX_INDEX,1 do					local desc, name = (pref..'%d_desc'):format(count), (pref..'%d_name'):format(count) s[desc] = argI(desc) s[name] = argI(name) or ('%s %d'):format(string.ucfirst(pref), count) end end -- Top level infobox values --0			s.tab = argJ('tab') or argI('tab') -- purposefully use 'j' here since default section does actually use 'tab1' --1|2			s.caption = argI('caption') or argI('imagecaption') s.image_gallery = (argI('image') and argI('image'):match('UNIQ%-%-gallery')) and argI('image') or nil s.image = not s.image_gallery and (argI('image') or not (minimalist or isStat or isMinion)) and string.wrapTag(animate.animate({ argI('image') or pagename..'.png', class = 'pi-image-thumbnail' }), 'center') or nil if not s.image_gallery and not s.image and isMinion then s.image_gallery = string.dedent:format(pagename, pagename) end --3			s.slot_item = argI('slot_item') or argI('slot') s.slot_item = yesno(s.slot_item, (isMinion and true or false)) and (s.slot_item or (isMinion and pagename..' I' or pagename)) or nil s.slot_item = s.slot_item and string.wrapHtml((''):format( s.slot_item, argI('slot_text') and '|text='..argI('slot_text') or '', argI('slot_title') and '|title='..argI('slot_title') or '', argI('slot_link') and '|link='..argI('slot_link') or '' ), 'center') --4			s.aka = argI('aka') --5			s.type = argI('type') or ((not minimalist) and deftype or nil) --6			s.color = argI('color') --7			s.appearance = argI('appearance') --8			s.collection = argI('collection') and (''):format(argI('collection')) --9			s.usage = argI('usage') --10			s.uses = argI('uses') --11			s.ways_to_increase = argI('ways_to_increase') --12			s.category = argI('category') --13			s.collects = argI('collects') and (''):format(argI('collects')) --14			s.upgrade_with = argI('upgrade_with') and (''):format(argI('upgrade_with')) --15			s.travel_scroll = argI('travel_scroll') --16			s.level = argI('level') --17			s.sublocations = argI('sublocations') and (''):format(argI('sublocations')) --18			s.fairy_souls = argI('fairy_souls') -- Dungeon Information group --A0 do local d = argI('dungeon') s.dungeon = d and (					(d == 'c' or d == 'cat' or d == 'catacombs' or d == 'the_catacombs')					and 'The Catacombs'					or ' Invalid dungeon name '				) end --A1 s.floor = argI('floor') --A2 s.boss = argI('boss') --A3 s.status = argI('status') --A4 s.dungeon_size = argI('dungeon_size') --A5 s.party_size = argI('party_size') --A6 s.required_combat_level = argI('required_combat_level') --A7 s.required_catacombs_level = argI('required_catacombs_level') --A8 s.reqs = argI('reqs') --A9 s.base_xp = argI('base_xp') --A10 s.failable = yesnoIcon(argI('failable')) -- Mob Information group --B0 s.mob_level = argI('mob_level') --B1 s.damage_deals = argI('damage_deals') --B2 s.damage_resistance = argI('damage_resistance') --B3 s.spawn_location = argI('spawn_location') and (''):format(argI('spawn_location')) --B4 s.spawn_condition = argI('spawn_condition') --B5 s.special = argI('special') --B6 s.special_behavior = argI('special_behavior') --B7 local ee = argI('effective_enchant') s.effective_enchant = ee and (				(ee == 'none' or ee == 'no' or ee == 'n') and 'None'				or (''):format(ee)			) -- Quest group --C0 s.requirements = argI('requirements') or argI('requirement') --C1 s.rewards = argI('rewards') or argI('reward') -- Stats group --D0 s.stats = argI('stats') --D1+ table.each(table.values(allstats), function(v)				local ln = v[1]				s[ln] = argI(ln)			end) -- Perks group --E0+ additerdata('perk') -- Capacity group --F0 s.default_desc = argI('default_desc') s.default_name = argI('default_name') or 'Default' --F1+ additerdata('upgrade') -- Location group --G0 s.xyz = argI('x') and (' %s  %s  %s  '):format(argI('x'), argI('y') or , argI('z') or ) s.xyz = s.xyz and string.wrapHtml(s.xyz, 'table', { style = 'width:100%; table-layout:fixed; text-align:center;' }) --G1 s.coordinates = argI('coordinates') --G2 s.location = argI('location') and (''):format(argI('location')) --G3 s.start_location = argI('start_location') and (''):format(argI('start_location')) --G4 s.start_npc = argI('start_npc') and (''):format(argI('start_npc')) --G5 s.prev_location = argI('prev_location') or (argI('next_location') and 'None (lowest tier location)') --G6 s.next_location = argI('next_location') or (argI('prev_location') and 'None (top tier location)') -- Inhabitants group --H0 s.npcs = argI('npcs') and (''):format(argI('npcs')) --H1 s.mobs = argI('mobs') and (''):format(argI('mobs')) -- Resources group --I0 s.drops = argI('drops') and string.wrapHtml(				(''):format(argI('drops')),				'div', { style = 'text-align:left;' }			) --I1 s.resources = argI('resources') and string.wrapHtml(				(''):format(argI('resources')),				'div', { style = 'text-align:left;' }			) -- Drops group --R0 s.mob_drops = argI('mob_drops') and (''):format(argI('mob_drops')) --R1 s.xp = argI('xp') and (''):format(argI('xp')) --R2 s.coins = argI('coins') and (''):format(argI('coins')) --R3 s.essence = argI('essence') and (''):format(argI('essence')) -- Values group --J0 s.base_value = argI('base_value') --J1 s.max_value = argI('max_value') -- Properties group --K0 s.unlock_requirement = argI('unlock_requirement') --K1 s.max_level = argI('max_level') -- Special Effects group --L0 s.skill_special_effect = argI('skill_special_effect') -- Upgrades group --M0 s.super_compactor = isMinion and yesnoIcon(argI('super_compactor') or true) or nil --M1 s.compactor = isMinion and yesnoIcon(argI('compactor')) or nil --M2 s.auto_smelter = isMinion and yesnoIcon(argI('auto_smelter')) or nil -- Player Interactions group --N0 s.quests = argI('quests') --N1 s.shop = yesnoIcon(argI('shop')) -- Next Event local skydate_start, skydate_end = argI('skydate_start') or argI('skydate_begin'), argI('skydate_end') if skydate_start then --S0 s.datetime = string.wrapHtml('', 'span', {					class = 'skydate-timestamp',					['data-skydate'] = skydate_start,				}) --S1 skydate_end = skydate_end or skydate_start skydate_end = skydate_end .. (skydate_end:match(',') and '' or ', 23:59') s.countdown = string.wrapHtml('', 'span', {					class = 'skydate-countdown',					['data-skydate-start'] = skydate_start,					['data-skydate-end'] = skydate_end,				}) end -- Minimap (at Coordinates) if isNPC then --O0 s.minimap = getMinimapForInfobox{ argI('location'), x = argI('x'), z = argI('z') } end -- Ideal Layout --P0 s.ideal_layout = argI('ideal_layout') and string.wrapHtml(argI('ideal_layout'), 'center', {style = 'margin:0 auto; width:272px;'}) -- Item Metadata -- Q0 s.id = argI('item_id') or argI('id') if s.id then -- Always show ID in all caps s.id = string.wrapTag(s.id:upper, 'code') -- If array syntax, make a list s.id = s.id:gsub(' ', '') -- lazy trim for array; ids never naturally have spaces s.id = table.concat(mw.text.split(s.id, ','), ' ') end -- Push section data into array sections[#sections+1] = s		end end -- Make infobox local ibox = infobox.create ibox:addTitle{ title } local panel = ibox:addPanel for i, sectionData in ipairs(sections) do		local sdata = argNormalize(sectionData) local section = --0panel:addSection{ label = sdata.tab } --1|2		if sdata.image_gallery then section:addImage{ sdata.image_gallery, caption = { sdata.caption }, source = 'image'..(i == 1 and '' or i) } else section:addData{ sdata.image } end section --3 :addData{ sdata.slot_item } --4 :addData{ sdata.aka, label = 'Also known as' } --5 :addData{ sdata.type, label = 'Type' } --6 :addData{ sdata.color, label = 'Color' } --7 :addData{ sdata.appearance, label = 'Appearance' } --8 :addData{ sdata.collection, label = 'Collection' } --9 :addData{ sdata.usage, label = 'Usage' } --10 :addData{ sdata.uses, label = 'Uses' } --11 :addData{ sdata.ways_to_increase, label = 'Ways to Increase' } --12 :addData{ sdata.category, label = 'Category' } --13 :addData{ sdata.collects, label = string.makeTitle('Collects', 'Average items collected per action') } --14 :addData{ sdata.upgrade_with, label = 'Upgrade with' } --15 :addData{ sdata.travel_scroll, label = 'Travel Scroll' } --16 :addData{ sdata.level, label = 'Level' } --17 :addData{ sdata.sublocations, label = 'Sub-locations' } --18 :addData{ sdata.fairy_souls, label = (' Fairy Souls'):format(pagename) } :addGroup --A0 :addData{ sdata.dungeon, label = 'Dungeon' } --A1 :addData{ sdata.floor, label = 'Dungeon Floor' } --A2 :addData{ sdata.boss, label = 'Boss' } --A3 :addData{ sdata.status, label = 'Status' } --A4 :addData{ sdata.dungeon_size, label = 'Dungeon Size' } --A5 :addData{ sdata.party_size, label = 'Party Size' } --A6 :addData{ sdata.required_combat_level, label = 'Required Level' } --A7 :addData{ sdata.required_catacombs_level, label = 'Required Level' } --A8 :addData{ sdata.reqs, label = 'Requirements to enter' } --A9 :addData{ sdata.base_xp, label = 'Base XP' } --A10:addData{ sdata.failable, label = 'Failable' } :done :addGroup --B0 :addData{ sdata.mob_level, label = 'Mob Level' } --B1 :addData{ sdata.damage_deals, label = 'Damage Deals' } --B2 :addData{ sdata.damage_resistance, label = 'Damage Resistance' } --B3 :addData{ sdata.spawn_location, label = 'Spawn Location' } --B4 :addData{ sdata.spawn_condition, label = 'Spawn Condition' } --B5 :addData{ sdata.special, label = 'Special' } --B6 :addData{ sdata.special_behavior, label = 'Special Behavior' } --B7 :addData{ sdata.effective_enchant, label = string.makeTitle('Effective Enchant', 'The weapon enchant that is most effective for killing this mob') } :done :addGroup --C0 :addData{ sdata.requirements, label = 'Start Req.' } --C1 :addData{ sdata.rewards, label = 'Reward' } :done do local group_ group_ = section:addGroup{ header = 'Stats', name = 'infobox-stats-list' } --D0 group_:addData{ sdata.stats } table.each(table.values(allstats), function(v)				local ln = v[1]				--D1+group_:addData{ sdata[ln], label = makeStat(ln, nil, true) }			end) end do local group = section:addGroup{ header = 'Perks' } --E0+ additergroup('perk', sdata, group) end do local group = section:addGroup{ header = 'Perks' } --F0 if sdata.default_desc then group:addData{ sdata.default_desc, label = sdata.default_name } end --F1+ additergroup('upgrade', sdata, group) end section:addGroup{ header = (not minimalist) and 'Location' or '' } --G0 :addData{ sdata.xyz, label = string.wrapHtml(' Coordinates', 'span', { style = 'white-space:nowrap; vertical-align: middle;' })} --G1 :addData{ sdata.coordinates, label = ' Coordinates' } --G2 :addData{ sdata.location, label = 'Location' } --G3 :addData{ sdata.start_location, label = 'Start Location' } --G4 :addData{ sdata.start_npc, label = 'Start NPC' } :addGroup{ layout = 'horizontal' } --G5 :addData{ sdata.prev_location, label = '← Previous Location' } --G6 :addData{ sdata.next_location, label = 'Next Location →' } :done :done :addGroup{ header = 'Inhabitants' } --H0 :addData{ sdata.npcs, label = 'NPCs' } --H1 :addData{ sdata.mobs, label = 'Mobs' } :done :addGroup{ header = 'Resources' } :addGroup{ layout = 'horizontal', ['row-items'] = 2 } --I0 :addData{ sdata.drops, label = 'Mob Drops' } --I1 :addData{ sdata.resources, label = 'Resources' } :done :done section:addGroup{ header = 'Drops' } --R0 :addData{ sdata.mob_drops, label = 'Drops' } --R1 :addData{ sdata.xp, label = 'XP' } --R2 :addData{ sdata.coins, label = '' } --R3 :addData{ sdata.essence, label = 'Essence' } :done :addGroup{ header = 'Values' } --J0 :addData{ sdata.base_value, label = 'Base value' } --J1 :addData{ sdata.max_value, label = 'Max value' } :done :addGroup{ header = 'Properties' } --K0 :addData{ sdata.unlock_requirement, label = 'Unlock Requirements' } --K1 :addData{ sdata.max_level, label = 'Skill Max Level' } :done :addGroup{ header = 'Special Effects' } --L0 :addData{ sdata.skill_special_effect, label = 'Special Effect' } :done :addGroup{ header = 'Upgrades', layout = 'horizontal', ['row-items'] = 1 } --M0 :addData{ sdata.super_compactor, label = 'Super Compactor 3000' } :addGroup{ layout = 'horizontal', ['row-items'] = 2 } --M1 :addData{ sdata.compactor, label = 'Compactor' } --M2 :addData{ sdata.auto_smelter, label = 'Auto Smelter' } :done :done :addGroup{ header = 'Player interactions' } --N0 :addData { sdata.quests, label = 'Quests' } --N1 :addData { sdata.shop, label = 'Shop' } :done :addGroup{ header = 'Next Event', collapse = 'open' } --S0 :addData{ sdata.datetime, label = 'Date & Time' } --S1 :addData{ sdata.countdown, label = 'Happening In' } :done :addGroup{ header = 'Minimap (at Coordinates)', collapse = 'open' } --O0 :addData { sdata.minimap } :done :addGroup{ header = 'Ideal Layout', collapse = 'closed' } --P0 :addData{ sdata.ideal_layout } :done :addGroup{ header = 'Metadata', ['row-items'] = 1, collapse = 'closed' } --Q0 :addData{ sdata.id, label = 'ID' } :done end return table.concat{ (frame.getParent and frame:getParent or mw.getCurrentFrame):preprocess(ibox:tostring), curTitle.namespace == 0 and category_to_add or '', } end

function p.test p.infoboxCreate{ } end

--Finish Module/Exports return p