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
Cookies help us deliver our services. By using our services, you agree to our use of cookies.