|
|
(167 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
| local p = {}; | | local p = require("Module:Move") |
| local cargo = mw.ext.cargo
| | p.game = require("Module:Game").Tekken7 |
| local tables = 'MoveDataCargoTest'
| |
| | |
| p.fields = 'id,name,input,target,damage,reach,tracksLeft,tracksRight,startup,recv,tot,crush,block,hit,ch,notes'
| |
| | |
| -- Get move id for querying, which is the 1st unnamed param of a template.
| |
| -- Moves are queried like this: {{TempateName|<moveId>}}
| |
| function getQueryId(frame)
| |
| local id = assert(frame:getParent().args[1], '1st unnamed param must be move id')
| |
| return mw.text.trim(id) -- whitespace is stripped only from named params
| |
| end
| |
| | |
| function moveNotFoundMsg(id)
| |
| return "move with id = '" .. id .. "' not found"
| |
| end
| |
| | |
| p.display = function(frame)
| |
| local function appendFrom(dst, src)
| |
| for k, v in pairs(src) do
| |
| dst[k] = v
| |
| end
| |
| end
| |
| local function getLeads(parentId)
| |
| local leads = {}
| |
| while (parentId ~= nil and parentId ~= '') do
| |
| local parent = cargo.query(tables, 'input,target,damage,parent', { where = "id='" .. parentId .. "'" })[1]
| |
| assert(parent, 'parent = "' .. parentId .. '" not found')
| |
| | |
| parentId = parent['parent']
| |
| parent['parent'] = nil
| |
|
| |
| for k, v in pairs(parent) do
| |
| local leadName = k .. 'Lead'
| |
| if leads[leadName] == nil then
| |
| leads[leadName] = ''
| |
| end
| |
|
| |
| leads[leadName] = v .. leads[leadName]
| |
| end
| |
| end
| |
|
| |
| return leads
| |
| end
| |
|
| |
| local leads = getLeads(frame:getParent().args['parent'])
| |
| if next(leads) == nil then
| |
| return frame:expandTemplate{ title = 'MoveData', args = frame:getParent().args }
| |
| end
| |
|
| |
| local args = {}
| |
| appendFrom(args, frame:getParent().args)
| |
| appendFrom(args, leads)
| |
| return frame:expandTemplate{ title = 'MoveData', args = args }
| |
| end
| |
| | |
| p.query = function(frame)
| |
| local id = getQueryId(frame)
| |
| local result = cargo.query(tables, p.fields, { where = "id = '" .. id .. "'" })[1]
| |
| assert(result, moveNotFoundMsg)
| |
|
| |
| for k, v in pairs(result) do
| |
| local override = frame:getParent().args[k]
| |
| if override ~= nil then
| |
| result[k] = override
| |
| end
| |
| end
| |
|
| |
| return frame:expandTemplate{ title = 'MoveDataCargoTest/Display', args = result }
| |
| end
| |
| | |
| p.punisher = function(frame) | |
| local id = getQueryId(frame)
| |
| local frames = frame:getParent().args['frames']
| |
| local rowspan = frame:getParent().args['rowspan']
| |
| local combo = frame:getParent().args['combo']
| |
| local type = frame:getParent().args['type']
| |
|
| |
| local input = ''
| |
| local damage = 0
| |
| local hit = nil
| |
| while (id ~= '') do
| |
| local move = cargo.query(tables, 'parent,input,damage,hit', { where = "id = '" .. id .. "'" })[1]
| |
| assert(move, moveNotFoundMsg(id))
| |
|
| |
| input = move['input'] .. input
| |
| damage = damage + move['damage']
| |
| if hit == nil then
| |
| hit = move['hit']
| |
| end
| |
|
| |
| id = move['parent']
| |
| end
| |
|
| |
| frame:callParserFunction{ name = '#cargo_store', args = {
| |
| '_table=Punisher',
| |
| type = type,
| |
| frames = frames,
| |
| damage = combo or damage
| |
| } }
| |
|
| |
| local row = mw.html.create('tr')
| |
| if rowspan ~= 'skip' then
| |
| row:tag('td'):wikitext(frames):attr('rowspan', rowspan or 1)
| |
| end
| |
| row:tag('td'):wikitext(input)
| |
| if combo ~= nil then
| |
| row:tag('td'):wikitext(damage .. ' (' .. combo .. ')')
| |
| else
| |
| row:tag('td'):wikitext(damage)
| |
| end
| |
| row:tag('td'):wikitext(hit)
| |
| return row
| |
| end
| |
| | |
| p.punishment = function(frame)
| |
| local character = frame:getParent().args[1]
| |
|
| |
| local data = mw.loadData('Module:Fighter/punishment')
| |
|
| |
| local punishers = cargo.query('Punisher', 'type,frames,damage', {
| |
| where = "Punisher._pageName='User:Lume/Cargo testing/" .. character .. " punishers'"
| |
| .. " AND (type = 'Standing' OR type = 'Crouching')"
| |
| })
| |
|
| |
| local span = 80
| |
| for _, p in pairs(punishers) do
| |
| local damages = mw.text.split(p['damage'], ', ', true)
| |
| for _, d in pairs(damages) do
| |
| if d > span then
| |
| span = d
| |
| end
| |
| end
| |
| end
| |
| if span % 5 ~= 0 then
| |
| span = span + 5 - (span % 5)
| |
| end
| |
|
| |
| local scale = mw.html.create('div'):addClass('punishment-scale')
| |
| for i = 0,span,5 do
| |
| local pip = mw.html.create('div'):addClass('punishment-scalepip')
| |
| :css("width", string.format("%.2f%%", 100 * i / span))
| |
| :node(mw.html.create('div'):addClass('punishment-piplabel'):wikitext(i))
| |
| if i % 50 == 0 then
| |
| pip:addClass('major')
| |
| elseif i % 25 == 0 then
| |
| pip:addClass('minor')
| |
| end
| |
| scale:node(pip)
| |
| end
| |
|
| |
| --[[
| |
| block = {
| |
| Standing = {
| |
| { frames, damages = {
| |
| { type, value }
| |
| ...
| |
| } }
| |
| ...
| |
| }
| |
| Crouching = {
| |
| { frames, damages = {
| |
| { type, value }
| |
| ...
| |
| } }
| |
| ...
| |
| }
| |
| }
| |
| --]]
| |
| local block = {}
| |
| for _, p in pairs(punishers) do
| |
| local type = p['type']
| |
| local frames = -tonumber(p['frames'])
| |
| local damageStrings = mw.text.split(p['damage'], ', ', true)
| |
|
| |
| --[[
| |
| damages = {
| |
| { type('' | rage | wall), value }
| |
| ...
| |
| }
| |
| --]]
| |
| local damages = {}
| |
| for _, dmgStr in pairs(damageStrings) do
| |
| local dmgSplit = mw.text.split(dmgStr, ' ', true)
| |
|
| |
| local value = tonumber(dmgSplit[1])
| |
| local dmgType = ''
| |
| if #dmgSplit == 2 then
| |
| dmgType = dmgSplit[2]
| |
| end
| |
|
| |
| table.insert(damages, { type = dmgType, value = value })
| |
| end
| |
|
| |
| if block[type] == nil then
| |
| block[type] = {}
| |
| end
| |
|
| |
| local sameFramePunisherFound = false
| |
| for _, punisher in block[type] do
| |
| if punisher.frames == frames then
| |
| sameFramePunisherFound = true
| |
|
| |
| for _, dmg in damages do
| |
| table.insert(punisher.damages, dmg)
| |
| end
| |
| end
| |
| end
| |
|
| |
| if not sameFramePunisherFound then
| |
| table.insert(block[type], { frames = frames, damages = damages })
| |
| end
| |
| end
| |
| for _, punishers in ipairs(block) do
| |
| for _, punisher in ipairs(punishers) do
| |
| table.sort(punisher.damages, function(l, r) return l.value < r.value end)
| |
| end
| |
| table.sort(punishers, function(l, r) return l.frames < r.frames end)
| |
| end
| |
|
| |
| local root = mw.html.create('div'):addClass('punishment')
| |
| for pos,punishment in pairs(block) do
| |
| local group = mw.html.create('div'):addClass('punishment-group')
| |
| root:node(group)
| |
| group:node(mw.html.create("div"):addClass('punishment-label')
| |
| :wikitext(pos .. " punishment")
| |
| )
| |
| local grid = mw.html.create('div'):addClass('punishment-grid')
| |
| group:node(grid)
| |
|
| |
| best = {}
| |
| for _, punisher in pairs(punishment) do
| |
| -- don't carry rage/meter punishment, makes viz. look funky
| |
| best[data.P_METER] = nil
| |
|
| |
| for k, v in pairs(punisher) do
| |
|
| |
|
| |
| if best[v] == nil or best[v] < k then
| |
| best[v] = k
| |
| end
| |
| end
| |
| if best[true] then
| |
| for k,v in pairs(best) do
| |
| if k ~= true and best[k] <= best[true] then
| |
| best[k] = nil
| |
| end
| |
| end
| |
| end
| |
|
| |
| if punishment[i] ~= nil or (i >= 10 and i <= 15) then
| |
| bestSortedKeys = {}
| |
| for k,_ in pairs(best) do
| |
| table.insert(bestSortedKeys, k)
| |
| end
| |
| table.sort(bestSortedKeys, function (a, b)
| |
| -- Larger bars first so that smaller bars are actually visible
| |
| return best[a] > best[b]
| |
| end)
| |
|
| |
| grid:node(mw.html.create('div'):addClass('punishment-startup')
| |
| :wikitext("-" .. i)
| |
| )
| |
| local bars = mw.html.create('div'):addClass('punishment-bars')
| |
| grid:node(bars)
| |
| for i,k in ipairs(bestSortedKeys) do
| |
| local class = k
| |
| if class == true then class = 'bg-blue' end
| |
| bars:node(
| |
| mw.html.create('div'):addClass('punishment-bar')
| |
| :addClass(class)
| |
| :css("width", string.format("%.2f%%", 100 * best[k] / span))
| |
| :wikitext(best[k])
| |
| )
| |
| end
| |
| local median = data.median[pos][i]
| |
| if median ~= nil then
| |
| bars:node(
| |
| mw.html.create('div'):addClass('punishment-median')
| |
| :css('width', string.format("%.2f%%", 100 * median / span))
| |
| )
| |
| end
| |
| end
| |
| end
| |
| grid:node(mw.clone(scale))
| |
| end
| |
|
| |
| return root
| |
| end
| |
| | |
| return p | | return p |