Module:Weapon
Jump to navigation
Jump to search
Tests
All tests passed.
Name | Expected | Actual | |
---|---|---|---|
test_renderObtain |
local p = {}
-- require('Module:Weapon/testcases').run()
local getArgs = require('Module:Arguments').getArgs
local str = require('Module:String')
local util = require('Module:Util')
local htmlparser = require('Module:HtmlParser')
function p.formatLink(link)
if string.find(link, '[[', 1, true) ~= nil then
return link
elseif string.find(link, '<a', 1, true) ~= nil then
return link
else
return '[[' .. link .. ']]'
end
end
function p.lineBreak(text)
local result = text
-- replace "%s/%s" of root level text nodes with "<br />"
local tmp = '<root>' .. text .. '</root>'
local root = htmlparser.parse_html(tmp)
local children = root[1]['childNodes']
for _,e in ipairs(children) do
if e['tagName'] == 'textNode' then
local value = e['value']
local fake_frame = { args = {
['source'] = value,
['pattern'] = '%s/%s',
['replace'] = '<br />',
['plain'] = 'False'
} }
local new_value = str.replace(fake_frame)
fake_frame = { args = {
['source'] = result,
['pattern'] = value,
['replace'] = new_value,
['plain'] = 'True'
} }
result = str.replace(fake_frame)
end
end
return result
end
function p._renderObtain(args)
local lang = mw.getContentLanguage()
local obtain = mw.text.trim(args['obtain'] or '')
local obtain_text = mw.text.trim(args['obtain_text'] or '')
local limit = mw.text.trim(args['limit'] or 999)
local release_date = mw.text.trim(args['release_date'] or '')
local format = mw.text.trim(args['format'] or '')
local categories = {}
local result = {}
if obtain == '' then
if ((format == 'div') and (obtain_text ~= '')) then
return '<div>' .. obtain_text .. '</div>'
else
return obtain_text
end
end
local obtains = mw.text.split(obtain, ';')
for _,line in ipairs(obtains) do
line = mw.text.trim(line)
local parts = mw.text.split(line, ',')
local maintype = parts[1]
if maintype == 'arcarum' then
table.insert(result, '[[File:Location Arcarum.png|56px|link=Arcarum]] [[Arcarum: The World Beyond]]')
elseif maintype == 'replicard' then
table.insert(result, '[[Replicard Sandbox]]')
elseif maintype == 'event' then
local type = parts[2] or ''
table.insert(categories, '[[Category:Event Weapons]]')
if type == 'rotb' then
table.insert(categories, '[[Category:Beast Weapons]]')
table.remove(parts, 2)
table.remove(parts, 1)
local link = table.concat(parts, ',')
if (string.len(link) > 0) then
table.insert(result, p.formatLink(link))
else
table.insert(result, '[[Rise of the Beasts]]')
end
elseif type == 'proving_grounds' then
local element = parts[3] or ''
element = lang:ucfirst(element)
table.insert(categories, '[[Category:Proving Grounds Weapons]]')
--table.insert(categories, '[[Category:'..element..' Proving Grounds Weapons]]')
--table.insert(result, '[[Proving Grounds|'..element..' Proving Grounds]]')
table.insert(result, '[[Proving Grounds]]')
elseif type == 'xeno' then
table.insert(result, p.formatLink(parts[3]))
elseif type == 'exo' then
table.insert(result, p.formatLink(parts[3]))
elseif type == 'showdown' then
table.insert(result, p.formatLink(parts[3]))
elseif type == 'story' then
table.insert(categories, '[[Category:Story Event Weapons]]')
table.insert(result, p.formatLink(parts[3]))
elseif type == 'collab' then
table.insert(categories, '[[Category:Collab Event Weapons]]')
table.insert(result, p.formatLink(parts[3]))
elseif type == 'side_story' then
table.insert(categories, '[[Category:Side Story Weapons]]')
table.insert(result, p.formatLink(parts[3]))
elseif type == 'unf' then
table.insert(categories, '[[Category:Unite and Fight Weapons]]')
if (string.len(link) > 0) then
table.insert(result, p.formatLink(link))
else
table.insert(result, '[[Unite and Fight]]')
end
end
elseif maintype == 'premium' then
local type = parts[2] or ''
if type == 'normal' then
table.insert(result, '[[Premium Draw]]')
table.insert(result, '[[Surprise Ticket]]')
elseif type == 'gala' then
local subtype = parts[3] or ''
if subtype == 'normal' then table.insert(result, '[[Premium Gala]]')
elseif subtype == 'flash' then table.insert(result, '[[Flash Gala]]')
end
elseif type == 'summer' then table.insert(result, '[[Summer Premium Draw]]')
elseif type == 'halloween' then table.insert(result, '[[Halloween Premium Draw]]')
elseif type == 'holiday' then table.insert(result, '[[Holiday Premium Draw]]')
elseif type == 'valentine' then table.insert(result, '[[Valentine Premium Draw]]')
elseif type == 'ticket' then table.insert(result, '[[Surprise Ticket]]')
elseif type == 'zodiac' then
local year = parts[3] or '????'
table.insert(result, '[[Premium Gala]] ('..year..' Zodiac Weapon)')
elseif type == 'special' then
local link = parts[3] or ''
if link ~= '' then table.insert(result, p.formatLink(link)) end
end
elseif maintype == 'classic' then
table.insert(result, '[[Classic Draw]]')
table.insert(result, '[[Surprise Ticket]]')
elseif maintype == 'classic2' then
table.insert(result, '[[Classic Draw II]]')
table.insert(result, '[[Surprise Ticket]]')
elseif maintype == 'special' then
table.remove(parts, 1)
local link = table.concat(parts, ',')
if (string.len(link) > 0) then
link = p.formatLink(link)
table.insert(result, '[[File:Location Treasure Quests.png|56px|link=Category:Special_Quest]] '..link)
end
elseif maintype == 'raid' then
local chapter = parts[2]
table.remove(parts, 2)
table.remove(parts, 1)
local link = table.concat(parts, ',')
if (string.len(link) > 0) then
link = p.formatLink(link)
if string.len(chapter) > 0 then link = '{{location|'..chapter..'|icon}}'..' '..link end
table.insert(result, link)
end
elseif maintype == 'shop' then
local type = parts[2] or ''
if type == 'pendants' then
-- pendants,[type],[cost]
local subtype = parts[3] or ''
local count = parts[4] or '??'
if (subtype == 'renown') or (subtype == 'prestige') then
subtype = lang:ucfirst(subtype)
table.insert(result, '{{itm|'..subtype..' Pendant,'..count..'|png}}')
end
elseif type == 'daily point' then
-- daily point,[cost]
local count = parts[3] or '??'
table.insert(result, '[[Daily Point Shop]] ('..count..' points)')
elseif type == 'weapon series' then
-- weapon series,[series]
local series = parts[3] or ''
if series == 'cosmic' then
link = '[[Shop#Cosmos_Weapons|Shop (Cosmos Weapons)]]'
end
table.insert(result, link)
elseif type == 'quest items' then
-- quest items,[category],[subcategory],[items]
local category = parts[3] or ''
local subcategory = parts[4] or ''
table.remove(parts, 4)
table.remove(parts, 3)
table.remove(parts, 2)
table.remove(parts, 1)
local items = table.concat(parts, ',')
local link = '[[Shop#Quest_Items|Treasure Trade]]'
if (subcategory == 'Primal Weapons') or (subcategory == 'Beast Weapons') or
(subcategory == 'Epic Weapons') or (subcategory == 'Cosmos Weapons') or
(subcategory == 'Beast Weapons') or (subcategory == 'Rose Weapons') or
(subcategory == 'Relics') or (subcategory == 'Hollowsky Weapons') or
(subcategory == 'Dark Opus Weapons') then
link = '[[Shop#'..subcategory..'|Treasure Trade ('..subcategory..')]]'
elseif subcategory == 'Upgraders' then
link = '[[Shop#Misc_Weapons|Treasure Trade (Upgraders)]]'
end
if string.len(items) > 0 then
link = '{{tt|1='..link..'|2=<div style="text-align:left;>Required treasure:<br />'..items..'</div>}}'
end
table.insert(result, link)
elseif type == 'trade moons' then
-- trade moons,[type],[cost]
local subtype = parts[3] or ''
local count = parts[4] or '??'
if (subtype == 'bronze') or (subtype == 'silver') or (subtype == 'gold') then
subtype = lang:ucfirst(subtype)
table.insert(result, '{{itm|'..subtype..' Moon,'..count..'}}')
end
elseif type == 'points' then
-- trade points,[type],[cost]
local subtype = parts[3] or ''
local count = parts[4] or '??'
table.insert(categories, '[[Category:Point Shop Weapons]]')
if (subtype == 'a') or (subtype == 'b') or (subtype == 'g') or (subtype == 'v') then
subtype = lang:ucfirst(subtype)
table.insert(categories, '[[Category:'..subtype..'-point Weapons]]')
table.insert(result, '[[Promotional_Codes#Point_Shop|'..count..' '..subtype..'-points]]')
end
end
end
end
for index,row in ipairs(result) do
if (row == '[[Surprise Ticket]]') and (string.len(release_date) > 0) then
local release_time = mw.text.split(release_date, '-')
release_time = os.time{year=release_time[1],month=release_time[2],day=release_time[3]}
local now_time = os.time(os.date("!*t"))
local diff = now_time - release_time
if diff < (140 * 24 * 60 * 60) then
result[index] = '{{tt|1='..row..' <span style="color:red;">(!)</span>|2=This is a recently released weapon and may not yet be available via [[Surprise Ticket]]s.}}'
end
end
end
categories = table.concat(categories, '')
if table.getn(result) > 0 then
if format == 'list' then
return '<li>'..table.concat(result, '</li><li>')..'</li>'..categories
elseif format == 'div' then
return '<div class="obtain-list-item">'..table.concat(result, '</div><div class="obtain-list-item">')..'</div>'..categories
else
return table.concat(result, '<br />')..categories
end
elseif string.len(obtain_text) > 0 then
if format == 'div' then
return '<div>' .. obtain_text .. '</div>'..categories
else
return obtain_text..categories
end
else
return obtain
end
end
function p.renderObtain(frame)
local args = getArgs(frame, {
trim = true,
frameOnly = true,
})
return frame:preprocess(p._renderObtain(args))
end
function p.renderOugi(frame)
local args = getArgs(frame)
local text = args['text'] or ''
return p.lineBreak(text)
end
function p.renderSkill(frame)
local args = getArgs(frame)
local text = args['text'] or ''
return p.lineBreak(text)
end
function p.renderList(frame)
mw.log('render start: ' .. os.clock())
local filter = {}
for ix,fil in pairs({'category','rarity','element','weapon','max_evo'}) do
if frame.args[fil] then
local text, matches = string.gsub(frame.args[fil], ',', '\|')
filter[fil] = text
end
end
local fields = {
'%PAGE%',
'id'
}
if frame.args.fields ~= nil then
for w in (frame.args.fields):gmatch('[^,]+') do
table.insert(fields, w)
end
end
mw.log('load data: ' .. os.clock())
local weapons = p.fetchWeapons(frame, filter, fields)
mw.log('expanding templates: ' .. os.clock())
local result = {}
local template = frame.args.template
for key,weapon in pairs(weapons) do
table.insert(result, frame:expandTemplate{title = template, args = weapon})
end
mw.log('done: ' .. os.clock())
return table.concat(result, '')
end
function p.fetchWeapons(frame, filter, fields)
local argList = fields
local params = {
category = 'Weapons',
notcategory = 'Templates',
notnamespace = 'Template|User',
include = '{Weapon}:' .. table.concat(argList, ':'),
mode = 'userformat',
secseparators = '====',
multisecseparators = '===='
}
if (filter ~= nil) then
local match = {}
for key,part in pairs(filter) do
if key == 'category' then
params['category'] = part
else
table.insert(match, key..'\\s*=\\s*'..part)
end
end
if #match > 0 then
params.includematch = '/^(?=.*\\b' .. table.concat(match, '\\b)(?=.*\\b') .. '\\b).*$/is'
end
end
mw.logObject(params)
local data = frame:callParserFunction('#dpl:', params)
argList[1] = 'link'
return p.indexDPLTable(frame, argList, data)
end
function p.indexDPLTable(frame, argList, data)
local result = {}
local ix = 0
local rows = util.string.split(data, '====')
for rowix,row in pairs(rows) do
local args = {}
local i = 0
local sargs = util.string.split(row, '\n|')
for argix,arg in pairs(sargs) do
i = i+1
if arg ~= '' then
local key = argList[i]
args[key] = arg
end
end
if args.link ~= nil then
ix = ix + 1
args.ix = ix
-- some housework
if (args.id ~= nil) then
-- rarity .. type .. seq
local id_type = string.sub(args.id, 4, 5)
if (id_type == '99') then
id_type = 'B'
else
id_type = string.sub(args.id, 5, 5)
end
args.short_id = string.sub(args.id, 3, 3) .. id_type .. string.sub(args.id, 6, 8)
else
args.short_id = nil
end
table.insert(result, args)
end
end
table.sort(result, function(a,b)
return a.link < b.link
end)
return result
end
function p.test()
mw.log(os.clock())
local frame = mw.getCurrentFrame()
mw.log(os.clock())
local items = p.fetchWeapons(frame, { rarity = 'ssr' }, { '%PAGE%','id','rarity','element','weapon'})
mw.log(os.clock())
local count = 0
for k,v in pairs(items) do
mw.logObject(v)
--mw.log(v.id .. ' ' .. v.short_id .. ' ' .. v.link)
count = count + 1
end
mw.log(os.clock())
return count
end
function p.testLineBreak()
return p.lineBreak([[
Massive Wind damage to a foe. / All allies
gain <span class="image_link"><div class="tooltip" style="border-bottom: 0;">
<a href="/Status_Effects#Wind_ATK_Boosted" title="Status Effects#Wind ATK Boosted">
<img alt="Status WindAtkUp.png" src="/images/thumb/4/4d/Status_WindAtkUp.png/25px-Status_WindAtkUp.png" width="25" height="25" srcset="/images/thumb/4/4d/Status_WindAtkUp.png/38px-Status_WindAtkUp.png 1.5x, /images/thumb/4/4d/Status_WindAtkUp.png/50px-Status_WindAtkUp.png 2x" /></a>
<a href="/Status_Effects#Wind_ATK_Boosted" title="Status Effects">25% Wind ATK Up</a>
<span class="tooltiptext" style="">Wind ATK is boosted<br /><hr />
<strong>Strength</strong>: 25%<hr /><strong>Duration</strong>: 3.5 turns<hr />
<a href="/Half_Turns" class="mw-redirect" title="Half Turns">Applied during the attack phase.</a><br />
On the next turn, it\'ll have 3 turns remaining.</span></div></span>.<br />
<span class="skill-upgrade-text">Additional effect at 4★:</span><br />
Gain <span class="image_link"><div class="tooltip" style="border-bottom: 0;">
<a href="/Status_Effects#Critical_Hit_Rate_Boosted" title="Status Effects#Critical Hit Rate Boosted">
<img alt="Status CriticalUp.png" src="/images/thumb/a/a2/Status_CriticalUp.png/25px-Status_CriticalUp.png" width="25" height="25" srcset="/images/thumb/a/a2/Status_CriticalUp.png/38px-Status_CriticalUp.png 1.5x, /images/thumb/a/a2/Status_CriticalUp.png/50px-Status_CriticalUp.png 2x" /></a>
<a href="/Status_Effects#Critical_Hit_Rate_Boosted" title="Status Effects">
??% / 30% Critical Hit Rate Up</a><span class="tooltiptext" style="">
DMG is slightly boosted for critical hits<br /><hr /><strong>Strength</strong>:
 ??% chance of dealing 30% more damage.<hr /><strong>Duration</strong>: 3.5 turns<hr />
<a href="/Half_Turns" class="mw-redirect" title="Half Turns">Applied during the attack phase.</a><br />
On the next turn, it\'ll have 3 turns remaining.</span></div></span>.
<sup id="cite_ref-Hecate_mk2_Orleans_1-1" class="reference">
<a href="#cite_note-Hecate_mk2_Orleans-1">[1]</a></sup>
]])
end
function p.testObtain()
mw.log(p._renderObtain({
['obtain'] = '',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = 'event,xeno,Xeno Vohu Manah Clash',
['obtain_text'] = '[[Xeno Vohu Manah Clash]]'
}))
mw.log(p._renderObtain({
['obtain'] = 'event,xeno,Xeno Vohu Manah Clash',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = '',
['obtain_text'] = '[[Xeno Vohu Manah Clash]]'
}))
mw.log(p._renderObtain({
['obtain'] = 'premium,zodiac,2015',
['obtain_text'] = '',
['limit'] = 1
}))
mw.log(p._renderObtain({
['obtain'] = 'premium,zodiac,2015;premium,valentine;premium,gala,normal;premium,gala,flash;premium,special,[[Premium Draw|Christmas Holiday Draw Set]]',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = '',
['obtain_text'] = '[[Premium Draw]]<br />[[Rise of the Beasts|Qinglong Showdown Extreme]]'
}))
mw.log(p._renderObtain({
['obtain'] = '[[Premium Draw]]<br />[[Rise of the Beasts|Qinglong Showdown Extreme]]',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = 'special,[[Angel Halo]]',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = 'event,side_story,[[By Any Other Name]]',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = 'shop,points,a,700',
['obtain_text'] = ''
}))
mw.log(p._renderObtain({
['obtain'] = 'event,proving_grounds,earth',
['obtain_text'] = ''
}))
end
return p