BryghtShadow (talk | contribs) (+memento group) |
BryghtShadow (talk | contribs) (Hmm...) |
||
(12 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | --<nowiki> |
||
⚫ | |||
⚫ | |||
+ | |||
local cargo = require('Module:CargoUtil') |
local cargo = require('Module:CargoUtil') |
||
local render_item_icon = require('Module:Render/Item')._icon |
local render_item_icon = require('Module:Render/Item')._icon |
||
Line 6: | Line 10: | ||
local enums = require('Module:Data/Enums') |
local enums = require('Module:Data/Enums') |
||
local yesno = require('Module:Yesno') |
local yesno = require('Module:Yesno') |
||
+ | enums.eCardType = { |
||
+ | [0] = "None", |
||
+ | [1] = "Equipment", |
||
+ | [2] = "Enhance_exp", |
||
+ | [3] = "Enhance_trust" |
||
⚫ | |||
local typeMap = { |
local typeMap = { |
||
[1] = 'Equipment', |
[1] = 'Equipment', |
||
Line 19: | Line 29: | ||
root:addClass('infobox') |
root:addClass('infobox') |
||
root:addClass(args.class) |
root:addClass(args.class) |
||
− | root:css{ |
||
⚫ | |||
− | ['margin-left'] = '15px', |
||
− | ['width'] = '300px', |
||
− | ['border'] = '1px solid #aaa', |
||
− | ['background'] = '#eee', |
||
− | ['font-size'] = '12px', |
||
⚫ | |||
local heading = root:tag('div') |
local heading = root:tag('div') |
||
heading:addClass('heading') |
heading:addClass('heading') |
||
− | heading:css{ |
||
− | ['background'] = 'goldenrod', |
||
− | ['font-weight'] = 700, |
||
− | ['font-size'] = '140%', |
||
− | ['line-height'] = '1.25em', |
||
− | ['display'] = 'flex', |
||
⚫ | |||
− | ['justify-items'] = 'flex-start', |
||
− | ['text-align'] = 'center', |
||
− | ['min-height'] = '64px', |
||
⚫ | |||
local icon = heading:tag('div') |
local icon = heading:tag('div') |
||
icon:addClass('infobox-icon') |
icon:addClass('infobox-icon') |
||
− | icon:css{ |
||
− | ['flex'] = '0 0 64px', |
||
− | ['padding'] = '0.25rem', |
||
⚫ | |||
icon:node(args.icon) |
icon:node(args.icon) |
||
local name = heading:tag('div') |
local name = heading:tag('div') |
||
name:addClass('name') |
name:addClass('name') |
||
− | name:css{ |
||
− | ['flex'] = '1 1 100%', |
||
− | ['display'] = 'flex', |
||
− | ['text-align'] = 'center', |
||
− | ['align-items'] = 'center', |
||
− | ['justify-content'] = 'center', |
||
− | ['margin'] = '0', |
||
− | ['padding'] = '0.25rem', |
||
− | } |
||
name:wikitext(args.name) |
name:wikitext(args.name) |
||
local wrapper = root:tag('div') |
local wrapper = root:tag('div') |
||
wrapper:addClass('wrapper') |
wrapper:addClass('wrapper') |
||
− | wrapper:css{ |
||
− | ['flex'] = '1 1 100%', |
||
− | ['overflow']='hidden', |
||
− | } |
||
local dl = wrapper:tag('dl') |
local dl = wrapper:tag('dl') |
||
− | dl:css{ |
||
− | ['display'] = 'grid', |
||
− | ['grid-template-columns'] = '100px 1fr', |
||
− | } |
||
local function printRow(t, label, content) |
local function printRow(t, label, content) |
||
if content == nil then return end |
if content == nil then return end |
||
local dt = t:tag('dt') |
local dt = t:tag('dt') |
||
− | dt:css{ |
||
− | ['grid-column-start'] = 1, |
||
− | ['padding'] = '2px 8px 2px 3px', |
||
− | ['text-align'] = 'right', |
||
− | ['border-right'] = '2px solid #aaa', |
||
− | ['margin'] = '0 -2px 0 0', |
||
⚫ | |||
dt:wikitext(label) |
dt:wikitext(label) |
||
local dd = t:tag('dd') |
local dd = t:tag('dd') |
||
− | dd:css{ |
||
− | ['grid-column-start'] = 2, |
||
− | ['margin'] = 0, |
||
− | ['padding'] = '2px 7px', |
||
− | ['border-left'] = '2px solid #aaa', |
||
⚫ | |||
dd:wikitext(content) |
dd:wikitext(content) |
||
end |
end |
||
Line 99: | Line 56: | ||
end |
end |
||
− | local |
+ | local cats = {} |
function p.getData(iname) |
function p.getData(iname) |
||
Line 292: | Line 249: | ||
end |
end |
||
⚫ | |||
function h.printEffects(root, args) |
function h.printEffects(root, args) |
||
if not args then return end |
if not args then return end |
||
Line 334: | Line 290: | ||
if eff.add_card_skill_buff_lvmax then |
if eff.add_card_skill_buff_lvmax then |
||
root:tag('h4'):wikitext('Max Limit Break') |
root:tag('h4'):wikitext('Max Limit Break') |
||
− | local |
+ | local buffdetails = h.getBuffDetails(eff.add_card_skill_buff_lvmax) or {} |
− | if |
+ | if #buffdetails == 0 then |
root:tag('div'):wikitext('Missing buff '..eff.add_card_skill_buff_lvmax..' from DB') |
root:tag('div'):wikitext('Missing buff '..eff.add_card_skill_buff_lvmax..' from DB') |
||
else |
else |
||
Line 342: | Line 298: | ||
tr:tag('th'):wikitext('Type') |
tr:tag('th'):wikitext('Type') |
||
for lb=5,5 do tr:tag('th'):wikitext('LB'..lb) end |
for lb=5,5 do tr:tag('th'):wikitext('LB'..lb) end |
||
− | for i |
+ | for i, buff in ipairs(buffdetails) do |
tr = tbl:tag('tr') |
tr = tbl:tag('tr') |
||
− | if tonumber(buff |
+ | if tonumber(buff.type or 0) > 0 then |
− | local |
+ | local statName = enums.statNameFromType(buff.type, buff.tktag) |
− | tr:tag('td'):wikitext( |
+ | tr:tag('td'):wikitext(statName) |
− | local min, max = buff |
+ | local min, max = buff.vini, buff.vmax |
local per = (max - min) / 4 |
local per = (max - min) / 4 |
||
for lb=5,5 do |
for lb=5,5 do |
||
Line 386: | Line 342: | ||
root:tag('h4'):wikitext('Ability '..key) |
root:tag('h4'):wikitext('Ability '..key) |
||
local ab = ability[key] |
local ab = ability[key] |
||
⚫ | |||
local abType = ab.type_detail and enums.EAbilityTypeDetail[tonumber(ab.type_detail)] or nil |
local abType = ab.type_detail and enums.EAbilityTypeDetail[tonumber(ab.type_detail)] or nil |
||
− | if abType ~= 'VisionAbility' then |
+ | if abType ~= nil and abType ~= 'VisionAbility' then |
error('Expected ability type "VisionAbility", but was "'..tostring(abType)..'".') |
error('Expected ability type "VisionAbility", but was "'..tostring(abType)..'".') |
||
end |
end |
||
Line 728: | Line 685: | ||
if not skill then return end |
if not skill then return end |
||
− | local |
+ | local t_buff_details = h.getBuffDetails(skill.t_buff) or {} |
− | local |
+ | local s_buff_details = h.getBuffDetails(skill.s_buff) or {} |
local stats = { |
local stats = { |
||
⚫ | |||
} |
} |
||
− | for i |
+ | for i, buff in ipairs(t_buff_details) do |
− | if tonumber( |
+ | if tonumber(buff.type or 0) > 0 then |
− | local tp = tostring( |
+ | local tp = tostring(buff.type) |
local values = {} |
local values = {} |
||
− | local min, max = |
+ | local min, max = buff.vini, buff.vmax |
local per = (max - min) / (maxLevel - 1) |
local per = (max - min) / (maxLevel - 1) |
||
for level=1,maxLevel do |
for level=1,maxLevel do |
||
Line 755: | Line 711: | ||
tr:tag('th'):wikitext('Lvl '..(maxLevel-10)) |
tr:tag('th'):wikitext('Lvl '..(maxLevel-10)) |
||
tr:tag('th'):wikitext('Lvl '..maxLevel) |
tr:tag('th'):wikitext('Lvl '..maxLevel) |
||
− | for i |
+ | for i, buff in ipairs(t_buff_details) do |
− | if tonumber( |
+ | if tonumber(buff.type or 0) > 0 then |
local tr = simple:tag('tr') |
local tr = simple:tag('tr') |
||
− | local tp = tostring( |
+ | local tp = tostring(buff.type) |
local values = stats[tp] |
local values = stats[tp] |
||
− | + | local statName = enums.statNameFromType(buff.type, buff.tktag) |
|
+ | tr:tag('td'):wikitext(statName) |
||
tr:tag('td'):wikitext(string.format('%+d', values[1])) |
tr:tag('td'):wikitext(string.format('%+d', values[1])) |
||
tr:tag('td'):wikitext(string.format('%+d', values[maxLevel-10])) |
tr:tag('td'):wikitext(string.format('%+d', values[maxLevel-10])) |
||
Line 788: | Line 745: | ||
local tr = wikitable:tag('tr') |
local tr = wikitable:tag('tr') |
||
tr:tag('th'):wikitext('Level') |
tr:tag('th'):wikitext('Level') |
||
− | for i |
+ | for i, buff in ipairs(t_buff_details) do |
− | if tonumber( |
+ | if tonumber(buff.type or 0) > 0 then |
− | local |
+ | local statName = enums.statNameFromType(buff.type, buff.tktag) |
− | tr:tag('th'):wikitext( |
+ | tr:tag('th'):wikitext(statName) |
end |
end |
||
end |
end |
||
Line 798: | Line 755: | ||
local tr = wikitable:tag('tr') |
local tr = wikitable:tag('tr') |
||
tr:tag('td'):wikitext(level) |
tr:tag('td'):wikitext(level) |
||
− | for i |
+ | for i, buff in ipairs(t_buff_details) do |
− | if tonumber( |
+ | if tonumber(buff.type or 0) > 0 then |
− | local tp = tostring( |
+ | local tp = tostring(buff.type) |
tr:tag('td'):wikitext(string.format('%+d', stats[tp][level])) |
tr:tag('td'):wikitext(string.format('%+d', stats[tp][level])) |
||
end |
end |
||
Line 825: | Line 782: | ||
-- ["vmax1"] = 30, |
-- ["vmax1"] = 30, |
||
-- } |
-- } |
||
− | local |
+ | local buff_details = h.getBuffDetails(buff_iname) or {} |
− | if |
+ | if #buff_details == 0 then |
root:tag('div'):wikitext('Missing buff ' .. buff_iname .. ' from DB') |
root:tag('div'):wikitext('Missing buff ' .. buff_iname .. ' from DB') |
||
return |
return |
||
Line 835: | Line 792: | ||
tr:tag('th'):wikitext('Type') |
tr:tag('th'):wikitext('Type') |
||
for lb=1,5 do tr:tag('th'):wikitext('LB'..lb) end |
for lb=1,5 do tr:tag('th'):wikitext('LB'..lb) end |
||
− | for i |
+ | for i, buff in ipairs(buff_details) do |
tr = tbl:tag('tr') |
tr = tbl:tag('tr') |
||
− | if tonumber(buff |
+ | if tonumber(buff.type or 0) > 0 then |
− | local |
+ | local statName = enums.statNameFromType(buff.type, buff.tktag) |
− | tr:tag('td'):wikitext( |
+ | tr:tag('td'):wikitext(statName) |
− | local min, max = buff |
+ | local min, max = buff.vini, buff.vmax |
local per = (max - min) / 4 |
local per = (max - min) / 4 |
||
for lb=1,5 do |
for lb=1,5 do |
||
Line 848: | Line 805: | ||
end |
end |
||
end |
end |
||
⚫ | |||
+ | |||
+ | function h.getBuffDetails(iname) |
||
⚫ | |||
+ | return cargo.query{ |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | orderBy = 'idx', |
||
⚫ | |||
end |
end |
||
Line 859: | Line 837: | ||
fields = { |
fields = { |
||
'ConceptCard.iname = iname', |
'ConceptCard.iname = iname', |
||
⚫ | |||
− | --name = "String", -- In Loc |
||
− | --expr = "String", -- In Loc |
||
− | --flavor is not actually in the data in JP (it's in a Loc file), but is imported as if it were |
||
-- Graphics |
-- Graphics |
||
'ConceptCard.icon = icon', |
'ConceptCard.icon = icon', |
||
Line 891: | Line 865: | ||
'ConceptCard.concept_card_groups = concept_card_groups', -- {"String", list='|'}, |
'ConceptCard.concept_card_groups = concept_card_groups', -- {"String", list='|'}, |
||
'ConceptCard.leader_skill = leader_skill', -- {"String", dataRef="MasterParam/Skill"}, |
'ConceptCard.leader_skill = leader_skill', -- {"String", dataRef="MasterParam/Skill"}, |
||
⚫ | |||
'Names.value = name', |
'Names.value = name', |
||
'Flavors.value = flavor', |
'Flavors.value = flavor', |
||
Line 899: | Line 874: | ||
'Flavors.param = "flavor" AND Flavors.lang = "english"', |
'Flavors.param = "flavor" AND Flavors.lang = "english"', |
||
}, |
}, |
||
⚫ | |||
⚫ | |||
+ | 'ConceptCard._pageName = Names._pageName', |
||
⚫ | |||
⚫ | |||
} |
} |
||
local data = card_rows[1] |
local data = card_rows[1] |
||
Line 905: | Line 883: | ||
return '`'..iname..'` not found in ConceptCard table.' |
return '`'..iname..'` not found in ConceptCard table.' |
||
end |
end |
||
+ | cats[#cats+1] = 'Memento' |
||
local effects = cargo.query{ |
local effects = cargo.query{ |
||
tables = 'ConceptCardEffect', |
tables = 'ConceptCardEffect', |
||
Line 925: | Line 904: | ||
} |
} |
||
} |
} |
||
− | -- if #effects == 0 then |
||
− | -- data2 = p.getData(iname) |
||
− | -- effects = data2.gl and data2.gl.effects or nil |
||
− | -- end |
||
− | for i, effect in ipairs(effects or {}) do |
||
− | for k,v in pairs(effect) do |
||
− | if type(v) == 'string' and v == '' then |
||
− | effect[k] = nil |
||
⚫ | |||
⚫ | |||
⚫ | |||
local name = data.name |
local name = data.name |
||
Line 948: | Line 916: | ||
} |
} |
||
img:wikitext('[[File:Game,ConceptCardIcon,',data.icon,'.png|57px]]') |
img:wikitext('[[File:Game,ConceptCardIcon,',data.icon,'.png|57px]]') |
||
− | local maxLevels = {1, 25, 30, 35, 40} |
||
-- Memento extra data |
-- Memento extra data |
||
local extra = mw.loadData("Module:Data/Extra/Memento")[iname] or {} |
local extra = mw.loadData("Module:Data/Extra/Memento")[iname] or {} |
||
Line 959: | Line 926: | ||
end |
end |
||
end |
end |
||
⚫ | |||
− | |||
⚫ | |||
− | 'Memento' |
||
− | } |
||
local root = mw.html.create() |
local root = mw.html.create() |
||
-- Info Box |
-- Info Box |
||
Line 1,007: | Line 971: | ||
:css{ |
:css{ |
||
['margin'] = 'auto', |
['margin'] = 'auto', |
||
− | [' |
+ | ['display'] = 'flex', |
⚫ | |||
⚫ | |||
} |
} |
||
+ | :tag('div') |
||
− | :wikitext('[[File:Game,ConceptCard,', data.icon, '.png]]') |
+ | :wikitext('[[File:Game,ConceptCard,', data.icon, '.png|512px]]') |
+ | :done() |
||
:tag('div'):addClass('flavor') |
:tag('div'):addClass('flavor') |
||
:css{ |
:css{ |
||
Line 1,016: | Line 984: | ||
} |
} |
||
:wikitext(data.flavor) |
:wikitext(data.flavor) |
||
+ | :done() |
||
h.printLeaderSkill(root, data.leader_skill) |
h.printLeaderSkill(root, data.leader_skill) |
||
⚫ | |||
-- TODO: Stats + Effects |
-- TODO: Stats + Effects |
||
h.printEffects(root, { |
h.printEffects(root, { |
||
Line 1,082: | Line 1,052: | ||
}, |
}, |
||
join = {'Skill._pageName = SkillName._pageName', 'Skill._pageName = SkillExpr._pageName'}, |
join = {'Skill._pageName = SkillName._pageName', 'Skill._pageName = SkillExpr._pageName'}, |
||
+ | }[1] |
||
⚫ | |||
+ | if not skill then return nil end |
||
root:newline():tag('h2'):wikitext("Leader Skill") |
root:newline():tag('h2'):wikitext("Leader Skill") |
||
root:newline():tag('h3'):wikitext(skill.name) |
root:newline():tag('h3'):wikitext(skill.name) |
||
Line 1,091: | Line 1,062: | ||
skill.cond = enums.ESkillCondition[tonumber(skill.cond)] |
skill.cond = enums.ESkillCondition[tonumber(skill.cond)] |
||
skill.timing = enums.ESkillTiming[tonumber(skill.timing)] |
skill.timing = enums.ESkillTiming[tonumber(skill.timing)] |
||
+ | |||
− | |||
if skill.t_buff then |
if skill.t_buff then |
||
local buff = cargo.query{ |
local buff = cargo.query{ |
||
Line 1,103: | Line 1,074: | ||
}, |
}, |
||
}[1] |
}[1] |
||
− | local buff_details = |
+ | local buff_details = h.getBuffDetails(buff.iname) or {} |
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | }, |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | }, |
||
− | } |
||
if #buff_details > 0 then |
if #buff_details > 0 then |
||
local tbl = root:newline():tag('table'):addClass('wikitable') |
local tbl = root:newline():tag('table'):addClass('wikitable') |
||
Line 1,127: | Line 1,084: | ||
:tag('th'):wikitext('Min'):done() |
:tag('th'):wikitext('Min'):done() |
||
:tag('th'):wikitext('Max'):done() |
:tag('th'):wikitext('Max'):done() |
||
− | for i, |
+ | for i, buff in ipairs(buff_details) do |
local tr = tbl:newline():tag('tr') |
local tr = tbl:newline():tag('tr') |
||
− | local fmt = yesno( |
+ | local fmt = yesno(buff.calc) and '%+d%%' or '%+d' |
− | + | local statName = enums.statNameFromType(buff.type, buff.tktag) |
|
− | tr:tag(' |
+ | tr:tag('th'):wikitext(statName) |
− | tr:tag('td'):wikitext(string.format(fmt, tonumber( |
+ | tr:tag('td'):wikitext(string.format(fmt, tonumber(buff.vini))) |
+ | tr:tag('td'):wikitext(string.format(fmt, tonumber(buff.vmax))) |
||
+ | if buff.tktag then |
||
+ | cats[#cats+1] = statName |
||
⚫ | |||
end |
end |
||
end |
end |
||
Line 1,166: | Line 1,127: | ||
}, |
}, |
||
} |
} |
||
⚫ | |||
for _, custom_target in ipairs(custom_targets) do |
for _, custom_target in ipairs(custom_targets) do |
||
if custom_target.concept_card_groups then |
if custom_target.concept_card_groups then |
||
Line 1,185: | Line 1,145: | ||
}, |
}, |
||
where = { |
where = { |
||
⚫ | |||
'ConceptCardGroup.server = "gl"', |
'ConceptCardGroup.server = "gl"', |
||
'ConceptCard.server = "gl"', |
'ConceptCard.server = "gl"', |
||
⚫ | |||
}, |
}, |
||
join = { |
join = { |
||
Line 1,196: | Line 1,156: | ||
} |
} |
||
root:newline():tag('h4'):wikitext('Memento Group') |
root:newline():tag('h4'):wikitext('Memento Group') |
||
⚫ | |||
for _, card in ipairs(cards) do |
for _, card in ipairs(cards) do |
||
− | mw.logObject(card) |
+ | mw.logObject(card, 'card') |
− | local icon = |
+ | -- local icon = '' |
+ | if card.PAGENAME then |
||
⚫ | |||
− | + | local icon = string.format( |
|
⚫ | |||
⚫ | |||
+ | card.icon, card.PAGENAME, card.PAGENAME) |
||
⚫ | |||
⚫ | |||
end |
end |
||
end |
end |
||
end |
end |
||
− | -- if #custom_targets > 0 then |
||
− | |||
− | -- for _, ct_iname in ipairs(buff.custom_targets) do |
||
− | -- local custom_target = cargo.query{ |
||
− | -- tables = 'CustomTarget', |
||
− | -- fields = { |
||
− | -- 'birth_id', -- Integer |
||
− | -- 'concept_card_groups', -- List of String |
||
− | -- 'dark', -- Integer |
||
− | -- 'fire', -- Integer |
||
− | -- -- 'iname', -- String |
||
− | -- 'job_groups', -- List of String |
||
− | -- -- 'server', -- String |
||
− | -- 'sex', -- Integer |
||
− | -- 'shine', -- Integer |
||
− | -- 'thunder', -- Integer |
||
− | -- 'unit_groups', -- List of String |
||
− | -- 'units', -- List of String |
||
− | -- 'water', -- Integer |
||
− | -- 'wind', -- Integer |
||
− | -- }, |
||
− | -- where = { |
||
− | -- 'server = "gl"', |
||
− | -- 'iname = "'..ct_iname..'"', |
||
− | -- } |
||
− | -- }[1] |
||
⚫ | |||
− | -- if custom_target.concept_card_groups then |
||
− | -- local cards = cargo.query{ |
||
− | -- tables = { |
||
− | -- 'ConceptCardGroup', |
||
− | -- 'ConceptCardGroup__cards', |
||
− | -- 'ConceptCard', |
||
− | -- }, |
||
− | -- fields = { |
||
⚫ | |||
− | -- 'ConceptCard.icon = icon', |
||
− | -- -- Type |
||
− | -- 'ConceptCard.type = type', -- eCardType |
||
− | -- 'ConceptCard.rare = rare', |
||
− | -- }, |
||
− | -- where = { |
||
− | -- 'ConceptCardGroup.server = "gl"', |
||
− | -- 'ConceptCard.server = "gl"', |
||
− | -- 'ConceptCardGroup.iname = "'..custom_target.concept_card_groups..'"' |
||
− | -- }, |
||
⚫ | |||
− | -- 'ConceptCardGroup._ID = ConceptCardGroup__cards._rowID', |
||
− | -- 'ConceptCardGroup__cards._value = ConceptCard.iname', |
||
− | -- } |
||
− | -- } |
||
− | -- for _, card in ipairs(cards) do |
||
⚫ | |||
⚫ | |||
− | -- end |
||
− | -- end |
||
− | -- end |
||
− | -- end |
||
end |
end |
||
end |
end |
||
function p.test(frame) |
function p.test(frame) |
||
− | local root = mw.html.create() |
+ | -- local root = mw.html.create() |
− | h.printLeaderSkill(root, 'SK_LS_TS_ENVYRIA_CLOE_01') |
+ | -- h.printLeaderSkill(root, 'SK_LS_TS_ENVYRIA_CLOE_01') |
− | + | -- mw.log(tostring(root)) |
|
+ | return |
||
− | -- return p.main{'TS_LOST_ZWEI_01'} |
||
+ | -- p.renderPage('TS_SAGA_BIRGITTA_01') .. |
||
+ | p.renderPage('TS_GL_SIBLINGS_01') |
||
end |
end |
||
return p |
return p |
||
+ | --</nowiki> |
Revision as of 07:29, 10 December 2020
Documentation for this module may be created at Module:Page/Memento/doc
--<nowiki>
local p = {}
local h = {}
local cargo = require('Module:CargoUtil')
local render_item_icon = require('Module:Render/Item')._icon
local render_gear_icon = require('Module:Render/Gear')._icon
local render_memento_icon = require('Module:Render/Memento')._icon
local render_unit_icon = require('Module:Render/Unit')._icon
local enums = require('Module:Data/Enums')
local yesno = require('Module:Yesno')
enums.eCardType = {
[0] = "None",
[1] = "Equipment",
[2] = "Enhance_exp",
[3] = "Enhance_trust"
}
local typeMap = {
[1] = 'Equipment',
[2] = 'Enhance EXP',
[3] = 'Enhance Trust',
}
local model = require('Module:Data').model
local query = model.query
local function makeInfobox(args)
local root = mw.html.create('div')
root:addClass('infobox')
root:addClass(args.class)
local heading = root:tag('div')
heading:addClass('heading')
local icon = heading:tag('div')
icon:addClass('infobox-icon')
icon:node(args.icon)
local name = heading:tag('div')
name:addClass('name')
name:wikitext(args.name)
local wrapper = root:tag('div')
wrapper:addClass('wrapper')
local dl = wrapper:tag('dl')
local function printRow(t, label, content)
if content == nil then return end
local dt = t:tag('dt')
dt:wikitext(label)
local dd = t:tag('dd')
dd:wikitext(content)
end
for i, label in ipairs(args.labels) do
printRow(dl, label, args.rows[label])
end
return tostring(root)
end
local cats = {}
function p.getData(iname)
local datapage = cargo.query{
tables = 'ConceptCard',
fields = '_pageName',
where = 'iname = "'..iname..'"',
groupBy = '_pageName, iname',
}[1]
local pagename = datapage and datapage._pageName or 'Data:Game/MasterParam/ConceptCard/'..iname
local frame = mw.getCurrentFrame()
local title = mw.title.new(pagename)
local content = title:getContent()
local args = {}
local params = content:match('^%s*%{%{#invoke:Data%|insert%|(.-)%}%}%s*$')
for param in mw.text.gsplit(params, '|', true) do
local k, v = param:match('([^=]+)=(.+)')
local obj = mw.text.jsonDecode(frame:preprocess(v))
if k == 'gl' or k == 'jp' then obj.server = k end
args[k] = obj
end
return args
end
local maxLevels = {1, 25, 30, 35, 40}
local function getVCR(data)
local t = {}
mw.logObject(data, 'getVCR')
local function f(s, render_icon)
local counts = data['trust_'..s..'_counts']
local names = data['trust_'..s..'_names']
if not names then return end
if type(names) == 'string' then
names = mw.text.split(names, '[%|,]')
end
if type(counts) == 'string' then
counts = mw.text.split(counts, '[%|,]')
end
for i, v in ipairs(names) do
-- table.insert(sb2, i)
-- table.insert(sb2, (counts[i] > 1) and counts[i] or nil)
table.insert(t, render_icon({v, name = 'none', count = tonumber(counts[i]) > 1 and tonumber(counts[i]) or nil}))
end
end
f('item', render_item_icon)
f('artifact', render_gear_icon)
return #t > 0 and table.concat(t) or nil
end
local function getUnitReward(data)
local iname = data.first_get_unit or ''
if iname == '' then return nil end
return render_unit_icon{iname, size='small'}
end
local function minQuery(args)
if type(args.fields) == 'string' and args.fields == '*' then
local subModel = mw.loadData('Module:Data/Model/'..args.tables)
local t = {'_pageName', 'server'}
for k,v in pairs(subModel) do
t[#t+1] = k
end
args.fields = t
end
local row = cargo.query(args)[1]
if not row then return end
local obj = {}
for k,v in pairs(row) do
if type(v) == 'table' then
if #v > 0 then obj[k] = v end
elseif v ~= '' then
obj[k] = v
end
end
return obj
end
local function queryBuff(iname)
if not iname then return end
return minQuery{tables='Buff',fields='*', where='iname="'..iname..'" AND server="gl"'}
end
local function querySkill(iname)
if not iname then return end
return minQuery{tables = 'Skill', fields = '*',
where = 'iname="'..iname..'" AND server="gl"'
}
end
local function queryAbility(iname)
if not iname then return end
return minQuery{tables = 'Ability', fields = '*',
where = 'iname="'..iname..'" AND server="gl"'
}
end
local function getUnitInamesByOrigins(birth_ids)
if type(birth_ids) == 'number' then
birth_ids = {birth_ids}
end
local ids = {}
for i, birth_id in ipairs(birth_ids) do
ids[i] = string.format('%q', birth_id)
end
local t = {}
local rows = cargo.query{
tables = 'Unit',
fields = 'iname',
where = {
'ai = "AI_PLAYER"',
'(notsmn IS NULL OR hero = 1)',
'server = "gl"',
'birth_id IN ('..table.concat(ids, ',')..')',
}
}
for i, row in ipairs(rows) do
t[i] = row.iname
end
return t
end
local function getUnitInamesByGender(sex)
local t = {}
local rows = cargo.query{
tables = 'Unit',
fields = 'iname',
where = {
'ai = "AI_PLAYER"',
'(notsmn IS NULL OR hero = 1)',
'server = "gl"',
'sex = "'..sex..'"',
}
}
for i, row in ipairs(rows) do
t[i] = row.iname
end
return t
end
local function getOriginalJobInamesFromJobInames( jobs )
local t = {}
local inames = {}
for i, v in ipairs(jobs) do
inames[i] = string.format('%q', v)
end
if #inames == 0 then return t end
local rows = cargo.query{
tables = 'Job',
fields = 'iname, origin',
where = 'iname IN ('..table.concat(inames, ',')..') AND server = "gl"'
}
for i, row in ipairs(rows) do
t[i] = (row.origin or '') ~= '' and row.origin or row.iname
end
return t
end
local function getOriginalJobInamesFromJobGroups( job_groups )
if type(job_groups) == 'string' then
job_groups = {job_groups}
end
local t, i = {}, 0
for _, jg_iname in ipairs(job_groups) do
local job_group = cargo.query{
tables = 'JobGroup',
fields = 'jobs',
where = 'iname = "'..jg_iname..'" AND server = "gl"',
}[1]
if job_group then
if type(job_group.jobs) == 'string' then
job_group.jobs = mw.text.split(job_group.jobs, '[%|,]')
end
local inames = getOriginalJobInamesFromJobInames(job_group.jobs)
for _, iname in ipairs(inames) do
i = i + 1
t[i] = iname
end
end
end
return t
end
local function getUnitInamesFromUnitGroups( unit_groups )
local t, i = {}, 0
for _, ug_iname in ipairs(unit_groups) do
local units = mw.loadData('Module:Data/MasterParam/UnitGroup')[ug_iname].units
for _, iname in ipairs(units) do
i = i + 1
t[i] = iname
end
end
return t
end
function h.printEffects(root, args)
if not args then return end
if not args.effects then return end
local stat = nil
local card_skills = {}
local abilities = {}
for i, eff in ipairs(args.effects) do
if eff.statusup_skill then
stat = eff
end
if eff.card_skill then
card_skills[#card_skills+1] = eff
end
if eff.abil_iname then
abilities[#abilities+1] = eff
end
end
local maxLevel = maxLevels[args.rare+1]
if stat then
root:tag('h2'):wikitext('Stats')
h.printStatsTable(root, stat.statusup_skill, maxLevel)
end
if #card_skills > 0 then
root:tag('h2'):wikitext('Group skills')
for i, eff in ipairs(card_skills) do
local skill = query('Skill', '_pageName', {
where = 'iname = "'..eff.card_skill..'" AND server = "gl"',
})[1]
local skillname = skill and model.getLoc(skill._pageName, 'name') or '???'
root:tag('h3'):wikitext(skillname)
h.printStatsTable(root, eff.card_skill, maxLevel)
if eff.add_card_skill_buff_awake then -- limit break buff
root:tag('h4'):wikitext('Limit Break')
h.printAddCardSkillBuffAwake(root, eff.add_card_skill_buff_awake)
end
if eff.add_card_skill_buff_lvmax then
root:tag('h4'):wikitext('Max Limit Break')
local buffdetails = h.getBuffDetails(eff.add_card_skill_buff_lvmax) or {}
if #buffdetails == 0 then
root:tag('div'):wikitext('Missing buff '..eff.add_card_skill_buff_lvmax..' from DB')
else
local tbl = root:tag('table'):addClass('wikitable')
local tr = tbl:tag('tr')
tr:tag('th'):wikitext('Type')
for lb=5,5 do tr:tag('th'):wikitext('LB'..lb) end
for i, buff in ipairs(buffdetails) do
tr = tbl:tag('tr')
if tonumber(buff.type or 0) > 0 then
local statName = enums.statNameFromType(buff.type, buff.tktag)
tr:tag('td'):wikitext(statName)
local min, max = buff.vini, buff.vmax
local per = (max - min) / 4
for lb=5,5 do
local value = math.floor((lb - 1) * per + min)
tr:tag('td'):wikitext(string.format('%+d', value))
end
end
end
end
end
if eff.cnds_iname then
h.printEffect(root, eff)
end
end
end
if #abilities > 0 then
root:tag('h2'):wikitext('Vision abilities')
local function printAbility(root, eff)
if not eff then return end
if not eff.abil_iname then return end
if not eff.abil_iname_lvmax then return end
local ability = {
base = queryAbility(eff.abil_iname),
max = queryAbility(eff.abil_iname_lvmax),
}
local baseName = model.getLoc(ability.base._pageName, 'name')
local maxName = model.getLoc(ability.max._pageName, 'name')
root:tag('h3'):wikitext(baseName)
if maxName ~= baseName then
error('Expected max ability name to be `'..baseName..'` but was `'..maxName..'`.')
end
for _, key in ipairs{'base', 'max'} do
root:tag('h4'):wikitext('Ability '..key)
local ab = ability[key]
mw.logObject(ab, 'ab')
local abType = ab.type_detail and enums.EAbilityTypeDetail[tonumber(ab.type_detail)] or nil
if abType ~= nil and abType ~= 'VisionAbility' then
error('Expected ability type "VisionAbility", but was "'..tostring(abType)..'".')
end
local ul = root:tag('ul')
if ab.slot then
local slot = enums.EAbilitySlot[tonumber(ab.slot)]
ul:tag('li'):wikitext('Slot: [[File:MasterAbilityIcon.png|20px|'..slot..'|link=]] '..slot)
end
if ab.skl1 then
local skill = querySkill(ab.skl1)
if tonumber(skill.atk_type or 0) > 0 then
local atk_type = enums.AttackTypes[tonumber(skill.atk_type)]
if atk_type == 'MagAttack' then
atk_type = 'Magical'
elseif atk_type == 'PhyAttack' then
atk_type = 'Physical'
end
ul:tag('li'):wikitext('DMG Type: [[File:Attack Class '..atk_type..'.png|20px|'..atk_type..'|link=]] '..atk_type)
end
if tonumber(skill.atk_det or 0) > 0 then
local atk_det = enums.attackDetailNameFromKey(skill.atk_det)
if atk_det == 'Blow' then
atk_det = 'Strike'
end
ul:tag('li'):wikitext('ATK Type: [[File:Attack Type '..atk_det..'.png|20px|'..atk_det..'|link=]] '..atk_det)
end
if tonumber(skill.elem or 0) > 0 then
local elem = enums.elemFromKey(tonumber(skill.elem))
ul:tag('li'):wikitext('Element: [[File:'..elem..'Element.png|20px|link=]] '..elem)
end
-- Explanation
local expr = model.getLoc(skill._pageName, 'expr')
root:tag('p'):wikitext(expr)
-- Skill effect
if tonumber(skill.eff_type or 0) > 0 and skill.eff_val_ini and skill.eff_val_max then
local tbl = root:tag('table'):addClass('wikitable')
tbl:tag('caption'):wikitext('Skill Effect')
local tr = tbl:tag('tr')
tr:tag('th'):wikitext('Type')
tr:tag('th'):wikitext('Min')
tr:tag('th'):wikitext('Max')
tr = tbl:tag('tr')
tr:tag('td'):wikitext(enums.SkillEffectTypes[tonumber(skill.eff_type)])
tr:tag('td'):wikitext((100+skill.eff_val_ini)..'%')
tr:tag('td'):wikitext((100+skill.eff_val_max)..'%')
end
-- Scaling
-- Jewel cost
local ul = root:tag('ul')
if tonumber(skill.count or 0) > 0 then
ul:tag('li'):wikitext('Charges: ' .. skill.count)
end
if tonumber(skill.cost or 0) > 0 then
ul:tag('li'):wikitext('Jewel Cost: ' .. skill.cost)
end
if tonumber(skill.eff_h or 0) > 0 then
ul:tag('li'):wikitext('Height: ' .. skill.eff_h)
end
if skill.sran then
ul:tag('li'):wikitext('Select Range: ' .. enums.ESelectType[tonumber(skill.sran)])
ul:tag('li'):wikitext('Range: ' .. (skill.rangemin or 0) .. '-'.. (skill.rangemax or 0))
end
if skill.ssco then
ul:tag('li'):wikitext('Select Scope: ' .. enums.ESelectType[tonumber(skill.ssco)])
ul:tag('li'):wikitext('Scope: ' .. (skill.scope or 0))
end
end
end
end
for _, eff in ipairs(abilities) do
printAbility(root, eff)
if eff.cnds_iname then
h.printEffect(root, eff)
end
end
end
end
function h.printEffect(root, args)
-- Stats
if args.statusup_skill then
h.printStatsTable(root, args.statusup_skill, args.rare)
end
local inames = {}
-- Condition groups
for i, iname in ipairs(h.getTriggerGroups(args.cnds_iname) or {}) do
inames[iname] = inames[iname] or {}
inames[iname].hasConditions = true
end
-- Buff groups
for i, iname in ipairs(h.getBuffGroups(args.add_card_skill_buff_awake) or {}) do
inames[iname] = inames[iname] or {}
inames[iname].hasBuff = true
end
local icons = {
['Trigger + Buff'] = {Unit={},Job={}},
['Trigger'] = {Unit={},Job={}},
['Buff'] = {Unit={},Job={}},
[''] = {Unit={},Job={}},
}
for iname, thing in pairs(inames) do
local triggerbuff = {}
if thing.hasConditions then
triggerbuff[#triggerbuff+1] = 'Trigger'
end
if thing.hasBuff then
triggerbuff[#triggerbuff+1] = 'Buff'
end
triggerbuff = table.concat(triggerbuff, ' + ')
local prefix = iname:sub(1,3)
local tp = prefix == 'UN_' and 'Unit' or prefix == 'JB_' and 'Job' or ''
local t = icons[triggerbuff][tp]
local l = #t
local render_icon = require('Module:Render/'..tp)._icon
local page = cargo.query{tables = 'Pages', fields = '_pageName', where = 'iname = "'..iname..'"'}[1]
local name
if page then
name = page._pageName
else
page = cargo.query{
tables = {tp, 'Loc'},
fields = 'value',
where = {
'iname="'..iname..'"',
'param = "name"',
'lang IN ("english","japanese")',
'server="gl"',
},
join = tp..'._pageName = Loc._pageName',
}[1]
if page then
name = page.value
else
name = iname
end
end
t[l+1] = {iname=iname, name=name, icon=render_icon{iname, size='small'}}
end
if args.add_card_skill_buff_awake then
for _, triggerbuff in ipairs({'Trigger + Buff', 'Trigger', 'Buff', ''}) do
for _, tp in ipairs({'Unit', 'Job'}) do
local objs = icons[triggerbuff][tp]
if #objs > 0 then
local heading = root:tag('h4')
heading:wikitext(tp, ' group')
if triggerbuff ~= '' then
heading:wikitext(' (', triggerbuff:lower(), ')')
end
table.sort(objs, function(a, b)
return a.name < b.name
end)
for i, obj in ipairs(objs) do
root:wikitext(obj.icon)
end
end
end
end
elseif args.abil_iname then
local objs = {}
if #icons.Trigger.Unit > 0 and #icons.Trigger.Job > 0 then
for _, unit in ipairs(icons.Trigger.Unit) do
local jb_inames = {}
local rows = query('Unit, Unit__jobsets, JobSet',
'JobSet.job = job',
{
where = 'Unit.server = "gl" AND JobSet.server = "gl" AND Unit.iname = "'..unit.iname..'"',
join = 'Unit._ID = Unit__jobsets._rowID, Unit__jobsets._value = JobSet.iname',
})
for _, row in ipairs(rows) do
jb_inames[row.job] = true
end
for _, job in ipairs(icons.Trigger.Job) do
if jb_inames[job.iname] then
objs[#objs+1] = {unit=unit, job=job}
end
end
end
local heading = root:tag('h4')
heading:wikitext('Unit and job restriction')
table.sort(objs, function(a, b)
return (a.unit.name < b.unit.name) and (a.job.name < b.job.name)
end)
local ul = root:tag('ul')
for _, obj in ipairs(objs) do
local li = ul:tag('li')
li:wikitext(obj.unit.icon, ' + ', obj.job.icon)
end
elseif #icons.Trigger.Unit > 0 then
local heading = root:tag('h4')
heading:wikitext('Unit restriction')
for _, obj in ipairs(icons.Trigger.Unit) do
objs[#objs+1] = obj
end
table.sort(objs, function(a,b) return a.name < b.name end)
for _, obj in ipairs(objs) do
root:wikitext(obj.icon)
end
elseif #icons.Trigger.Job > 0 then
local heading = root:tag('h4')
heading:wikitext('Job restriction')
for _, obj in ipairs(icons.Trigger.Job) do
objs[#objs+1] = obj
end
table.sort(objs, function(a,b) return a.name < b.name end)
for _, obj in ipairs(objs) do
root:wikitext(obj.icon)
end
end
end
end
function h.getTriggerGroups(cnds_iname)
if not cnds_iname then return end
-- Condition groups
local conditions = mw.loadData('Module:Data/MasterParam/ConceptCardConditions')[cnds_iname]
if not conditions then return end
local t = {}
if conditions.birth_id then
for _, iname in ipairs(getUnitInamesByOrigins(conditions.birth_id)) do
t[#t+1] = iname
end
end
if conditions.job_group then
for _, iname in ipairs(getOriginalJobInamesFromJobGroups(conditions.job_group)) do
t[#t+1] = iname
end
end
if conditions.sex then
for _, iname in ipairs(getUnitInamesByGender(conditions.sex)) do
t[#t+1] = iname
end
end
if conditions.un_group then
for _, iname in ipairs(mw.loadData('Module:Data/MasterParam/UnitGroup')[conditions.un_group].units) do
t[#t+1] = iname
end
end
if conditions.el_dark then
end
if conditions.el_fire then
end
if conditions.el_shine then
end
if conditions.el_thunder then
end
if conditions.el_water then
end
if conditions.el_wind then
end
if conditions.supported_units then
end
return t
end
function h.getBuffGroups(buff_iname)
if not buff_iname then return end
local buff = queryBuff(buff_iname)
if not buff then return end
if type(buff.custom_targets) == 'string' then
buff.custom_targets = mw.text.split(buff.custom_targets, '[%|,]')
end
local t = {}
for i, ct_iname in ipairs(buff.custom_targets or {}) do
local custom_target = mw.loadData('Module:Data/MasterParam/CustomTarget')[ct_iname]
if custom_target.birth_id then
for _, iname in ipairs(getUnitInamesByOrigins(custom_target.birth_id)) do
t[#t+1] = iname
end
end
if custom_target.concept_card_groups then
-- TODO
end
if custom_target.jobs then
for _, iname in ipairs(getOriginalJobInamesFromJobInames(custom_target.jobs)) do
t[#t+1] = iname
end
end
if custom_target.job_groups then
for _, iname in ipairs(getOriginalJobInamesFromJobGroups(custom_target.job_groups)) do
t[#t+1] = iname
end
end
if custom_target.sex then
for _, iname in ipairs(getUnitInamesByGender(custom_target.sex)) do
t[#t+1] = iname
end
end
if custom_target.units then
for _, iname in ipairs(custom_target.units) do
t[#t+1] = iname
end
end
if custom_target.unit_groups then
for _, iname in ipairs(getUnitInamesFromUnitGroups(custom_target.unit_groups)) do
t[#t+1] = iname
end
end
if custom_target.dark then
end
if custom_target.fire then
end
if custom_target.shine then
end
if custom_target.thunder then
end
if custom_target.water then
end
if custom_target.wind then
end
end
local un_group = buff.un_group and mw.loadData('Module:Data/MasterParam/UnitGroup')[buff.un_group]
for _, iname in ipairs(un_group or {}) do
t[#t+1] = iname
end
return t
end
function h.printStatsTable(root, skill_iname, maxLevel)
local skill = querySkill(skill_iname)
if not skill then return end
local t_buff_details = h.getBuffDetails(skill.t_buff) or {}
local s_buff_details = h.getBuffDetails(skill.s_buff) or {}
local stats = {
}
for i, buff in ipairs(t_buff_details) do
if tonumber(buff.type or 0) > 0 then
local tp = tostring(buff.type)
local values = {}
local min, max = buff.vini, buff.vmax
local per = (max - min) / (maxLevel - 1)
for level=1,maxLevel do
values[level] = math.floor((level - 1) * per + min)
end
stats[tp] = values
end
end
-- Render
root:tag('h4'):wikitext('Simple stats')
local simple = root:tag('table'):addClass('wikitable')
local tr = simple:tag('tr')
tr:tag('th'):wikitext('Type')
tr:tag('th'):wikitext('Lvl 1')
tr:tag('th'):wikitext('Lvl '..(maxLevel-10))
tr:tag('th'):wikitext('Lvl '..maxLevel)
for i, buff in ipairs(t_buff_details) do
if tonumber(buff.type or 0) > 0 then
local tr = simple:tag('tr')
local tp = tostring(buff.type)
local values = stats[tp]
local statName = enums.statNameFromType(buff.type, buff.tktag)
tr:tag('td'):wikitext(statName)
tr:tag('td'):wikitext(string.format('%+d', values[1]))
tr:tag('td'):wikitext(string.format('%+d', values[maxLevel-10]))
tr:tag('td'):wikitext(string.format('%+d', values[maxLevel]))
end
end
--[==[ Scrollable table?
<div style="display: table">
<div style="max-height: 240px; overflow-y: scroll; box-sizing: border-box; padding: 4px; border: 1px solid #131313">
-- Long table here
</div>
</div>
--]==]
root:tag('h4'):wikitext('Detailed stats')
local detailed = root:tag('div'):css{
display = 'flex',
['flex-wrap'] = 'wrap',
}
for col = 1, maxLevel/10 do
local flexitem = detailed:tag('div'):css{
flex = 0,
background = col % 2 == 0 and 'orange' or 'salmon', -- yum ^_^
}
local wikitable = flexitem:tag('table'):addClass('wikitable')
local tr = wikitable:tag('tr')
tr:tag('th'):wikitext('Level')
for i, buff in ipairs(t_buff_details) do
if tonumber(buff.type or 0) > 0 then
local statName = enums.statNameFromType(buff.type, buff.tktag)
tr:tag('th'):wikitext(statName)
end
end
for row = 1, 10 do
local level = (col - 1) * 10 + row
local tr = wikitable:tag('tr')
tr:tag('td'):wikitext(level)
for i, buff in ipairs(t_buff_details) do
if tonumber(buff.type or 0) > 0 then
local tp = tostring(buff.type)
tr:tag('td'):wikitext(string.format('%+d', stats[tp][level]))
end
end
end
end
end
function h.printAddCardSkillBuffAwake(root, buff_iname)
-- add_card_skill_buff_awake = table#1 {
-- ["_pageName"] = "Data:Game/MasterParam/Buff/BUFF GS1 LOST ZWEI 01 BONUS 01",
-- ["calc1"] = 0,
-- ["chktgt"] = 0,
-- ["cond"] = 4,
-- ["custom_targets"] = table#2 {
-- "CT_LOST",
-- "CT_UROBOROS",
-- },
-- ["iname"] = "BUFF_GS1_LOST_ZWEI_01_BONUS_01",
-- ["server"] = "gl",
-- ["timing"] = 1,
-- ["type1"] = 7,
-- ["vini1"] = 8,
-- ["vmax1"] = 30,
-- }
local buff_details = h.getBuffDetails(buff_iname) or {}
if #buff_details == 0 then
root:tag('div'):wikitext('Missing buff ' .. buff_iname .. ' from DB')
return
end
-- Show limit break
local tbl = root:tag('table'):addClass('wikitable')
local tr = tbl:tag('tr')
tr:tag('th'):wikitext('Type')
for lb=1,5 do tr:tag('th'):wikitext('LB'..lb) end
for i, buff in ipairs(buff_details) do
tr = tbl:tag('tr')
if tonumber(buff.type or 0) > 0 then
local statName = enums.statNameFromType(buff.type, buff.tktag)
tr:tag('td'):wikitext(statName)
local min, max = buff.vini, buff.vmax
local per = (max - min) / 4
for lb=1,5 do
local value = math.floor((lb - 1) * per + min)
tr:tag('td'):wikitext(string.format('%+d', value))
end
end
end
end
function h.getBuffDetails(iname)
if not iname then return nil end
return cargo.query{
tables = 'BuffDetail',
fields = {
'idx',
'calc',
'tktag',
'type',
'vini',
'vmax',
'vone',
},
where = {
'BuffDetail.server = "gl"',
'BuffDetail.buff_iname = "'..iname..'"',
},
orderBy = 'idx',
}
end
local function renderPage(iname)
local card_rows = cargo.query{
tables = {
'ConceptCard',
'Loc = Names',
'Loc = Flavors',
},
fields = {
'ConceptCard.iname = iname',
-- Graphics
'ConceptCard.icon = icon',
-- Type
'ConceptCard.type = type', -- eCardType
'ConceptCard.rare = rare',
'ConceptCard.lvcap = lvcap', -- Default defined by rare
'ConceptCard.birth_id = birth_id', -- The origin of the memento
'ConceptCard.coin_item = coin_item', -- Not sure what this is used for, maybe related to the coin shop
-- Value
'ConceptCard.sell = sell', -- Integer",
'ConceptCard.not_sale = not_sale', -- Boolean",
'ConceptCard.en_cost = en_cost', -- Integer",
'ConceptCard.en_exp = en_exp', -- Integer",
'ConceptCard.en_trust = en_trust', -- Integer",
-- Rewards
'ConceptCard.trust_artifact_names = trust_artifact_names', -- {"String", list='|', dataRef="MasterParam/Artifact"},
'ConceptCard.trust_artifact_counts = trust_artifact_counts', -- {"Integer", list='|'},
'ConceptCard.trust_item_names = trust_item_names', -- {"String", list='|', dataRef="MasterParam/Item"},
'ConceptCard.trust_item_counts = trust_item_counts', -- {"Integer", list='|'},
-- References
'ConceptCard.first_get_unit = first_get_unit', -- {"String", dataRef="MasterParam/Unit"}, -- Unit acquired when first obtaining memento
-- Leader Skill
'ConceptCard.concept_card_groups = concept_card_groups', -- {"String", list='|'},
'ConceptCard.leader_skill = leader_skill', -- {"String", dataRef="MasterParam/Skill"},
-- Labels
'Names.value = name',
'Flavors.value = flavor',
},
where = {
'ConceptCard.iname = "'..iname..'"',
'Names.param = "name" AND Names.lang = "english"',
'Flavors.param = "flavor" AND Flavors.lang = "english"',
},
join = {
'ConceptCard._pageName = Names._pageName',
'ConceptCard._pageName = Flavors._pageName',
},
}
local data = card_rows[1]
if not data then
return '`'..iname..'` not found in ConceptCard table.'
end
cats[#cats+1] = 'Memento'
local effects = cargo.query{
tables = 'ConceptCardEffect',
fields = {
'cc_iname',
'abil_iname',
'abil_iname_lvmax',
'add_card_skill_buff_awake',
'add_card_skill_buff_lvmax',
'card_skill',
'cnds_iname',
'is_decrease_eff',
'server',
'skin',
'statusup_skill'
},
where = {
'cc_iname = "'..iname..'"',
'server = "gl"',
}
}
local name = data.name
local icon = mw.html.create('div')
icon:addClass('item-icon')
local img = icon:tag('div')
img:addClass('img x-'..data.rare..' y-4')
img:css{
['width'] = '57px',
['height'] = '57px',
['padding'] = '3.5px',
}
img:wikitext('[[File:Game,ConceptCardIcon,',data.icon,'.png|57px]]')
-- Memento extra data
local extra = mw.loadData("Module:Data/Extra/Memento")[iname] or {}
local releaseDates
for _, region in ipairs{'jp', 'gl'} do
local date = extra[region..'Date']
if date then
releaseDates = releaseDates or mw.html.create('ul')
releaseDates:tag('li'):wikitext(region:upper(), ': ', date)
end
end
local root = mw.html.create()
-- Info Box
local infobox = makeInfobox{
name = name,
icon = icon,
labels = {
'Type',
'Rank',
'Max level',
'Enhancer cost',
'Enhancer EXP',
'Enhancer trust',
'Vision Clear Reward',
'Gives unit',
'Source',
'Release dates',
'Global only',
'External links',
},
rows = {
['Type'] = typeMap[tonumber(data.type)],
['Rank'] = (data.rare + 1)..'★',
['Max level'] = maxLevels[data.rare + 1],
['Enhancer cost'] = data.en_cost, -- zeni required to upgrade a memento with this memento
['Enhancer EXP'] = data.en_exp, -- EXP given by this memento
['Enhancer trust'] = data.en_trust,
['Vision Clear Reward'] = getVCR(data),
['Gives unit'] = getUnitReward(data),
['Source'] = extra.source or 'Unreleased',
['Release dates'] = releaseDates and tostring(releaseDates) or nil,
['Global only'] = extra.glOnly and 'Yes' or nil,
['External links'] = '[http://www.alchemistcodedb.com/card/'..iname:gsub('_','-'):lower()..' AlchemistCodeDB]',
}
}
root:node(infobox)
if tonumber(data.type) and typeMap[tonumber(data.type)] then
cats[#cats+1] = typeMap[tonumber(data.type)] .. ' memento'
end
-- Body
-- Card Image + Flavor
root:tag('div'):addClass('responsive-img')
:css{
['margin'] = 'auto',
['display'] = 'flex',
['flex-direction'] = 'column',
['min-width'] = '300px',
}
:tag('div')
:wikitext('[[File:Game,ConceptCard,', data.icon, '.png|512px]]')
:done()
:tag('div'):addClass('flavor')
:css{
['max-width'] = '1024px',
['padding'] = '8px',
}
:wikitext(data.flavor)
:done()
h.printLeaderSkill(root, data.leader_skill)
-- mw.logObject(effects, 'effects')
-- TODO: Stats + Effects
h.printEffects(root, {
rare = data.rare,
lvmax = data.lvmax,
effects = effects,
})
-- Category
for i, cat in ipairs(cats) do
root:wikitext('[[Category:', cat, ']]')
end
-- TODO Implement http://cdn.alchemistcodedb.com/assets/big-card-frames-b34ac394d6035fb657d491b956e2c4764836b51b9361fccc4b31e722a27df510.png
return tostring(root)
end
local renderFuncs = {
Icon = render_memento_icon
}
local function renderTransclude(iname, args)
local type = mw.text.trim(args[1])
args[1] = iname
return (renderFuncs[type] or renderFuncs.Name)(args)
end
function p._main(iname, args)
if not args or args.isPage then
return renderPage(iname)
else
return renderTransclude(iname, args)
end
end
p.renderPage = renderPage
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {parentFirst = true})
return renderPage(args[1])
end
function h.printLeaderSkill(root, sk_iname)
if sk_iname == nil then return end
local skill = cargo.query{
tables = {'Skill', 'Loc = SkillName', 'Loc = SkillExpr'},
fields = {
'Skill.iname = iname',
'SkillName.value = name',
'SkillExpr.value = expr',
'Skill.type = type',
'Skill.eff_type = eff_type',
'Skill.target = target',
'Skill.cond = cond',
'Skill.timing = timing',
'Skill.t_buff = t_buff',
},
where = {
'Skill.server = "gl"',
'Skill.iname = "'..sk_iname..'"',
'SkillName.param = "name" AND SkillName.lang = "english"',
'SkillExpr.param = "expr" AND SkillExpr.lang = "english"',
},
join = {'Skill._pageName = SkillName._pageName', 'Skill._pageName = SkillExpr._pageName'},
}[1]
if not skill then return nil end
root:newline():tag('h2'):wikitext("Leader Skill")
root:newline():tag('h3'):wikitext(skill.name)
root:newline():tag('p'):wikitext(skill.expr)
skill.type = enums.ESkillType[tonumber(skill.type)]
skill.eff_type = enums.SkillEffectTypes[tonumber(skill.eff_type)]
skill.target = enums.ESkillTarget[tonumber(skill.target)]
skill.cond = enums.ESkillCondition[tonumber(skill.cond)]
skill.timing = enums.ESkillTiming[tonumber(skill.timing)]
if skill.t_buff then
local buff = cargo.query{
tables = {'Buff'},
fields = {
'iname',
},
where = {
'Buff.iname = "'..skill.t_buff..'"',
'Buff.server = "gl"',
},
}[1]
local buff_details = h.getBuffDetails(buff.iname) or {}
-- mw.logObject(buff_details)
if #buff_details > 0 then
local tbl = root:newline():tag('table'):addClass('wikitable')
tbl:newline():tag('caption'):wikitext('Target Buff ('..skill.target..') ('..skill.cond..')')
tbl:newline():tag('tr'):tag('th'):attr('colspan', 3):wikitext('Stats')
tbl:newline():tag('tr')
:tag('th'):wikitext('Type'):done()
:tag('th'):wikitext('Min'):done()
:tag('th'):wikitext('Max'):done()
for i, buff in ipairs(buff_details) do
local tr = tbl:newline():tag('tr')
local fmt = yesno(buff.calc) and '%+d%%' or '%+d'
local statName = enums.statNameFromType(buff.type, buff.tktag)
tr:tag('th'):wikitext(statName)
tr:tag('td'):wikitext(string.format(fmt, tonumber(buff.vini)))
tr:tag('td'):wikitext(string.format(fmt, tonumber(buff.vmax)))
if buff.tktag then
cats[#cats+1] = statName
end
end
end
local custom_targets = cargo.query{
tables = {
'Buff',
'Buff__custom_targets',
'CustomTarget',
},
fields = {
'CustomTarget.birth_id = birth_id', -- Integer
'CustomTarget.sex = sex', -- Integer
'CustomTarget.dark = dark', -- Integer
'CustomTarget.fire = fire', -- Integer
'CustomTarget.shine = shine', -- Integer
'CustomTarget.thunder = thunder', -- Integer
'CustomTarget.water = water', -- Integer
'CustomTarget.wind = wind', -- Integer
'CustomTarget.concept_card_groups = concept_card_groups', -- List of String
'CustomTarget.job_groups = job_groups', -- List of String
'CustomTarget.unit_groups = unit_groups', -- List of String
'CustomTarget.units = units', -- List of String
},
where = {
'Buff.iname = "'..skill.t_buff..'"',
'Buff.server = "gl"',
'CustomTarget.server = "gl"',
},
join = {
'Buff._ID = Buff__custom_targets._rowID',
'Buff__custom_targets._value = CustomTarget.iname',
},
}
for _, custom_target in ipairs(custom_targets) do
if custom_target.concept_card_groups then
local cards = cargo.query{
tables = {
'ConceptCardGroup',
'ConceptCardGroup__cards',
'ConceptCard',
'Pages',
},
fields = {
-- 'ConceptCard.iname = iname',
'ConceptCard.icon = icon',
-- Type
'ConceptCard.type = type', -- eCardType
'ConceptCard.rare = rare',
'Pages._pageName = PAGENAME',
},
where = {
'ConceptCardGroup.iname = "'..custom_target.concept_card_groups..'"',
'ConceptCardGroup.server = "gl"',
'ConceptCard.server = "gl"',
},
join = {
'ConceptCardGroup._ID = ConceptCardGroup__cards._rowID',
'ConceptCardGroup__cards._value = ConceptCard.iname',
'ConceptCard.iname = Pages.iname',
}
}
root:newline():tag('h4'):wikitext('Memento Group')
local ul = root:newline():tag('ul')
for _, card in ipairs(cards) do
mw.logObject(card, 'card')
-- local icon = ''
if card.PAGENAME then
local icon = string.format(
'[[File:Game,ConceptCardIcon,%s.png|32px|link=%s]] [[%s]]',
card.icon, card.PAGENAME, card.PAGENAME)
ul:newline():tag('li'):wikitext(icon)
end
end
end
end
end
end
function p.test(frame)
-- local root = mw.html.create()
-- h.printLeaderSkill(root, 'SK_LS_TS_ENVYRIA_CLOE_01')
-- mw.log(tostring(root))
return
-- p.renderPage('TS_SAGA_BIRGITTA_01') ..
p.renderPage('TS_GL_SIBLINGS_01')
end
return p
--</nowiki>