Module:BTD6 hero xp

Revision as of 03:57, 13 August 2026 by Polavux (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:BTD6 hero xp/doc

local p = {}
local mFloor = math.floor

local function RoundHalfUp(num)
	local floored = mFloor(num)
	
	return floored + ((num - floored >= 0.5) and 1 or 0)
end

function Main(curve)
	local levelReqs = { 180, 460, 1000, 1860, 3280, 5180, 8320, 9380, 13620, 16380, 14400, 16650, 14940, 16380, 17820, 19260, 20700, 16470, 17280 }
	local xpModifiers = { 1, 1.1, 1.2, 1.3, 1 * 1.1 * 1.05 * 1.08, 1.1 * 1.1 * 1.05 * 1.08, 1.2 * 1.1 * 1.05 * 1.08, 1.3 * 1.1 * 1.05 * 1.08 }
	
	local wikitable = {
		'<div class="hatnote">Note: the number of rounds to level up assumes the Hero was placed on round 1 and there are no other Heroes on the map.</div>\n{|class="wikitable" style="text-align:center"\n!rowspan="2"|Level!!rowspan="2"|XP required!!colspan="4"|Rounds to level up!!colspan="4"|Rounds to level up w/ [[File:BTD6_mk_MonkeyEducationIcon.png|x20px|link=Monkey Education]][[File:BTD6_mk_SelfTaughtHeroesIcon.png|x20px|link=Self Taught Heroes]][[File:BTD6_mk_MonkeysStrongerTogetherIcon.png|x20px|link=Monkeys Together Strong]][[File:BTD6_mk_EmpoweredHeroesIcon.png|x20px|link=Empowered Heroes]]\n|-\n![[Beginner]]!![[Intermediate]]!![[Advanced]]!![[Expert]]!![[Beginner]]!![[Intermediate]]!![[Advanced]]!![[Expert]]'
	}
	
	-- local functions to improve performance
	local lang = mw.language.new("en")
	local tInsert = table.insert
	local sFormat = string.format
	
	local xpLv3 = RoundHalfUp(640 * curve)
	
	local totalRequired = 0
	
	local totalXpDifference = {0, 0, 0, 0, xpLv3, xpLv3, xpLv3, xpLv3}
	local totalRoundsDifference = {0, 0, 0, 0, 0, 0, 0, 0}
	
	local function InsertRounds(index, req)
		local xp = 0
		local mult = xpModifiers[index]
		local totalXp = totalXpDifference[index]
		local totalRounds = totalRoundsDifference[index]
		
		while totalXp < req do
			totalRounds = totalRounds + 1
			
			if		totalRounds <= 20						then xp = (totalRounds * 20 + 20)
			elseif	totalRounds > 20 and totalRounds <= 50	then xp = (totalRounds * 40 - 380)
			else												 xp = (totalRounds * 90 - 2880) end
		
		    totalXp = totalXp + RoundHalfUp(xp * mult)
		end
		
		if totalRounds == 0 then tInsert(wikitable, '|—')
		else tInsert(wikitable, sFormat('|%i (%i)', totalRounds - totalRoundsDifference[index], totalRounds))
		end
		
		totalXpDifference[index] = totalXp
		totalRoundsDifference[index] = totalRounds
	end	
	
	for i, v in ipairs(levelReqs) do
		local req = RoundHalfUp(v * curve)
		totalRequired = totalRequired + req
		tInsert(wikitable, sFormat('|-\n!%i\n|%s (%s)', i + 1, lang:formatNum(req), lang:formatNum(totalRequired)))
		
		InsertRounds(1, totalRequired)
		InsertRounds(2, totalRequired)
		InsertRounds(3, totalRequired)
		InsertRounds(4, totalRequired)
		InsertRounds(5, totalRequired)
		InsertRounds(6, totalRequired)
		InsertRounds(7, totalRequired)
		InsertRounds(8, totalRequired)
	end
	
	tInsert(wikitable, '|}')
	
	return table.concat(wikitable, '\n')
end

function p.main(frame)
	return Main(tonumber(frame.args[1]))
end

return p