Module:CalculatedStats: Difference between revisions

Jump to navigation Jump to search
No edit summary
No edit summary
 
(27 intermediate revisions by the same user not shown)
Line 1: Line 1:
--For calculated stats in SMT1, SMT2, SMTif, SMT Devil Summoner
--For calculated stats in SMT1, SMT2, SMTif, SMT Devil Summoner
--To do:
--To do:
--Mega-CD SMT1; it seems to have different formulas depending on if it is a boss or normal demon
--Fix Mega-CD SMT1
--Verify formulas (esp. Soul Hackers)
--Fix Soul Hackers
--Sources:
--Add Persona 2: Eternal Punishment (formulas unknown)
--https://w.atwiki.jp/shinmegamitensei1/pages/449.html#id_abe440aa
--Add Shin Megami Tensei: Nine (formulas unknown)
--https://w.atwiki.jp/shinmegamitensei1/pages/61.html
--https://w.atwiki.jp/shinmegamitensei2/pages/703.html#id_abe440aa
--https://w.atwiki.jp/devilsummoner/pages/115.html
--https://szsk.github.io/data/sh/system/battle/parameter.html


local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
Line 17: Line 13:
end
end


local function outputCells(stat1,stat2,stat3,stat4,stat5,stat6)
local function outputCells6(stat1,stat2,stat3,stat4,stat5,stat6)
return string.format("| %s\n| %s\n| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4,stat5,stat6)
return string.format("| %s\n| %s\n| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4,stat5,stat6)
end
local function outputCells4(stat1,stat2,stat3,stat4)
return string.format("| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4)
end
local function outputCells7(stat1,stat2,stat3,stat4,stat5,stat6,stat7)
return string.format("| %s\n| %s\n| %s\n| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4,stat5,stat6,stat7)
end
end


function p.smt1(frame)
function p.smt1(frame)
local args = getArgs(frame)
local args = getArgs(frame)
if args["platform"] then
if string.lower(args["platform"]) == "mcd" then
return p.smt1mcd(frame)
end
end
local level = args[1] --Level
local level = args[1] --Level
local strength = args[2] --Strength
local strength = args[2] --Strength
Line 39: Line 48:
mefc = intelligence + round(magic / 8)
mefc = intelligence + round(magic / 8)
}
}
return outputCells(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"])
local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
local additionalOutput = ""
for i, stat in ipairs(stats) do --Manual override
if args[stat] then
statTable[stat] = args[stat]
additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
end
end
return outputCells6(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"]) .. additionalOutput
end
end


Line 52: Line 70:
local luck = args[7] --Luck
local luck = args[7] --Luck
local levelMinus20 = math.max(level - 20,0)
local levelMinus20 = math.max(level - 20,0)
local isBoss = false
if args["boss"] then
isBoss = true
end
local statTable = {
local statTable = {
atk = levelMinus20 + (strength * 3) + math.floor(vitality / 4),
atk = levelMinus20 + (strength * 3) + math.floor(vitality / 4),
acc = math.floor(strength / 8) + agility + math.floor(luck / 10), --Incorrect
acc = math.floor(vitality / 4) + agility,
def = math.floor(levelMinus20 / 2) + math.floor(strength / 4) + (vitality * 3),
def = math.floor(levelMinus20 / 2) + math.floor(strength / 4) + (vitality * 3),
eva = math.floor(intelligence / 8) + agility,
eva = round(intelligence / 8) + agility,
matk = math.floor(intelligence / 8) + magic,
matk = round(intelligence / 8) + magic,
mefc = intelligence + math.floor(magic / 8)
mefc = intelligence + round(magic / 8)
}
}
if isBoss then
statTable["atk"] = levelMinus20 + 1 + (strength * 3) + round(vitality / 4)
statTable["acc"] = round(strength / 4) + agility
statTable["def"] = math.floor((levelMinus20 + 1) / 2) + math.floor(strength / 4) + (vitality * 2)
statTable["eva"] = math.floor(intelligence / 8) + agility
statTable["matk"] = math.floor(intelligence / 8) + magic
statTable["mefc"] = intelligence + math.floor(magic / 8)
end
local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
for i, stat in ipairs(stats) do
local additionalOutput = ""
for i, stat in ipairs(stats) do --Manual override
if args[stat] then
if args[stat] then
statTable[stat] = args[stat]
additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
end
end
end
end
return outputCells(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"])
return outputCells6(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"]) .. additionalOutput
end
end


Line 86: Line 117:
mefc = intelligence + math.floor(magic / 4)
mefc = intelligence + math.floor(magic / 4)
}
}
return outputCells(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"])
local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
local additionalOutput = ""
for i, stat in ipairs(stats) do --Add category
if args[stat] then
additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
end
end
return outputCells6(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"]) .. additionalOutput
end
end


function p.smtif(frame)
p.smtif = p.smt2
return p.smt2(frame)
end


function p.desum(frame)
function p.desum(frame)
Line 103: Line 139:
local luck = args[7] --Luck
local luck = args[7] --Luck
local platform = ""
local platform = ""
if args[8] then
if args["platform"] then
platform = string.lower(args[8]) --game platform
platform = string.lower(args["platform"]) --game platform
end
end
local statTable = {
local statTable = {
Line 113: Line 149:
matk = math.floor(intelligence / 2) + (magic * 2),
matk = math.floor(intelligence / 2) + (magic * 2),
mdef = intelligence + math.floor(level / 2) + math.floor(magic / 4) + math.floor(endurance / 2),
mdef = intelligence + math.floor(level / 2) + math.floor(magic / 4) + math.floor(endurance / 2),
accPSP = math.floor((level * 1.5) + agility + (strength + luck) / 4),
evaPSP = math.floor((level * 1.5) + agility + (intelligence + luck) / 4),
matkPSP = math.floor((intelligence / 2) + (magic * 2)),
mdefPSP = math.floor(intelligence + (level / 2) + (magic / 4) + (endurance / 2))
mdefPSP = math.floor(intelligence + (level / 2) + (magic / 4) + (endurance / 2))
}
}
Line 124: Line 157:
return statTable[stat]
return statTable[stat]
else
else
return frame:expandTemplate{ title = "tt", args = { statTable[stat], "Sega Saturn" } } .. " / " .. frame:expandTemplate{ title = "tt", args = { statTable[stat.."PSP"], "PlayStation Portable" } }
return frame:expandTemplate{ title = "tt", args = { statTable[stat], "Sega Saturn" } } .. "/" .. frame:expandTemplate{ title = "tt", args = { statTable[stat.."PSP"], "PlayStation Portable" } }
end
end
local stats = { "atk", "acc", "def", "eva", "matk", "mdef" }
local additionalOutput = ""
for i, stat in ipairs(stats) do --Add category
if args[stat] then
additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
end
end
end
end
local outputAtk = statTable["atk"]
local outputAtk = statTable["atk"]
local outputAcc = bothPlatsValue("acc")
local outputAcc = statTable["acc"]
local outputDef = statTable["def"]
local outputDef = statTable["def"]
local outputEva = bothPlatsValue("eva")
local outputEva = statTable["eva"]
local outputMatk = bothPlatsValue("matk")
local outputMatk = statTable["matk"]
local outputMdef = bothPlatsValue("mdef")
local outputMdef = bothPlatsValue("mdef")


return outputCells(outputAtk,outputAcc,outputDef,outputEva,outputMatk,outputMdef)
return outputCells6(outputAtk,outputAcc,outputDef,outputEva,outputMatk,outputMdef) .. additionalOutput
end
end


Line 147: Line 187:
local luck = args[7] --Luck
local luck = args[7] --Luck
local statTable = {
local statTable = {
patk = (level + strength) * 2,
patk = (level + strength) * 2, --Seems good
phit = math.floor(level * 1.5) + math.floor(agility * 1.2) + math.floor(luck * 0.6),
phit = math.floor(level * 1.5) + math.floor(agility * 1.2) + math.floor(luck * 0.6), --Needs work
matk = intelligence * 2 + math.floor(magic * 7.5),
matk = intelligence * 2 + math.floor(magic * 7.5), --Needs work
mhit = intelligence * 2 + math.floor(magic / 2) * 2,
mhit = intelligence * 2 + math.floor(magic / 2) * 2, --Seems good
def = (level + endurance) * 2 + 16,
def = (level + endurance) * 2 + 16, --Seems good
eva = math.floor(level * 1.5) + agility + math.floor(luck / 2)
eva = math.floor(level * 1.5) + agility + math.floor(luck / 2) --Seems good
}
}
local stats = { "patk", "phit", "matk", "mhit", "def", "eva" }
local stats = { "patk", "phit", "matk", "mhit", "def", "eva" }
for i, stat in ipairs(stats) do
local additionalOutput = ""
for i, stat in ipairs(stats) do --Manual override
if args[stat] then
statTable[stat] = args[stat]
additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
end
end
return outputCells6(statTable["patk"],statTable["phit"],statTable["matk"],statTable["mhit"],statTable["def"],statTable["eva"]) .. additionalOutput
end
 
function p.p2is(frame)
local args = getArgs(frame)
local level = args[1] --Level
local strength = args[2] --Strength
local vitality = args[3] --Vitality
local dexterity = args[4] --Dexterity
local agility = args[5] --Agility
local luck = args[6] --Luck
local platform = ""
if args["platform"] then
platform = string.lower(args["platform"]) --game platform
end
local statTable = {
atk = (level + strength) * 2,
def = (level + vitality) * 2,
matk = dexterity * 2 + math.floor(level * 0.8),
mdef = math.floor(dexterity * 2.5) + math.floor(vitality / 2),
atkPSP = math.floor(0.7 * ((level + strength) * 2)),
defPSP = math.floor(0.8 * ((level + vitality) * 2)),
matkPSP = math.floor(0.7 * (dexterity * 2 + math.floor(level * 0.8))),
mdefPSP = math.floor(0.8 * (math.floor(dexterity * 2.5) + math.floor(vitality / 2)))
}
local function bothPlatsValue(stat)
if platform == "psp" then
return statTable[stat.."PSP"]
elseif platform == "ps" then
return statTable[stat]
else
return frame:expandTemplate{ title = "tt", args = { statTable[stat], "PlayStation" } } .. "/" .. frame:expandTemplate{ title = "tt", args = { statTable[stat.."PSP"], "PlayStation Portable" } }
end
end
local outputAtk = bothPlatsValue("atk")
local outputDef = bothPlatsValue("def")
local outputMatk = bothPlatsValue("matk")
local outputMdef = bothPlatsValue("mdef")
 
return outputCells4(outputAtk,outputDef,outputMatk,outputMdef)
end
 
function p.smtn(frame)
local args = getArgs(frame)
local level = args[1] --Level
local strength = args[2] --Strength
local intelligence = args[3] --Intelligence
local magic = args[4] --Magic
local vitality = args[5] --Vitality
local agility = args[6] --Agility
local luck = args[7] --Luck
local statTable = {
atk = (level + strength) * 2, --Good
acc = math.floor(level * 1.5) + agility + math.floor(luck / 2), --Somewhat close
pdef = (level + vitality) * 2 + 16, --Good
peva = math.floor(level * 1.5) + agility + math.floor(luck / 2), --Unknown; need more data
matk = level + math.floor(intelligence / 3) + magic * 3, --Very close
msuc = intelligence + math.floor(magic / 2), --Good
mdef = level + vitality + intelligence * 2 + math.floor(magic/4) --Good
}
local stats = { "atk", "acc", "pdef", "peva", "matk", "msuc", "mdef" }
local additionalOutput = ""
for i, stat in ipairs(stats) do --Manual override
if args[stat] then
if args[stat] then
statTable[stat] = args[stat]
statTable[stat] = args[stat]
additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
end
end
end
end
return outputCells(statTable["patk"],statTable["phit"],statTable["matk"],statTable["mhit"],statTable["def"],statTable["eva"])
return outputCells7(statTable["atk"],statTable["acc"],statTable["pdef"],statTable["peva"],statTable["matk"],statTable["msuc"],statTable["mdef"]) .. additionalOutput
end
end


return p
return p

Latest revision as of 22:37, 28 September 2024

Documentation

Basic use

To use this module, do as follows for most games:

{{#invoke:CalculatedStats|<function>|<level>|<strength>|<intelligence>|<magic>|<vitality/endurance>|<agility>|<luck>}}

For Persona 2: Innocent Sin, do as follows for basic use:

{{#invoke:CalculatedStats|<function>|<level>|<strength>|<vitality>|<dexterity>|<agility>|<luck>}}

This module should not be invoked directly in the mainspace and should be part of a template, with the values filled with template parameters.

Valid values for function (case sensitive):

  • smt1 for Shin Megami Tensei
  • smt2 for Shin Megami Tensei II
  • smtif for Shin Megami Tensei if... (alias for smt2)
  • smtn for Shin Megami Tensei: Nine
  • desum for Shin Megami Tensei: Devil Summoner
  • sh1 for Devil Summoner: Soul Hackers
  • p2is for Persona 2: Innocent Sin

Platform

Shin Megami Tensei has different formulas for the Mega-CD version. Set the named parameter platform to MCD (case insensitive) to output the Mega-CD stats.

Shin Megami Tensei: Devil Summoner by default shows both the Sega Saturn and PlayStation Portable values for Magic Defense. Set the named parameter platform to either SAT or PSP (case insensitive) to display only one of them.

Persona 2: Innocent Sin is similar to Devil Summoner but it applies for all stats. Set the named parameter platform to PS or PSP to show only one platform's set of stats.

Boss

Shin Megami Tensei (Mega-CD) uses different stat calculations for bosses than it does for regular demons. Set the named parameter boss to something (recommended: y) to use the boss calculations.

Manual stat inputting

Devil Summoner: Soul Hackers and Shin Megami Tensei: Nine support manual input of stats through named arguments (see the code to know what to use). This is because some of the calculations for Devil Summoner: Soul Hackers and Shin Megami Tensei: Nine are not yet perfect.

Sources

All sources were verified and, if they were wrong, corrected formulas are used in this module.


--For calculated stats in SMT1, SMT2, SMTif, SMT Devil Summoner
--To do:
	--Fix Mega-CD SMT1
	--Fix Soul Hackers
	--Add Persona 2: Eternal Punishment (formulas unknown)
	--Add Shin Megami Tensei: Nine (formulas unknown)

local getArgs = require('Module:Arguments').getArgs
local p = {}

local function round(number)
	return math.floor(number + 0.5)
end

local function outputCells6(stat1,stat2,stat3,stat4,stat5,stat6)
	return string.format("| %s\n| %s\n| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4,stat5,stat6)
end

local function outputCells4(stat1,stat2,stat3,stat4)
	return string.format("| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4)
end

local function outputCells7(stat1,stat2,stat3,stat4,stat5,stat6,stat7)
	return string.format("| %s\n| %s\n| %s\n| %s\n| %s\n| %s\n| %s",stat1,stat2,stat3,stat4,stat5,stat6,stat7)
end

function p.smt1(frame)
	local args = getArgs(frame)
	if args["platform"] then
		if string.lower(args["platform"]) == "mcd" then
			return p.smt1mcd(frame)
		end
	end
	local level = args[1] --Level
	local strength = args[2] --Strength
	local intelligence = args[3] --Intelligence
	local magic = args[4] --Magic
	local vitality = args[5] --Vitality
	local agility = args[6] --Agility
	local luck = args[7] --Luck
	local levelMinus19 = math.max(level - 19,0)
	local statTable = {
		atk = levelMinus19 + (strength * 3) + round(vitality / 4),
		acc = round(strength / 4) + agility,
		def = round(levelMinus19 / 2) + round(strength / 4) + (vitality * 2),
		eva = round(intelligence / 8) + agility,
		matk = round(intelligence / 8) + magic,
		mefc = intelligence + round(magic / 8)
	}
	local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
	local additionalOutput = ""
	for i, stat in ipairs(stats) do --Manual override
		if args[stat] then
			statTable[stat] = args[stat]
			additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
		end
	end
	
	return outputCells6(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"]) .. additionalOutput
end

function p.smt1mcd(frame)
	local args = getArgs(frame)
	local level = args[1] --Level
	local strength = args[2] --Strength
	local intelligence = args[3] --Intelligence
	local magic = args[4] --Magic
	local vitality = args[5] --Vitality
	local agility = args[6] --Agility
	local luck = args[7] --Luck
	local levelMinus20 = math.max(level - 20,0)
	local isBoss = false
	if args["boss"] then
		isBoss = true
	end
	local statTable = {
		atk = levelMinus20 + (strength * 3) + math.floor(vitality / 4),
		acc = math.floor(vitality / 4) + agility,
		def = math.floor(levelMinus20 / 2) + math.floor(strength / 4) + (vitality * 3),
		eva = round(intelligence / 8) + agility,
		matk = round(intelligence / 8) + magic,
		mefc = intelligence + round(magic / 8)
	}
	if isBoss then
		statTable["atk"] = levelMinus20 + 1 + (strength * 3) + round(vitality / 4)
		statTable["acc"] = round(strength / 4) + agility
		statTable["def"] = math.floor((levelMinus20 + 1) / 2) + math.floor(strength / 4) + (vitality * 2)
		statTable["eva"] = math.floor(intelligence / 8) + agility
		statTable["matk"] = math.floor(intelligence / 8) + magic
		statTable["mefc"] = intelligence + math.floor(magic / 8)
	end
	local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
	local additionalOutput = ""
	for i, stat in ipairs(stats) do --Manual override
		if args[stat] then
			additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
		end
	end
	return outputCells6(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"]) .. additionalOutput
end

function p.smt2(frame)
	local args = getArgs(frame)
	local level = args[1] --Level
	local strength = args[2] --Strength
	local intelligence = args[3] --Intelligence
	local magic = args[4] --Magic
	local vitality = args[5] --Vitality
	local agility = args[6] --Agility
	local luck = args[7] --Luck
	local statTable = {
		atk = (level + strength) * 2,
		acc = math.floor(level * 1.5) + agility + math.floor((strength + luck) / 4),
		def = (level + vitality) * 2,
		eva = math.floor(level * 1.5) + agility + math.floor((intelligence + luck) / 4),
		matk = math.floor(intelligence / 4) + magic,
		mefc = intelligence + math.floor(magic / 4)
	}
	local stats = { "atk", "acc", "def", "eva", "matk", "mefc" }
	local additionalOutput = ""
	for i, stat in ipairs(stats) do --Add category
		if args[stat] then
			additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
		end
	end
	return outputCells6(statTable["atk"],statTable["acc"],statTable["def"],statTable["eva"],statTable["matk"],statTable["mefc"]) .. additionalOutput
end

p.smtif = p.smt2

function p.desum(frame)
	local args = getArgs(frame)
	local level = args[1] --Level
	local strength = args[2] --Strength
	local intelligence = args[3] --Intelligence
	local magic = args[4] --Magic
	local endurance = args[5] --Endurance
	local agility = args[6] --Agility
	local luck = args[7] --Luck
	local platform = ""
	if args["platform"] then
		platform = string.lower(args["platform"]) --game platform
	end
	local statTable = {
		atk = (level + strength) * 2,
		acc = math.floor(level * 1.5) + agility + math.floor((strength + luck) / 4),
		def = (level + endurance) * 2,
		eva = math.floor(level * 1.5) + agility + math.floor((intelligence + luck) / 4),
		matk = math.floor(intelligence / 2) + (magic * 2),
		mdef = intelligence + math.floor(level / 2) + math.floor(magic / 4) + math.floor(endurance / 2),
		mdefPSP = math.floor(intelligence + (level / 2) + (magic / 4) + (endurance / 2))
	}
	local function bothPlatsValue(stat)
		if platform == "psp" then
			return statTable[stat.."PSP"]
		elseif platform == "sat" or statTable[stat] == statTable[stat.."PSP"] then
			return statTable[stat]
		else
			return frame:expandTemplate{ title = "tt", args = { statTable[stat], "Sega Saturn" } } .. "/" .. frame:expandTemplate{ title = "tt", args = { statTable[stat.."PSP"], "PlayStation Portable" } }
		end
	end
	local stats = { "atk", "acc", "def", "eva", "matk", "mdef" }
	local additionalOutput = ""
	for i, stat in ipairs(stats) do --Add category
		if args[stat] then
			additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
		end
	end
	local outputAtk = statTable["atk"]
	local outputAcc = statTable["acc"]
	local outputDef = statTable["def"]
	local outputEva = statTable["eva"]
	local outputMatk = statTable["matk"]
	local outputMdef = bothPlatsValue("mdef")

	return outputCells6(outputAtk,outputAcc,outputDef,outputEva,outputMatk,outputMdef) .. additionalOutput
end

function p.sh1(frame)
	local args = getArgs(frame)
	local level = args[1] --Level
	local strength = args[2] --Strength
	local intelligence = args[3] --Intelligence
	local magic = args[4] --Magic
	local endurance = args[5] --Endurance
	local agility = args[6] --Agility
	local luck = args[7] --Luck
	local statTable = {
		patk = (level + strength) * 2, --Seems good
		phit = math.floor(level * 1.5) + math.floor(agility * 1.2) + math.floor(luck * 0.6), --Needs work
		matk = intelligence * 2 + math.floor(magic * 7.5), --Needs work
		mhit = intelligence * 2 + math.floor(magic / 2) * 2, --Seems good
		def = (level + endurance) * 2 + 16, --Seems good
		eva = math.floor(level * 1.5) + agility + math.floor(luck / 2) --Seems good
	}
	local stats = { "patk", "phit", "matk", "mhit", "def", "eva" }
	local additionalOutput = ""
	for i, stat in ipairs(stats) do --Manual override
		if args[stat] then
			statTable[stat] = args[stat]
			additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
		end
	end
	return outputCells6(statTable["patk"],statTable["phit"],statTable["matk"],statTable["mhit"],statTable["def"],statTable["eva"]) .. additionalOutput
end

function p.p2is(frame)
	local args = getArgs(frame)
	local level = args[1] --Level
	local strength = args[2] --Strength
	local vitality = args[3] --Vitality
	local dexterity = args[4] --Dexterity
	local agility = args[5] --Agility
	local luck = args[6] --Luck
	local platform = ""
	if args["platform"] then
		platform = string.lower(args["platform"]) --game platform
	end
	local statTable = {
		atk = (level + strength) * 2,
		def = (level + vitality) * 2,
		matk = dexterity * 2 + math.floor(level * 0.8),
		mdef = math.floor(dexterity * 2.5) + math.floor(vitality / 2),
		atkPSP = math.floor(0.7 * ((level + strength) * 2)),
		defPSP = math.floor(0.8 * ((level + vitality) * 2)),
		matkPSP = math.floor(0.7 * (dexterity * 2 + math.floor(level * 0.8))),
		mdefPSP = math.floor(0.8 * (math.floor(dexterity * 2.5) + math.floor(vitality / 2)))
	}
	local function bothPlatsValue(stat)
		if platform == "psp" then
			return statTable[stat.."PSP"]
		elseif platform == "ps" then
			return statTable[stat]
		else
			return frame:expandTemplate{ title = "tt", args = { statTable[stat], "PlayStation" } } .. "/" .. frame:expandTemplate{ title = "tt", args = { statTable[stat.."PSP"], "PlayStation Portable" } }
		end
	end
	local outputAtk = bothPlatsValue("atk")
	local outputDef = bothPlatsValue("def")
	local outputMatk = bothPlatsValue("matk")
	local outputMdef = bothPlatsValue("mdef")

	return outputCells4(outputAtk,outputDef,outputMatk,outputMdef)
end

function p.smtn(frame)
	local args = getArgs(frame)
	local level = args[1] --Level
	local strength = args[2] --Strength
	local intelligence = args[3] --Intelligence
	local magic = args[4] --Magic
	local vitality = args[5] --Vitality
	local agility = args[6] --Agility
	local luck = args[7] --Luck
	local statTable = {
		atk = (level + strength) * 2, --Good
		acc = math.floor(level * 1.5) + agility + math.floor(luck / 2), --Somewhat close
		pdef = (level + vitality) * 2 + 16, --Good
		peva = math.floor(level * 1.5) + agility + math.floor(luck / 2), --Unknown; need more data
		matk = level + math.floor(intelligence / 3) + magic * 3, --Very close
		msuc = intelligence + math.floor(magic / 2), --Good
		mdef = level + vitality + intelligence * 2 + math.floor(magic/4) --Good
	}
	local stats = { "atk", "acc", "pdef", "peva", "matk", "msuc", "mdef" }
	local additionalOutput = ""
	for i, stat in ipairs(stats) do --Manual override
		if args[stat] then
			statTable[stat] = args[stat]
			additionalOutput = "[[Category:Pages with manually input calcuated stats]]"
		end
	end
	return outputCells7(statTable["atk"],statTable["acc"],statTable["pdef"],statTable["peva"],statTable["matk"],statTable["msuc"],statTable["mdef"]) .. additionalOutput
end

return p