Module:Sandbox/MonkeysHK

local getArgs = require('Module:Arguments').getArgs local mergeArgsSyntax = require('Module:Arguments').mergeArgsSyntax local loader = require('Module:Loader')

local string, table, yesno, uiText = loader.require('String', 'Table', 'Yesno', 'UIText') local collectionData, armorSets, tooltips = loader.loadData('Collection/Data', 'Armor/Sets', 'Inventory slot/Aliases')

local p = {}

local recipeAliases = { ['r'] = 'recipe', ['recipe'] = 'recipe', ['recipes'] = 'recipes', ['rs'] = 'recipes', ['rec'] = 'recipe', ['recs'] = 'recipes', ['recip'] = 'recipe', ['recips'] = 'recipes', ['res'] = 'recipes', ['re'] = 'recipe', ['up'] = 'upgrade', ['upg'] = 'upgrade', ['u'] = 'upgrade', ['upgr'] = 'upgrade', ['upgra'] = 'upgrade', ['upgrad'] = 'upgrade', ['upgrade'] = 'upgrade', }

-- first row positions for Collection UI local firstRowPositions = { --1 { {3, 5} },	--2 { {3, 4}, {3, 6} },	--3 { {3, 4}, {3, 5}, {3, 6} },	--4 { {3, 3}, {3, 4}, {3, 6}, {3, 7} },	--5 { {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7} },	--6 { {3, 2}, {3, 3}, {3, 4}, {3, 6}, {3, 7}, {3, 8} },	--7 { {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8} },	--8 { {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 6}, {3, 7}, {3, 8}, {3, 9} }, }

-- X/Y positions for Collection Rewards UI local rewardUIPositions = { -- 1 { {3, 5} },	-- 2 { {3, 4}, {3, 6} },	-- 3 { {3, 3}, {3, 5}, {3, 7} },	-- 4 { {3, 2}, {3, 4}, {3, 6}, {3, 8} },	-- 5 { {2, 2}, {2, 4}, {2, 6}, {2, 8}, {4, 5}, },	-- 6 { {2, 2}, {2, 4}, {2, 6}, {2, 8}, {5, 4}, {5, 6}, },	-- 7 { {2, 2}, {2, 4}, {2, 6}, {2, 8}, {3, 3}, {3, 5}, {3, 7}, },	-- 8 { {2, 2}, {2, 4}, {2, 6}, {2, 8}, {4, 2}, {4, 4}, {4, 6}, {4, 8}, },	-- 9 { {2, 4}, {2, 5}, {2, 6}, {3, 4}, {3, 5}, {3, 6}, {4, 4}, {4, 5}, {4, 6}, },	--10 { {2, 4}, {2, 5}, {2, 6}, {2, 7}, {3, 4}, {3, 5}, {3, 6}, {4, 4}, {4, 5}, {4, 6}, },	--11 { {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {3, 4}, {3, 5}, {3, 6}, {4, 4}, {4, 5}, {4, 6}, }, }

-- maximum of three rows of rewards (or 27 rewards) will be processed local numToEng = { 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty', 'twenty-one', 'twenty-two', 'twenty-three', 'twenty-four', 'twenty-five', 'twenty-six', 'twenty-seven' }

local function wrapdiv(s) return (' %s '):format(s) end local function frm(...) return table.concat(table.map({...}, function(s) return string.gsub(s, ' ', '-') end), '-') end local function makeUI(params) local res = '' return res end local function typeformatter(item, _type, ttcol) local str if _type:match('[Ee]xperience') then str = ('&8+&3%s %s'):format(item, _type) elseif _type:match('[Uu]pgrade') then str = ('&a%s Upgrade'):format(item) elseif _type:match('[Cc]oming [Ss]oon') then str = ('&%s%s &8(&4COMING SOON&8)'):format(ttcol, item) elseif _type:match('[Dd]warven [Ff]orge [Rr]ecipe') then str = ('&%s%s &6Dwarven Forge Recipe'):format(ttcol, item) elseif _type:match('[Nn]one') then str = ('&%s%s'):format(ttcol, item) else str = ('&%s%s &7%s'):format(ttcol, item, _type) end return str end local function getRarityCol(item) -- For getting special case rarity colors local function specialCaseColors(item) if item:match('[Mm]inion') then return '9' end -- if item:match('Enchanted Book') then return '9' end if item:match('[Cc]oming [Ss]oon') then return 'c' end if tonumber(item) then return '3' end end local tooltip = tooltips[item] local tooltipRarity = tooltip and tooltip.title and tooltip.title:match('^&([a-z0-9])') or nil return tooltipRarity or specialCaseColors(item) or 'f' end local function getRewardStr(rewards, req) local rewardStr = ('&7Reward%s:/%s'):format(		#rewards > 1 and 's' or '',		table.concat(table.map(rewards, function(v)			v = type(v) == 'table' and v or {v}			return ('&#160;&#160;%s'):format( v.tooltip or typeformatter(v[1], v.type or 'recipe', v.ttcolor or getRarityCol(v[1])) )		end), '/')	) return ('&f%s &e0&6\\/&e%s&7//%s'):format(		('-'):rep(20),		string._formatShortNum(string._toNumber(req)),		rewardStr	) end

- -- Template: Collection UI -- -- Creates a main collection UI for a given item - function p.collectionUI(frame) local args = getArgs(frame) local res = wrapdiv(p._collectionUI(args)) return mw.getCurrentFrame:preprocess(res) end - -- function: _collectionUI(args: table|frame) -- -- Invoked by. - local function explode(collData) for _, rewardTb in ipairs(collData) do		local tb = {} for _, reward in ipairs(rewardTb.reward) do			-- checks all conditions when reward name needs explosion if armorSets[reward[1]] then for _, w in ipairs(armorSets[reward[1]]) do					local t = table.deepCopy(reward) t[1] = w					table.push(tb, t)				end elseif reward.explode then for _, v in ipairs(reward.explode) do					local t = table.deepCopy(reward) if type(v) == 'table' then for _, w in ipairs(table.merge(table.namedKeys(v), {1})) do							t[w] = (v[w] ~= '__NIL__' and v[w] or nil) end else t[1] = v					end table.push(tb, t)				end else table.push(tb, reward) end end rewardTb.reward = tb	end end local function parseCollectionData(collData, collection, id, args) mw.logObject(collData) local tb = { collection and collection .. ' Collection' or title.rootText, ['1, 5'] = ('%s, none; none, &e%s Collection, &7View all your %s Collection/&7progress and rewards!//&7Total Collected: &e0'):format(			args.title or collection,			collection,			collection		), id = id, return_text = args['return_text'] or args['goback'], return_link = args['return_link'], return_id = args['return_id'], hide = args['hide'], dnl = true, }	local rows, total = 1, #collData local frp = firstRowPositions[total] local function calcXY(i) local x, y		if frp then local pos = frp[i] x, y = pos[1], pos[2] else x = 2 + rows y = i % 9 y = y == 0 and 9 or y		end return x, y	end for i, rewardTb in ipairs(collData) do		if i > 27 then break end -- Processes upwards of 3 rows of rewards -- calculate X, Y		local x, y = calcXY(i) -- advance row if i % 9 == 0 and i > 0 then rows = rows + 1 end local title = ('&%s%s %s'):format(i == 1 and 'e' or 'c', collection, string._toRoman(i)) local text = ('/&7Progress: &e0&6%%/%s//&eClick to view rewards!'):format(			getRewardStr(rewardTb.reward, rewardTb.required)		) tb[('%s, %s'):format(x, y)] = ('%s Stained Glass Pane; %s, %s; none, %s, %s'):format(			i == 1 and 'Yellow' or 'Red', i,			rewardTb._goto or frm(collection, numToEng[i]),			title, text		) end return tb end local function parseChildren(collData, collection, parentId) local uis = {} for i, rewardTb in ipairs(collData) do		-- create UIs local _type = rewardTb.reward[1].type local settings = { collection, i,			id = ('%s'):format(frm(collection, numToEng[i])), return_text = ('&7To %s Collection'):format(collection), return_id = parentId, hide = true, }		if _type:match('[Rr]ecipe') or _type:match('[Cc]oming [Ss]oon') then table.push(uis, p._collectionRewardsUI(settings)) end end return uis end local function parseTextList(s) local rewards = {} local count = 0 local function g(s) return s and s:gsub('\255', ',') or nil end for i, v in ipairs(string.split((s:gsub('\\,', '\255')), '\n')) do		local _type v = string.methods(v):_trim if v:getValue ~= '' then if v:charAt(1) == '*' then _type = v:charAt(2) == '*' and 'item' or 'amount' end if _type == 'amount' then -- * amount[, goto] local amount, _goto = unpack(string.split(v:sub(2), "%s*,%s*")) count = count + 1 rewards[count] = { required = g(amount), _goto = g(_goto and _goto:gsub('^goto%-', '') or nil), reward = {}, }			elseif _type == 'item' then -- ** reward[, type][, rarity] local item, type, rarity = unpack(string.split(v:sub(3), '%s*,%s*')) item = g(item or v:sub(3)) table.push(rewards[count].reward, {					item,					ttcolor = g((rarity and rarity ~= '') and uiText.getFormatting(rarity) or nil),					type = g((type and type ~= "") and string.ucfirst(recipeAliases[type:lower] or type)),				}) end end end return rewards end function p._collectionUI(args) checkType(1, args, { 'table' }) assertTrue(args[1], 'No collection specified', 2) local collection = args[1] and args[1]:gsub('[Ee][Nn][Cc][Hh][Aa]?[Nn]?[Tt]?[Ee]?[Dd]? ?', ):gsub('[Bb][Ll][Oo][Cc][Kk] ?[Oo]?[Ff]? ?', ) local dt = table.deepCopy(collectionData[collection], true) local list = args[2] and parseTextList(args[2]) or {} for i = 1, #list do		-- process/override args if list[i] then dt[i] = dt[i] or {} dt[i].reward = dt[i].reward or {} dt[i].required = list[i].required or dt[i].required dt[i]._goto = list[i]._goto or dt[i]._goto local dtreward, listreward = dt[i].reward, list[i].reward or {} for j = 1, #listreward do				dtreward[j] = dtreward[j] or {} dtreward[j][1] = listreward[j][1] or dtreward[j][1] dtreward[j].ttcolor = listreward[j].ttcolor or dtreward[j].ttcolor dtreward[j].type = listreward[j].type or dtreward[j].type end end end local title = mw.title.getCurrentTitle explode(dt) local id = args['id'] or frm(collection, 'default') local parent = parseCollectionData(dt, collection, id, args) local children = parseChildren(dt, collection, id) -- pipeline(ui, table.dump, 0, error) return table.concat(table.merge({ makeUI(parent) }, children)) end

- -- Template: Collection Rewards UI -- -- Creates a collection Rewards UI. - function p.collectionRewardsUI(frame) local args = getArgs(frame) return mw.getCurrentFrame:preprocess(p._collectionRewardsUI(args)) end - -- function: _collectionRewardsUI(args) -- -- Invoked by - local function addItem(tb, x, y, item, id, itemTitle, itemText) tb[('%s, %s'):format(x, y)] = ('%s, %s; %s, %s, %s'):format(		item,		id or 'none',		id and 'none' or ,		itemTitle or 'none',		itemText and itemText .. (item == 'Coming Soon' and  or '//&eClick to view recipe!') or 'none'	) end function p._collectionRewardsUI(args) checkType(1, args, { 'table' }) local coll, tier, required, items = args[1], args[2], args[3], args[4] coll = coll and coll:gsub('[Ee][Nn][Cc][Hh][Aa]?[Nn]?[Tt]?[Ee]?[Dd]? ?', ):gsub('[Bb][Ll][Oo][Cc][Kk] ?[Oo]?[Ff]? ?', ) if not items then items = required required = nil end items = type(items) == 'string' and mergeArgsSyntax(items) or items or {} local dt = table.deepCopy(collectionData[coll] and collectionData[coll][tier] or {}, true) local collFullname = ('%s %s'):format(coll, string._toRoman(tier or 1)) dt.required = required or dt.required for i = 1, math.max(#dt, #items) do		-- process/override args if items[i] then local item, id, title, text = pipeline(items[i], string.trim, 2, string.sub, '%s*,%s*', string.unpackedSplit) dt.reward = dt.reward or {} dt.reward[1] = item or dt.reward[1] dt.reward.id = id or dt.reward.id			dt.reward.title = title or dt.reward.title dt.reward.text = text or dt.reward.text end end local tb = { ('%s Rewards'):format(collFullname), ['1, 5'] = ('%s, none, &%s%s, &7View your %s/&7Collection rewards!//%s'):format(			coll, tier > 1 and 'c' or 'e', collFullname,			collFullname, getRewardStr(dt.reward, dt.required or 'unknown')		), id = args['id'], return_text = args['return_text'] or args['goback'], return_link = args['return_link'], return_id = args['return_id'], hide = args['hide'], dnl = true, }	local amount = #dt local pos = rewardUIPositions[amount] for i, reward in ipairs(dt) do		local tooltip = coll.type:match('[Cc]oming [Ss]oon') and tooltips['Coming Soon'] or tooltips[reward[1]] if not tooltip then error('No tooltip for: ' .. reward[1]) end local itemTitle = reward.title or (tooltip and tooltip.title) local itemText = reward.desc or (tooltip and tooltip.text) local id = reward.id or frm(coll, numToEng[i], 'recipe') addItem(tb, unpack(pos[i]), reward[1], id, itemTitle, itemText) end return makeUI(tb) end

return p