Module:BTD6 stats: Difference between revisions

From Blooncyclopedia, the independent Bloons knowledge base
Jump to navigation Jump to search
mNo edit summary
changed to the new system
Line 11: Line 11:


local template_names = {
local template_names = {
attacks = "BTD6 attack",
attacks ="BTD6 attack",
projectiles = "BTD6 projectile",
projectiles ="BTD6 projectile",
abilities = "BTD6 ability",
collectables="BTD6 collectable",
effects = "BTD6 effect",
abilities ="BTD6 ability",
zones = "BTD6 zone",
effects ="BTD6 effect",
subtowers = "BTD6 tower",
buffs ="BTD6 buff",
buffs = "BTD6 buff"
zones ="BTD6 zone",
subtowers ="BTD6 tower"
}
}


Line 33: Line 34:
if type(v) == "table" and ssub(k, 1, 1) ~= "_" then
if type(v) == "table" and ssub(k, 1, 1) ~= "_" then
template[k] = {}
template[k] = {}
if prev_data[k] == nil then prev_data[k] = {} end
if prev_data[k] == nil then prev_data[k] = {} end
-- iterate through attacks/abilities/subtowers
-- iterate through attacks/abilities/subtowers
for kk, vv in pairs(v) do
for _, i in ipairs(v["_order"]) do
if k == "subtowers" then tinsert(template[k], sformat(header, kk)) end
if k == "subtowers" then tinsert(template[k], sformat(header, i)) end
if prev_data[k][kk] == nil then prev_data[k][kk] = {} end
if prev_data[k][i] == nil then prev_data[k][i] = {} end
-- parse sub-table of table
-- parse sub-table of table
tinsert(template[k], parse_stats(frame, kk, vv, prev_data[k][kk], template_names[k]))
tinsert(template[k], parse_stats(frame, i, v[i], prev_data[k][i], template_names[k]))
end
end
Line 78: Line 78:
-- iterate through attacks/abilities/subtowers
-- iterate through attacks/abilities/subtowers
for kk, vv in pairs(v) do
for _, i in ipairs(v["_order"]) do
if prev_data[k][kk] == nil then prev_data[k][kk] = {} end
if prev_data[k][i] == nil then prev_data[k][i] = {} end
-- parse sub-table of table
-- parse sub-table of table
tinsert(template[k], parse_stats(frame, kk, vv, prev_data[k][kk], template_names[k]))
tinsert(template[k], parse_stats(frame, i, v[i], prev_data[k][i], template_names[k]))
end
end
Line 116: Line 116:
if type(v) == "table" and ssub(k, 1, 1) ~= "_" then
if type(v) == "table" and ssub(k, 1, 1) ~= "_" then
if template[k] == nil then template[k] = {} end
if template[k] == nil then template[k] = {} end
if prev_data[k] == nil then prev_data[k] = {} end
if prev_data[k] == nil then prev_data[k] = {} end
-- iterate through attacks/abilities/subtowers
-- iterate through attacks/abilities/subtowers
for kk, vv in pairs(v) do
for _, i in ipairs(v["_order"]) do
if prev_data[k][kk] == nil then prev_data[k][kk] = {} end
if prev_data[k][i] == nil then prev_data[k][i] = {} end
-- parse sub-table of table
-- parse sub-table of table
parse_stats_full(frame, kk, vv, prev_data[k][kk], template_names[k])
parse_stats_full(frame, i, v[i], prev_data[k][i], template_names[k])
end
end
Line 138: Line 137:
-- iterate through attacks/abilities/subtowers
-- iterate through attacks/abilities/subtowers
for kk, vv in pairs(v) do
for _, i in ipairs(v["_order"]) do
if k == "subtowers" then tinsert(template[k], sformat(header, kk)) end
if k == "subtowers" then tinsert(template[k], sformat(header, i)) end
tinsert(template[k], parse_stats_full(frame, kk, nil, vv, template_names[k]))
tinsert(template[k], parse_stats_full(frame, i, nil, v[i], template_names[k]))
end
end
Line 169: Line 168:
-- iterate through attacks/abilities/subtowers
-- iterate through attacks/abilities/subtowers
for kk, vv in pairs(v) do
for _, i in ipairs(v["_order"]) do
if prev_data[k][kk] == nil then prev_data[k][kk] = {} end
if prev_data[k][i] == nil then prev_data[k][i] = {} end
-- parse sub-table of table
-- parse sub-table of table
parse_stats_full(frame, kk, vv, prev_data[k][kk], template_names[k])
parse_stats_full(frame, i, v[i], prev_data[k][i], template_names[k])
end
end
Line 186: Line 185:
-- iterate through attacks/abilities/subtowers
-- iterate through attacks/abilities/subtowers
for kk, vv in pairs(v) do
for _, i in ipairs(v["_order"]) do
if prev_data[k][kk] == nil then prev_data[k][kk] = {} end
if prev_data[k][i] == nil then prev_data[k][i] = {} end
-- parse sub-table of table
-- parse sub-table of table
tinsert(template[k], parse_stats_full(frame, kk, nil, vv, template_names[k]))
tinsert(template[k], parse_stats_full(frame, i, nil, v[i], template_names[k]))
end
end
Line 204: Line 203:
-- stats of a single tower
-- stats of a single tower
function p.base_stats(frame)
function p.base_stats(frame)
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s", frame.args[1]))
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
local header_level = frame.args["header level"] ~= nil and frame.args["header level"] or "3"
local header_level = frame.args["header level"] ~= nil and frame.args["header level"] or "3"
local header = "<h" .. header_level .. ">%s</h" .. header_level .. ">"
local header = "<h" .. header_level .. ">%s</h" .. header_level .. ">"
Line 221: Line 220:
-- stats of a paragon
-- stats of a paragon
function p.paragon(frame)
function p.paragon(frame)
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s", frame.args[1]))
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
local out = parse_tower(frame, data, my_data, "<h3>%s</h3>")
local out = parse_tower(frame, data, my_data, "<h3>%s</h3>")
Line 229: Line 228:
-- stat changes of a tower
-- stat changes of a tower
function p.tower_upgrade_stats(frame)
function p.tower_upgrade_stats(frame)
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s", frame.args[1]))
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
local ret = {}
local ret = {}
Line 241: Line 240:
local upgrade_crosspaths = {
local upgrade_crosspaths = {
--["100"] = {{"_110", "_120", "_130", "_140", "_150"}, {"_101", "_102", "_103", "_104", "_105"}},
["_100"] = {{"_110"}, {"_101"}},
--["200"] = {{"_210", "_220", "_230", "_240", "_250"}, {"_201", "_202", "_203", "_204", "_205"}},
["_200"] = {{"_210", "_220"}, {"_201", "_202"}},
--["010"] = {{"_110", "_210", "_310", "_410", "_510"}, {"_011", "_012", "_013", "_014", "_015"}},
["_010"] = {{"_110"}, {"_011"}},
--["020"] = {{"_120", "_220", "_320", "_420", "_520"}, {"_021", "_022", "_023", "_024", "_025"}},
["_020"] = {{"_120", "_220"}, {"_021", "_022"}},
--["001"] = {{"_101", "_201", "_301", "_401", "_501"}, {"_011", "_021", "_031", "_041", "_051"}},
["_001"] = {{"_101"}, {"_011"}},
--["002"] = {{"_102", "_202", "_302", "_402", "_502"}, {"_012", "_022", "_032", "_042", "_052"}},
["_002"] = {{"_102", "_202"}, {"_012", "_022"}},
["_100"] = {{}},
["_200"] = {{}},
["_010"] = {{}},
["_020"] = {{}},
["_001"] = {{}},
["_002"] = {{}},
["_300"] = {{"_310", "_320"}, {"_301", "_302"}},
["_300"] = {{"_310", "_320"}, {"_301", "_302"}},
["_400"] = {{"_410", "_420"}, {"_401", "_402"}},
["_400"] = {{"_410", "_420"}, {"_401", "_402"}},
Line 282: Line 275:
-- stat changes of a hero
-- stat changes of a hero
function p.hero_level_changes(frame)
function p.hero_level_changes(frame)
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s", frame.args[1]))
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
local ret = {}
local ret = {}
Line 303: Line 296:
-- stat changes of a hero
-- stat changes of a hero
function p.hero_level_stats(frame)
function p.hero_level_stats(frame)
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s", frame.args[1]))
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
local ret = {}
local ret = {}
Line 323: Line 316:


function p.last_updated(frame)
function p.last_updated(frame)
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s", frame.args[1]))
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
return string.format("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 v%s|version %s]]</div>", data["_last_updated"], data["_last_updated"])
return string.format("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 v%s|version %s]]</div>", data["_last_updated"], data["_last_updated"])
end
end


return p
return p

Revision as of 20:27, 4 February 2025

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

-- This code is copyrighted and licensed under the Creative Commons Attribution-NonCommercial-ShareAlike International license, version 4.0. You may reuse and adapt this code for other purposes if:
-- * You give appropriate credit
-- * You are not using this material for commercial purposes
-- * You are releasing it under the same license
-- The subpages of this page are adapted from internal data in Bloons TD 6, which is copyrighted by Ninja Kiwi Limited. Its usage on Blooncyclopedia is believed to be fair use.
-- 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 my_data = {}

local template_names = {
	attacks		="BTD6 attack",
	projectiles	="BTD6 projectile",
	collectables="BTD6 collectable",
	abilities	="BTD6 ability",
	effects		="BTD6 effect",
	buffs		="BTD6 buff",
	zones		="BTD6 zone",
	subtowers	="BTD6 tower"
}

function parse_tower(frame, new_data, prev_data, header)
	local template = {}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local tconcat = table.concat
	local sformat = string.format
	local ssub = string.sub
	
	-- search through tables
	for k, v in pairs(new_data) do
		if type(v) == "table" and ssub(k, 1, 1) ~= "_" then
			template[k] = {}
			if prev_data[k] == nil then prev_data[k] = {} end
			
			-- iterate through attacks/abilities/subtowers
			for _, i in ipairs(v["_order"]) do
				if k == "subtowers" then tinsert(template[k], sformat(header, i)) end
				if prev_data[k][i] == nil then prev_data[k][i] = {} end
				-- parse sub-table of table
				tinsert(template[k], parse_stats(frame, i, v[i], prev_data[k][i], template_names[k]))
			end
			
			template[k] = tconcat(template[k])
		
		elseif type(v) ~= "table" then
			-- if previous value exists, make it a comparison
			if prev_data[k] ~= nil then
				template[k] = prev_data[k]
				template[k .. " after"] = v
			else
				template[k] = v
			end
			
			-- update previous value
			prev_data[k] = v
		end
	end
	
	return frame:expandTemplate{title = "BTD6 tower", args = template}
end

function parse_stats(frame, name, new_data, prev_data, template_name)
	local template = {name = name}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local tconcat = table.concat
	
	-- search through tables
	for k, v in pairs(new_data) do
		if type(v) == "table" then
			template[k] = {}
			
			if prev_data[k] == nil then prev_data[k] = {} end
			
			-- iterate through attacks/abilities/subtowers
			for _, i in ipairs(v["_order"]) do
				if prev_data[k][i] == nil then prev_data[k][i] = {} end
				-- parse sub-table of table
				tinsert(template[k], parse_stats(frame, i, v[i], prev_data[k][i], template_names[k]))
			end
			
			template[k] = tconcat(template[k])
		
		else
			-- if previous value exists, make it a comparison
			if prev_data[k] ~= nil then
				template[k] = prev_data[k]
				template[k .. " after"] = v
			else
				template[k] = v
			end
			
			-- update previous value
			prev_data[k] = v
		end
	end
	
	return frame:expandTemplate{title = template_name, args = template}
end

function parse_tower_full(frame, new_data, prev_data, header)
	local template = {}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local tconcat = table.concat
	local sformat = string.format
	local ssub = string.sub
	
	-- search through tables
	for k, v in pairs(new_data) do
		if type(v) == "table" and ssub(k, 1, 1) ~= "_" then
			if template[k] == nil then template[k] = {} end
			if prev_data[k] == nil then prev_data[k] = {} end
			
			-- iterate through attacks/abilities/subtowers
			for _, i in ipairs(v["_order"]) do
				if prev_data[k][i] == nil then prev_data[k][i] = {} end
				-- parse sub-table of table
				 parse_stats_full(frame, i, v[i], prev_data[k][i], template_names[k])
			end
		
		elseif type(v) ~= "table" then
			-- update previous value
			prev_data[k] = v
		end
	end
	
	-- update prev_data first
	for k, v in pairs(prev_data) do
		if k == "attacks" or k == "abilities" or k == "subtowers" or k == "zones" then
			template[k] = {}
			
			-- iterate through attacks/abilities/subtowers
			for _, i in ipairs(v["_order"]) do
				if k == "subtowers" then tinsert(template[k], sformat(header, i)) end
				tinsert(template[k], parse_stats_full(frame, i, nil, v[i], template_names[k]))
			end
			
			template[k] = tconcat(template[k])
		
		elseif type(v) ~= "table" then
			-- update previous value
			template[k] = v
		end
	end
	
	return frame:expandTemplate{title = "BTD6 tower", args = template}
end

function parse_stats_full(frame, name, new_data, prev_data, template_name)
	local template = {name = name}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local tconcat = table.concat
	
	-- update prev_data first
	if new_data ~= nil then
		for k, v in pairs(new_data) do
			if type(v) == "table" then
				mw.logObject(k)
				if prev_data[k] == nil then prev_data[k] = {} end
				
				-- iterate through attacks/abilities/subtowers
				for _, i in ipairs(v["_order"]) do
					if prev_data[k][i] == nil then prev_data[k][i] = {} end
					-- parse sub-table of table
					parse_stats_full(frame, i, v[i], prev_data[k][i], template_names[k])
				end
			
			else
				prev_data[k] = v
			end
		end
	end
	
	for k, v in pairs(prev_data) do
		if type(v) == "table" then
			template[k] = {}
			
			-- iterate through attacks/abilities/subtowers
			for _, i in ipairs(v["_order"]) do
				if prev_data[k][i] == nil then prev_data[k][i] = {} end
				-- parse sub-table of table
				tinsert(template[k], parse_stats_full(frame, i, nil, v[i], template_names[k]))
			end
			
			template[k] = tconcat(template[k])
		
		else
			template[k] = v
		end
	end
	
	return frame:expandTemplate{title = template_name, args = template}
end

-- stats of a single tower
function p.base_stats(frame)
	local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
	local header_level = frame.args["header level"] ~= nil and frame.args["header level"] or "3"
	local header = "<h" .. header_level .. ">%s</h" .. header_level .. ">"
	
	if frame.args[2] == nil then
		if data["_000"] ~= nil then
			return parse_tower(frame, data["_000"], my_data, header)
		else
			return parse_tower(frame, data, my_data, header)
		end
	else
		return parse_tower(frame, data["_" .. frame.args[2]], my_data, header)
	end
end

-- stats of a paragon
function p.paragon(frame)
	local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
	
	local out = parse_tower(frame, data, my_data, "<h3>%s</h3>")
	return string.format("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 v%s|version %s]]</div>", data["_last_updated"], data["_last_updated"]) .. out
end

-- stat changes of a tower
function p.tower_upgrade_stats(frame)
	local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
	
	local ret = {}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local sformat = string.format
	local ssub = string.sub
	
	local base_data = data[frame.args[2]]
	
	local upgrade_crosspaths = {
		["_100"] = {{"_110"}, {"_101"}},
		["_200"] = {{"_210", "_220"}, {"_201", "_202"}},
		["_010"] = {{"_110"}, {"_011"}},
		["_020"] = {{"_120", "_220"}, {"_021", "_022"}},
		["_001"] = {{"_101"}, {"_011"}},
		["_002"] = {{"_102", "_202"}, {"_012", "_022"}},
		["_300"] = {{"_310", "_320"}, {"_301", "_302"}},
		["_400"] = {{"_410", "_420"}, {"_401", "_402"}},
		["_500"] = {{"_510", "_520"}, {"_501", "_502"}},
		["_030"] = {{"_130", "_230"}, {"_031", "_032"}},
		["_040"] = {{"_140", "_240"}, {"_041", "_042"}},
		["_050"] = {{"_150", "_250"}, {"_051", "_052"}},
		["_003"] = {{"_103", "_203"}, {"_013", "_023"}},
		["_004"] = {{"_104", "_204"}, {"_014", "_024"}},
		["_005"] = {{"_105", "_205"}, {"_015", "_025"}}
	}
	
	tinsert(ret, sformat("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 v%s|version %s]]</div>", data["_last_updated"], data["_last_updated"]))
	
	for i, v in ipairs(upgrade_crosspaths[frame.args[2]]) do
		local result = parse_tower(frame, base_data, my_data, "<h3>%s</h3>")
		if i == 1 then tinsert(ret, result) end
		for ii, vv in ipairs(v) do
			if base_data[vv] ~= nil then
				tinsert(ret, sformat("<h3>%s-%s-%s</h3>", ssub(vv, 2, 2), ssub(vv, 3, 3), ssub(vv, 4, 4)))
				tinsert(ret, parse_tower(frame, base_data[vv], my_data, "<h4>%s</h4>"))
			end
		end
	end
	
	return table.concat(ret, "\n")
end

-- stat changes of a hero
function p.hero_level_changes(frame)
	local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
	
	local ret = {}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local sformat = string.format
	
	-- calculate base tower stats for later comparison
	parse_tower(frame, data, my_data, "<h3>%s</h3>")
	
	for i = 2, 20 do
		tinsert(ret, sformat("===Level %i===", i))
		tinsert(ret, parse_tower(frame, data["_" .. i], my_data, "<h4>%s</h4>"))
	end
	
	return table.concat(ret, "\n")
end

-- stat changes of a hero
function p.hero_level_stats(frame)
	local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
	
	local ret = {}
	
	-- local functions to improve performance
	local tinsert = table.insert
	local sformat = string.format
	
	-- calculate base tower stats for later comparison
	parse_tower(frame, data, my_data, "<h3>%s</h3>")
	
	for i = 2, 20 do
		tinsert(ret, sformat("===Level %i===", i))
		tinsert(ret, parse_tower_full(frame, data["_" .. i], my_data, "<h4>%s</h4>"))
	end
	
	return table.concat(ret, "\n")
end

function p.last_updated(frame)
	local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1]))
	return string.format("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 v%s|version %s]]</div>", data["_last_updated"], data["_last_updated"])
end

return p