Module:BATTD costs: Difference between revisions

From Blooncyclopedia, the independent Bloons knowledge base
Jump to navigation Jump to search
No edit summary
No edit summary
Line 3: Line 3:
local function upgrade(towerName, upgradeName)
local function upgrade(towerName, upgradeName)
local sFormat = string.format
local sFormat = string.format
local tConcat = table.concat
local query = mw.ext.cargo.query
local query = mw.ext.cargo.query
local lang = mw.language.new("en")
-- build key:values table of upgrades where id=key
local outputTable = {}
local upgradesById = {}
local upgradeId = ""
local upgradeId = ""
local upgrades = query("battd_upgrades", "id, name, tower, cost", {
local upgradesById = {} -- key:value table  - upgrade:upgrade data
local upgradePrereqsById = {} -- key:values table - upgrade:prerequisites to purchase this upgrade
local upgradePrereqsOfById = {} -- key:values table - upgrades:upgrades this is a prerequisite of
local upgradeLocksById = {} -- key:values table - upgrades:upgrades that this upgrade locks
local purchasableUpgrades = {} -- upgrades that are directly purchasable from this upgrade
local alreadyPurchasedUpgrades = {} -- this upgrade and all upgrades the player has to have already purchased to get it
-- cargo queries for data
local upgrades, upgradePrereqs, upgradeLocks =
query("battd_upgrades", "_pageName, id, name, tower, cost", {
where=sFormat("tower='%s'", towerName)
where=sFormat("tower='%s'", towerName)
}),
query("battd_upgrades=main, battd_upgrades__previous=prev", "main.id=thisId, prev._value=prevId", {
where=sFormat("main.tower='%s'", towerName),
join="main._ID=prev._RowID"
}),
query("battd_upgrades=main, battd_upgrades__locked_by_upgrades=lock", "main.id=thisId, lock._value=lockId", {
where=sFormat("main.tower='%s'", towerName),
join="main._ID=lock._RowID"
})
})


-- build upgradesById
for i, upgrade in ipairs(upgrades) do
for i, upgrade in ipairs(upgrades) do
upgradesById[upgrade.id] = upgrade
if upgrade.name == upgradeName then upgradeId = upgrade.id end
if upgrade.name == upgradeName then upgradeId = upgrade.id end
upgradesById[upgrade.id] = upgrade
end
end
-- build key:values table of upgrade prereqs where id=current and values=previous
-- build alreadyPurchasedUpgrades
local upgradePrereqsById = {}
local function getAlreadyPurchasedUpgrades(myUpgradeId)
local roots = {}
local cost = upgradesById[myUpgradeId].cost
local upgradePrereqs = query("battd_upgrades=main, battd_upgrades__previous=prev", "main.id=thisId, prev._value=nextId", {
alreadyPurchasedUpgrades[myUpgradeId] = true
where=sFormat("main.tower='%s'", towerName),
join="main._ID=prev._RowID",
for i, id in ipairs(upgradePrereqsById[myUpgradeId]) do
})
cost = cost + getAlreadyPurchasedUpgrades(id)
 
end
for i, upgrade in ipairs(upgradePrereqs) do
return cost
if not upgrade.nextId then roots[#roots+1] = upgrade.thisId end
if upgradePrereqsById[upgrade.thisId] then upgradePrereqsById[upgrade.thisId][#upgradePrereqsById[upgrade.thisId]+1] = upgrade.nextId end
upgradePrereqsById[upgrade.thisId] = {upgrade.nextId}
end
end
-- build key:values table of upgrade locks where id=current and values=previous
-- tower cost + total cost of this upgrade and all its prereqs
local upgradeLocksById = {}
local baseCost = getAlreadyPurchasedUpgrades(upgradeId) + query("battd_characters", "cost", {
local upgradeLocks = query("battd_upgrades=main, battd_upgrades__locked_by_upgrades=lock", "main.id=thisId, lock._value=lockId", {
where=sFormat("name='%s'", towerName)
where=sFormat("main.tower='%s'", towerName),
})[1].cost
join="main._ID=lock._RowID",
})


-- build upgradeLocksById
for i, upgrade in ipairs(upgradeLocks) do
for i, upgrade in ipairs(upgradeLocks) do
if upgradeLocksById[upgrade.thisId] then upgradePrereqsById[upgrade.thisId][#upgradePrereqsById[upgrade.thisId]+1] = upgrade.lockId end
if upgrade.lockId then
upgradeLocksById[upgrade.thisId] = {upgrade.lockId}
if upgradeLocksById[upgrade.thisId] then
upgradeLocksById[upgrade.thisId][#upgradeLocksById[upgrade.thisId]+1] = upgrade.lockId
else
upgradeLocksById[upgrade.thisId] = {upgrade.lockId}
end
end
end
end
local function recursiveGetCost(id)
local cost = upgradesById[id].cost
 
for i, v in ipairs(upgradePrereqsById[id]) do
-- build upgradePrereqsById, upgradePrereqsOfById, purchasableUpgrades
cost = cost + recursiveGetCost(v)
for i, upgrade in ipairs(upgradePrereqs) do
-- upgrade:next table
if upgrade.prevId then
if upgradePrereqsOfById[upgrade.prevId] then
upgradePrereqsOfById[upgrade.prevId][#upgradePrereqsOfById[upgrade.prevId]+1] = upgrade.thisId
else
upgradePrereqsOfById[upgrade.prevId] = {upgrade.thisId}
end
-- if this upgrade is purchasable next in the tree
if upgrade.prevId == upgradeId then purchasableUpgrades[upgrade.thisId] = true end
-- if this upgrade is a root upgrade and is not already purchased
elseif not alreadyPurchasedUpgrades[upgrade.thisId] then
purchasableUpgrades[#purchasableUpgrades+1] = upgrade.thisId
end
end
return cost
-- upgrade:prev table
if upgradePrereqsById[upgrade.thisId] then
upgradePrereqsById[upgrade.thisId][#upgradePrereqsById[upgrade.thisId]+1] = upgrade.prevId
else
upgradePrereqsById[upgrade.thisId] = {upgrade.prevId}
end
end
-- generate table header
local row = {[[{|class="wikitable sortable" style="text-align:center"
!Cost!!Sell value]]}
for i, upgrade in ipairs(upgrades) do
--mw.logObject(upgrade)
if not alreadyPurchasedUpgrades[upgrade.id] then row[#row+1] = sFormat("!![[%s|%s]]", upgrade._pageName, upgrade.name) end
end
end
-- tower cost + total cost of this upgrade and all its prereqs
outputTable[1] = tConcat(row)
local baseCost = recursiveGetCost(upgradeId) + query("battd_characters", "cost", {
where=sFormat("name='%s'", towerName)
--[=[local function recursiveGetTotalCosts(currentCost, myUpgradeId, purchasedUpgrades)
})[1].cost
currentCost = currentCost + upgradesById[upgradeId].cost
purchasedUpgrades[myUpgradeId] = true
row = {sFormat([[|-
|$%s]], lang:formatNum(currentCost))}
for i, id in ipairs(upgradesById) do
row[i+1] = purchasedUpgrades[id] and "||{{Y}}" or "||{{N}}"
end
outputTable[#outputTable+1] = tConcat(row, "\n")
for k, id in pairs(upgradePrereqsOfById[myUpgradeId]) do
recursiveGetTotalCosts(currentCost, id, purchasedUpgrades)
end
end]=]--


return baseCost
--mw.logObject(upgradePrereqsOfById)
--mw.logObject(purchasableUpgrades)
--mw.log(table.concat(outputTable))
--mw.logObject(upgradeLocksById)
outputTable[#outputTable+1] = "\n|}"
return tConcat(outputTable)
end
end



Revision as of 03:24, 11 January 2026

Documentation for this module may be created at Module:BATTD costs/doc

local p = {}

local function upgrade(towerName, upgradeName)
	local sFormat = string.format
	local tConcat = table.concat
	local query = mw.ext.cargo.query
	local lang = mw.language.new("en")
	
	local outputTable = {}
	local upgradeId = ""
	
	local upgradesById = {}				-- key:value table  - upgrade:upgrade data
	local upgradePrereqsById = {}		-- key:values table - upgrade:prerequisites to purchase this upgrade
	local upgradePrereqsOfById = {}		-- key:values table - upgrades:upgrades this is a prerequisite of
	local upgradeLocksById = {}			-- key:values table - upgrades:upgrades that this upgrade locks
	local purchasableUpgrades = {}		-- upgrades that are directly purchasable from this upgrade
	local alreadyPurchasedUpgrades = {} -- this upgrade and all upgrades the player has to have already purchased to get it
	
	-- cargo queries for data
	local upgrades, upgradePrereqs, upgradeLocks =
	query("battd_upgrades", "_pageName, id, name, tower, cost", {
		where=sFormat("tower='%s'", towerName)
	}),
	query("battd_upgrades=main, battd_upgrades__previous=prev", "main.id=thisId, prev._value=prevId", {
		where=sFormat("main.tower='%s'", towerName),
		join="main._ID=prev._RowID"
	}),
	query("battd_upgrades=main, battd_upgrades__locked_by_upgrades=lock", "main.id=thisId, lock._value=lockId", {
		where=sFormat("main.tower='%s'", towerName),
		join="main._ID=lock._RowID"
	})

	-- build upgradesById
	for i, upgrade in ipairs(upgrades) do
		upgradesById[upgrade.id] = upgrade
		if upgrade.name == upgradeName then upgradeId = upgrade.id end
	end
	
	-- build alreadyPurchasedUpgrades
	local function getAlreadyPurchasedUpgrades(myUpgradeId)
		local cost = upgradesById[myUpgradeId].cost
		alreadyPurchasedUpgrades[myUpgradeId] = true
		
		for i, id in ipairs(upgradePrereqsById[myUpgradeId]) do
			cost = cost + getAlreadyPurchasedUpgrades(id)
		end
		return cost
	end
	
	-- tower cost + total cost of this upgrade and all its prereqs
	local baseCost = getAlreadyPurchasedUpgrades(upgradeId) + query("battd_characters", "cost", {
		where=sFormat("name='%s'", towerName)
	})[1].cost

	-- build upgradeLocksById
	for i, upgrade in ipairs(upgradeLocks) do
		if upgrade.lockId then
			if upgradeLocksById[upgrade.thisId] then
				upgradeLocksById[upgrade.thisId][#upgradeLocksById[upgrade.thisId]+1] = upgrade.lockId
			else
				upgradeLocksById[upgrade.thisId] = {upgrade.lockId}
			end
		end
	end
	
	

	-- build upgradePrereqsById, upgradePrereqsOfById, purchasableUpgrades
	for i, upgrade in ipairs(upgradePrereqs) do
		-- upgrade:next table
		if upgrade.prevId then
			if upgradePrereqsOfById[upgrade.prevId] then
				upgradePrereqsOfById[upgrade.prevId][#upgradePrereqsOfById[upgrade.prevId]+1] = upgrade.thisId
			else
				upgradePrereqsOfById[upgrade.prevId] = {upgrade.thisId}
			end
			
			-- if this upgrade is purchasable next in the tree
			if upgrade.prevId == upgradeId then purchasableUpgrades[upgrade.thisId] = true end
		
		-- if this upgrade is a root upgrade and is not already purchased
		elseif not alreadyPurchasedUpgrades[upgrade.thisId] then
			purchasableUpgrades[#purchasableUpgrades+1] = upgrade.thisId
		end
		
		-- upgrade:prev table
		if upgradePrereqsById[upgrade.thisId] then
			upgradePrereqsById[upgrade.thisId][#upgradePrereqsById[upgrade.thisId]+1] = upgrade.prevId
		else
			upgradePrereqsById[upgrade.thisId] = {upgrade.prevId}
		end
	end
	
	
	
	-- generate table header
	local row = {[[{|class="wikitable sortable" style="text-align:center"
!Cost!!Sell value]]}
	
	for i, upgrade in ipairs(upgrades) do
		--mw.logObject(upgrade)
		if not alreadyPurchasedUpgrades[upgrade.id] then row[#row+1] = sFormat("!![[%s|%s]]", upgrade._pageName, upgrade.name) end
	end
	
	outputTable[1] = tConcat(row)
	
	--[=[local function recursiveGetTotalCosts(currentCost, myUpgradeId, purchasedUpgrades)
		currentCost = currentCost + upgradesById[upgradeId].cost
		purchasedUpgrades[myUpgradeId] = true
		
		row = {sFormat([[|-
|$%s]], lang:formatNum(currentCost))}
		
		for i, id in ipairs(upgradesById) do
			row[i+1] = purchasedUpgrades[id] and "||{{Y}}" or "||{{N}}"
		end
		
		outputTable[#outputTable+1] = tConcat(row, "\n")
		
		for k, id in pairs(upgradePrereqsOfById[myUpgradeId]) do
			recursiveGetTotalCosts(currentCost, id, purchasedUpgrades)
		end
	end]=]--

	--mw.logObject(upgradePrereqsOfById)
	--mw.logObject(purchasableUpgrades)
	--mw.log(table.concat(outputTable))
	--mw.logObject(upgradeLocksById)
	
	outputTable[#outputTable+1] = "\n|}"
	return tConcat(outputTable)
end

function p.upgrade(frame)
	return upgrade(frame.args[1], frame.args[2])
end

return p