Module:BTD6 hero xp: Difference between revisions

From Blooncyclopedia, the independent Bloons knowledge base
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
 
(15 intermediate revisions by 2 users not shown)
Line 1: Line 1:
-- This code is copyrighted and available under the Creative Commons Attribution-NonCommercial-ShareAlike International license, version 4.0. You may use and adapt this code if:
-- * You give appropriate credit
-- * You are not using this material for commercial purposes
-- * You are releasing it under the same license
-- Further information: https://www.bloonswiki.com/Blooncyclopedia:Copyrights
-- By editing this code, you agree to release your changes under the same terms.
local p = {}
local p = {}
local lang = mw.language.new("en")
local mFloor = math.floor


local level_reqs = { 180, 460, 1000, 1860, 3280, 5180, 8320, 9380, 13620, 16380, 14400, 16650, 14940, 16380, 17820, 19260, 20700, 16470, 17280 }
local function RoundHalfUp(num)
local difficulty_modifiers = { 1, 1.1, 1.2, 1.3 }
local floored = mFloor(num)
return floored + ((num - floored >= 0.5) and 1 or 0)
end


function p.main(frame)
function _main(curve)
local level_reqs = { 180, 460, 1000, 1860, 3280, 5180, 8320, 9380, 13620, 16380, 14400, 16650, 14940, 16380, 17820, 19260, 20700, 16470, 17280 }
local xp_modifiers = { 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 = {
local wikitable = {
'{|class="wikitable" style="text-align:center;display:inline-table"\n!rowspan="2"|Level!!rowspan="2"|XP required!!colspan="4"|<abbr title="if placed on round 1">Rounds to reach level</abbr>\n|-\n![[Beginner]]!![[Intermediate]]!![[Advanced]]!![[Expert]]'
'<div class="hatnote">Note: the number of rounds to level up assumes the Hero is placed on round 1 and no other Heroes are placed.</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 curve = tonumber(frame.args[1])
-- local functions to improve performance
local tinsert = table.insert
local sformat = string.format
local xp_lv3 = RoundHalfUp(640 * curve)
local total_required = 0
local total_required = 0
local total_xp_diff = {0, 0, 0, 0}
local total_xp_diff = {0, 0, 0, 0, xp_lv3, xp_lv3, xp_lv3, xp_lv3}
local total_rounds_diff = {0, 0, 0, 0}
local total_rounds_diff = {0, 0, 0, 0, 0, 0, 0, 0}
local function insert_rounds(index, req)
local function insert_rounds(index, req)
local xp = 0
local xp = 0
local mult = difficulty_modifiers[index]
local mult = xp_modifiers[index]
local total_xp = total_xp_diff[index]
local total_xp = total_xp_diff[index]
local total_rounds = total_rounds_diff[index]
local total_rounds = total_rounds_diff[index]
Line 26: Line 45:
if total_rounds <= 20 then xp = (total_rounds * 20 + 20)
if total_rounds <= 20 then xp = (total_rounds * 20 + 20)
elseif total_rounds > 20 and total_rounds <= 50 then xp = (total_rounds * 50 - 380)
elseif total_rounds > 20 and total_rounds <= 50 then xp = (total_rounds * 40 - 380)
else xp = (total_rounds * 90 - 2880) end
else xp = (total_rounds * 90 - 2880) end
total_xp = total_xp + (xp * mult)
    -- Check if it is a perfect half tie-breaker
    total_xp = total_xp + RoundHalfUp(xp * mult)
end
end
table.insert(wikitable, string.format('|%i (%i)', total_rounds - total_rounds_diff[index], total_rounds))
if total_rounds == 0 then tinsert(wikitable, '|—')
else tinsert(wikitable, sformat('|%i (%i)', total_rounds - total_rounds_diff[index], total_rounds))
end
total_xp_diff[index] = total_xp
total_xp_diff[index] = total_xp
Line 40: Line 61:
for i, v in ipairs(level_reqs) do
for i, v in ipairs(level_reqs) do
local req = math.floor(v * curve)
local req = RoundHalfUp(v * curve)
total_required = total_required + req
total_required = total_required + req
table.insert(wikitable, string.format('|-\n!%i\n|%i (%i)', i + 1, req, total_required))
tinsert(wikitable, sformat('|-\n!%i\n|%s (%s)', i + 1, lang:formatNum(req), lang:formatNum(total_required)))
insert_rounds(1, total_required)
insert_rounds(1, total_required)
Line 48: Line 69:
insert_rounds(3, total_required)
insert_rounds(3, total_required)
insert_rounds(4, total_required)
insert_rounds(4, total_required)
insert_rounds(5, total_required)
insert_rounds(6, total_required)
insert_rounds(7, total_required)
insert_rounds(8, total_required)
end
end
table.insert(wikitable, '|}')
tinsert(wikitable, '|}')
return table.concat(wikitable, '\n')
return table.concat(wikitable, '\n')
end
function p.main(frame)
return _main(tonumber(frame.args[1]))
end
end


return p
return p

Latest revision as of 23:33, 3 June 2026

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

-- This code is copyrighted and available under the Creative Commons Attribution-NonCommercial-ShareAlike International license, version 4.0. You may use and adapt this code if:
-- * You give appropriate credit
-- * You are not using this material for commercial purposes
-- * You are releasing it under the same license
-- Further information: https://www.bloonswiki.com/Blooncyclopedia:Copyrights
-- By editing this code, you agree to release your changes under the same terms.

local p = {}
local lang = mw.language.new("en")
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 level_reqs = { 180, 460, 1000, 1860, 3280, 5180, 8320, 9380, 13620, 16380, 14400, 16650, 14940, 16380, 17820, 19260, 20700, 16470, 17280 }
	local xp_modifiers = { 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 is placed on round 1 and no other Heroes are placed.</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 tinsert = table.insert
	local sformat = string.format
	
	local xp_lv3 = RoundHalfUp(640 * curve)
	
	local total_required = 0
	
	local total_xp_diff = {0, 0, 0, 0, xp_lv3, xp_lv3, xp_lv3, xp_lv3}
	local total_rounds_diff = {0, 0, 0, 0, 0, 0, 0, 0}
	
	local function insert_rounds(index, req)
		local xp = 0
		local mult = xp_modifiers[index]
		local total_xp = total_xp_diff[index]
		local total_rounds = total_rounds_diff[index]
		
		while total_xp < req do
			total_rounds = total_rounds + 1
			
			if		total_rounds <= 20							then xp = (total_rounds * 20 + 20)
			elseif	total_rounds > 20 and total_rounds <= 50	then xp = (total_rounds * 40 - 380)
			else													 xp = (total_rounds * 90 - 2880) end
		
		    -- Check if it is a perfect half tie-breaker
		    total_xp = total_xp + RoundHalfUp(xp * mult)
		end
		
		if total_rounds == 0 then tinsert(wikitable, '|—')
		else tinsert(wikitable, sformat('|%i (%i)', total_rounds - total_rounds_diff[index], total_rounds))
		end
		
		total_xp_diff[index] = total_xp
		total_rounds_diff[index] = total_rounds
	end	
	
	for i, v in ipairs(level_reqs) do
		local req = RoundHalfUp(v * curve)
		total_required = total_required + req
		tinsert(wikitable, sformat('|-\n!%i\n|%s (%s)', i + 1, lang:formatNum(req), lang:formatNum(total_required)))
		
		insert_rounds(1, total_required)
		insert_rounds(2, total_required)
		insert_rounds(3, total_required)
		insert_rounds(4, total_required)
		insert_rounds(5, total_required)
		insert_rounds(6, total_required)
		insert_rounds(7, total_required)
		insert_rounds(8, total_required)
	end
	
	tinsert(wikitable, '|}')
	
	return table.concat(wikitable, '\n')
end

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

return p