Module:Weapon
Documentation for this module may be created at Module:Weapon/doc
local p = {}
local utils = require("Module:Utils")
local constant = mw.loadJsonData("Module:Data/constant.json")
local weapon = mw.loadJsonData("Module:Data/weapon.json")
local resource = mw.loadJsonData("Module:Data/resource.json")
function p.createInfobox(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
local item = weapon[name]
local itemLevel = frame.args.levelOverride
if itemLevel == nil or itemLevel == "" then itemLevel = 30 end
local stats = p.createStats(item, itemLevel)
local str = {
WeaponName = name,
Description = item.description,
Class = item.type,
Subclass = item.subtype,
Level = itemLevel,
InstinctA = item.affinities.Instinct[2],
InstinctAVal = stats[item.affinities.Instinct[2]],
InstinctB = item.affinities.Instinct[1],
InstinctBVal = stats[item.affinities.Instinct[1]],
DisciplineA = item.affinities.Discipline[2],
DisciplineAVal = stats[item.affinities.Discipline[2]],
DisciplineB = item.affinities.Discipline[1],
DisciplineBVal = stats[item.affinities.Discipline[1]],
FocusA = item.affinities.Focus[2],
FocusAVal = stats[item.affinities.Focus[2]],
FocusB = item.affinities.Focus[1],
FocusBVal = stats[item.affinities.Focus[1]]
}
return frame:expandTemplate{title = 'Infobox weapon', args = str}
end
function p.getDescription(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
return weapon[name].description
end
function p.createAbility(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
local item = weapon[name]
local str = {
image = frame.args.image,
name = item.weaponAbility.name,
tags = frame.args.tags,
description = item.weaponAbility.description,
mods = frame.args.mods,
}
return frame:expandTemplate{title = 'Ability', args = str}
end
function p.createStats(item, itemLevel)
local scaling = (item.attributeAutoScalingData.PerLevelBudgetIncrement * (itemLevel - 1))
local total = 0
for k, v in pairs(item.attributes) do
total = total + v
end
local maxhealth = p.calculateMaxStat("Max Health", item.attributes["Max Health"] or 0, total, scaling)
local resilience = p.calculateMaxStat("Resilience", item.attributes["Resilience"] or 0, total, scaling)
local weaponpower = p.calculateMaxStat("Weapon Power", item.attributes["Weapon Power"] or 0, total, scaling)
local abilitypower = p.calculateMaxStat("Ability Power", item.attributes["Ability Power"] or 0, total, scaling)
local critrating = p.calculateMaxStat("Crit Rating", item.attributes["Crit Rating"] or 0, total, scaling)
local critpower = p.calculateMaxStat("Crit Power", item.attributes["Crit Power"] or 0, total, scaling)
local breakpower = p.calculateMaxStat("Break Power", item.attributes["Break Power"] or 0, total, scaling)
local physdefense = p.calculateMaxStat("Phys Defense", item.attributes["Phys Defense"] or 0, total, scaling)
local magdefense = p.calculateMaxStat("Mag Defense", item.attributes["Mag Defense"] or 0, total, scaling)
local leveledStats = {
["Max Health"] = maxhealth,
["Resilience"] = resilience,
["Weapon Power"] = weaponpower,
["Ability Power"] = abilitypower,
["Crit Rating"] = critrating,
["Crit Power"] = critpower,
["Break Power"] = breakpower,
["Phys Defense"] = physdefense,
["Mag Defense"] = magdefense
}
return leveledStats
end
function p.calculateMaxStat(stats, single, total, scaling)
single = single * 3.13 -- 1 + 75% (5-star Awakening) + 138% (Lv30 Accolade)
total = total * 3.13 -- 1 + 75% (5-star Awakening) + 138% (Lv30 Accolade)
local maxstat = math.floor((single/total) * (total + scaling) * constant.Stats[stats].ItemBudgetMultiplier * constant.Stats[stats].DisplayValueMultiplier + 0.5)
if maxstat == 0 then maxstat = "" end
return maxstat
end
function p.createMaxStats(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
local item = weapon[name]
local level = constant["Max Level"]
local temper = constant["Max Temper"]
local awakening = constant["Max Awakening"]
local scaling = (item.attributeAutoScalingData.PerLevelBudgetIncremteent * (level - 1)) + (item.attributeAutoScalingData.PerTemperBudgetIncrements * temper) + (item.attributeAutoScalingData.PerRankBudgetIncrements * awakening)
local total = 0
for k, v in pairs(item.attributes) do
total = total + v
end
local maxhealth = p.getMaxStats("Max Health", item.attributes["Max Health"] or 0, total, scaling)
local resilience = p.getMaxStats("Resilience", item.attributes["Resilience"] or 0, total, scaling)
local weaponpower = p.getMaxStats("Weapon Power", item.attributes["Weapon Power"] or 0, total, scaling)
local abilitypower = p.getMaxStats("Ability Power", item.attributes["Ability Power"] or 0, total, scaling)
local critrating = p.getMaxStats("Crit Rating", item.attributes["Crit Rating"] or 0, total, scaling)
local critpower = p.getMaxStats("Crit Power", item.attributes["Crit Power"] or 0, total, scaling)
local breakpower = p.getMaxStats("Break Power", item.attributes["Break Power"] or 0, total, scaling)
local physdefense = p.getMaxStats("Phys Defense", item.attributes["Phys Defense"] or 0, total, scaling)
local magdefense = p.getMaxStats("Mag Defense", item.attributes["Mag Defense"] or 0, total, scaling)
local str = "Max stats are derived from level " .. level .. ", " .. temper .. " tempers, awakening " .. awakening .. ", and 0% affinity."
str = str .. '\n<div class="row"><div class="col-lg-8">'
str = str .. '\n{| class="table" style="margin-top:0 !important"'
str = str .. '\n! ' .. (maxhealth == "" and 'style="opacity:0.5"' or '') .. ' | Max Health'
str = str .. '\n| ' .. maxhealth
str = str .. '\n! ' .. (abilitypower == "" and 'style="opacity:0.5"' or '') .. ' | Ability Power'
str = str .. '\n| ' .. abilitypower
str = str .. '\n! ' .. (breakpower == "" and 'style="opacity:0.5"' or '') .. ' | Break Power'
str = str .. '\n| ' .. breakpower
str = str .. '\n|-'
str = str .. '\n! ' .. (resilience == "" and 'style="opacity:0.5"' or '') .. ' | Resilience'
str = str .. '\n| ' .. resilience
str = str .. '\n! ' .. (critrating == "" and 'style="opacity:0.5"' or '') .. ' | Crit Rating'
str = str .. '\n| ' .. critrating
str = str .. '\n! ' .. (physdefense == "" and 'style="opacity:0.5"' or '') .. ' | Phys Defense'
str = str .. '\n| ' .. physdefense
str = str .. '\n|-'
str = str .. '\n! ' .. (weaponpower == "" and 'style="opacity:0.5"' or '') .. ' | Weapon Power'
str = str .. '\n| ' .. weaponpower
str = str .. '\n! ' .. (critpower == "" and 'style="opacity:0.5"' or '') .. ' | Crit Power'
str = str .. '\n| ' .. critpower
str = str .. '\n! ' .. (magdefense == "" and 'style="opacity:0.5"' or '') .. ' | Mag Defense'
str = str .. '\n| ' .. magdefense
str = str .. '\n|}</div></div>'
return str
end
function p.getMaxStats(stats, single, total, scaling)
local maxstats = math.floor((single/total) * (total + scaling) * constant.Stats[stats].ItemBudgetMultiplier * constant.Stats[stats].DisplayValueMultiplier + 0.5)
if maxstats == 0 then maxstats = "" end
return maxstats
end
function p.createData(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
local item = weapon[name]
local level = constant["Max Level"]
local temper = constant["Max Temper"]
local awakening = constant["Max Awakening"]
local scaling = (item.attributeAutoScalingData.PerLevelBudgetIncrement * (level - 1)) + (item.attributeAutoScalingData.PerTemperBudgetIncrements * temper) + (item.attributeAutoScalingData.PerRankBudgetIncrements * awakening)
local total = 0
for k, v in pairs(item.attributes) do
total = total + v
end
local echo = ""
-- for k, v in ipairs(item.echoSlot) do
-- if v.level <= level then
-- echo = echo .. v.level .. " || ".. frame:expandTemplate{title = 'Icon', args = {v.slot}} .. ", "
-- end
-- end
echo = echo:sub(1, -3)
local str = {
maxhealth = item.attributes["Max Health"] or "",
resilience = item.attributes["Resilience"] or "",
weaponpower = item.attributes["Weapon Power"] or "",
abilitypower = item.attributes["Ability Power"] or "",
critrating = item.attributes["Crit Rating"] or "",
critpower = item.attributes["Crit Power"] or "",
breakpower = item.attributes["Break Power"] or "",
physdefense = item.attributes["Phys Defense"] or "",
magdefense = item.attributes["Mag Defense"] or "",
affinitymaxhealth = "",
affinityresilience = "",
affinityweaponpower = "",
affinityabilitypower = "",
affinitycritrating = "",
affinitycritpower = "",
affinitybreakpower = "",
affinityphysdefense = "",
affinitymagdefense = "",
totalstats = total,
level = item.attributeAutoScalingData.PerLevelBudgetIncrement,
temper = item.attributeAutoScalingData.PerTemperBudgetIncrements,
awakening = item.attributeAutoScalingData.PerRankBudgetIncrements,
totalscaling = scaling,
echo = echo
}
for k, v in pairs(item.affinities.Instinct) do
if v == "Max Health" then str.affinitymaxhealth = "Instinct" end
if v == "Resilience" then str.affinityresilience = "Instinct" end
if v == "Weapon Power" then str.affinityweaponpower = "Instinct" end
if v == "Ability Power" then str.affinityabilitypower = "Instinct" end
if v == "Crit Rating" then str.affinitycritrating = "Instinct" end
if v == "Crit Power" then str.affinitycritpower = "Instinct" end
if v == "Break Power" then str.affinitybreakpower = "Instinct" end
if v == "Phys Defense" then str.affinityphysdefense = "Instinct" end
if v == "Mag Defense" then str.affinitymagdefense = "Instinct" end
end
for k, v in pairs(item.affinities.Discipline) do
if v == "Max Health" then str.affinitymaxhealth = "Discipline" end
if v == "Resilience" then str.affinityresilience = "Discipline" end
if v == "Weapon Power" then str.affinityweaponpower = "Discipline" end
if v == "Ability Power" then str.affinityabilitypower = "Discipline" end
if v == "Crit Rating" then str.affinitycritrating = "Discipline" end
if v == "Crit Power" then str.affinitycritpower = "Discipline" end
if v == "Break Power" then str.affinitybreakpower = "Discipline" end
if v == "Phys Defense" then str.affinityphysdefense = "Discipline" end
if v == "Mag Defense" then str.affinitymagdefense = "Discipline" end
end
for k, v in pairs(item.affinities.Focus) do
if v == "Max Health" then str.affinitymaxhealth = "Focus" end
if v == "Resilience" then str.affinityresilience = "Focus" end
if v == "Weapon Power" then str.affinityweaponpower = "Focus" end
if v == "Ability Power" then str.affinityabilitypower = "Focus" end
if v == "Crit Rating" then str.affinitycritrating = "Focus" end
if v == "Crit Power" then str.affinitycritpower = "Focus" end
if v == "Break Power" then str.affinitybreakpower = "Focus" end
if v == "Phys Defense" then str.affinityphysdefense = "Focus" end
if v == "Mag Defense" then str.affinitymagdefense = "Focus" end
end
return frame:expandTemplate{title = 'Weapon data', args = str}
end
function p.createCraftingTable(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
local item = weapon[name]
local total = {}
local str = {
basic = "",
expanded = "",
total = ""
}
local cat = {
unique = {},
rare = {},
common = {},
currency = {}
}
for k, v in ipairs(item.craftingRecipes) do
if v.name == "Gold" then
str.basic = str.basic .. frame:expandTemplate{title = 'Gold', args = {v.amount}} .. ", "
else
str.basic = str.basic .. frame:expandTemplate{title = 'Icon', args = {v.name, v.amount}} .. ", "
end
end
str.basic = str.basic:sub(1, -3)
for k, v in ipairs(item.craftingRecipes) do
if v.name == "Gold" then
str.expanded = str.expanded .. frame:expandTemplate{title = 'Gold', args = {v.amount}} .. ", "
else
str.expanded = str.expanded .. frame:expandTemplate{title = 'Icon', args = {v.name, v.amount}} .. ", "
end
if resource[v.name] ~= nil and resource[v.name].craftingRecipes ~= nil then
for k2, v2 in ipairs(resource[v.name].craftingRecipes) do
if total[v2.name] == nil then
total[v2.name] = v2.amount
else
total[v2.name] = total[v2.name] + v2.amount
end
if v2.name == "Gold" then
str.expanded = str.expanded .. 'class="subcraft" | ' .. frame:expandTemplate{title = 'Gold', args = {v2.amount}} .. ", "
else
str.expanded = str.expanded .. 'class="subcraft" | ' .. frame:expandTemplate{title = 'Icon', args = {v2.name, v2.amount}} .. ", "
end
end
else
if total[v.name] == nil then
total[v.name] = v.amount
else
total[v.name] = total[v.name] + v.amount
end
end
end
str.expanded = str.expanded:sub(1, -3)
for k, v in pairs(total) do
if resource[k].type == "Currency" then
cat.currency[k] = v
elseif string.find(k, "Spectra") then
cat.common[k] = v
elseif string.find(k, "Vestige") or string.find(k, "Essence") or string.find(k, "Recipe") then
cat.unique[k] = v
else
cat.rare[k] = v
end
end
local first = true
for k, v in pairs(cat.unique) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Rare resources</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
for k, v in pairs(cat.rare) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Rare resources</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
first = true
for k, v in pairs(cat.common) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Common resources</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
first = true
for k, v in pairs(cat.currency) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Currency</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
str.total = str.total:sub(1, -3)
return frame:expandTemplate{title = 'Crafting table', args = str}
end
function p.createAwakeningTable(frame)
local name = frame.args.name
if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
local item = weapon[name]
local total = {}
local str = {
[1] = "", [2] = "", [3] = "", [4] = "", [5] = "",
total = ""
}
local cat = {
unique = {},
rare = {},
common = {},
currency = {}
}
local tier = 1
for k, v in ipairs(item.awakening) do
for k2, v2 in ipairs(v) do
if v2.name == "Gold" then
str[tier] = str[tier] .. frame:expandTemplate{title = 'Currency', args = {"Gold", v2.amount}} .. ", "
else
str[tier] = str[tier] .. frame:expandTemplate{title = 'Icon', args = {v2.name, v2.amount}} .. ", "
end
if v2.recipe ~= nil then
for k3, v3 in ipairs(v2.recipe) do
if total[v3.name] == nil then
total[v3.name] = v3.amount
else
total[v3.name] = total[v3.name] + v3.amount
end
if v3.name == "Gold" then
str[tier] = str[tier] .. 'class="subcraft" | ' .. frame:expandTemplate{title = 'Currency', args = {"Gold", v3.amount}} .. ", "
else
str[tier] = str[tier] .. 'class="subcraft" | ' .. frame:expandTemplate{title = 'Icon', args = {v3.name, v3.amount}} .. ", "
end
end
else
if total[v2.name] == nil then
total[v2.name] = v2.amount
else
total[v2.name] = total[v2.name] + v2.amount
end
end
end
str[tier] = str[tier]:sub(1, -3)
tier = tier + 1
end
for k, v in pairs(total) do
if resource[k].type == "Currency" then
cat.currency[k] = v
elseif string.find(k, "Spectra") then
cat.common[k] = v
elseif string.find(k, "Vestige") or string.find(k, "Essence") or string.find(k, "Recipe") then
cat.unique[k] = v
else
cat.rare[k] = v
end
end
local first = true
for k, v in pairs(cat.unique) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Rare resources</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
for k, v in pairs(cat.rare) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Rare resources</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
first = true
for k, v in pairs(cat.common) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Common resources</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
first = true
for k, v in pairs(cat.currency) do
if first then
str.total = str.total .. "|-\n"
str.total = str.total .. '! colspan=3 | <div style="color:#5ba3d7;font-size:200%;font-weight:700;font-style:italic;margin:1rem">Currency</div>\n'
end
first = false
str.total = str.total .. "|-\n"
str.total = str.total .. "| " .. frame:expandTemplate{title = 'Icon', args = {k}} .. "\n"
str.total = str.total .. "| " .. v .. "\n"
str.total = str.total .. "| " .. resource[k].description .. "@@"
end
str.total = str.total:sub(1, -3)
return frame:expandTemplate{title = 'Awakening table', args = str}
end
return p