Module:Calculator/ItemEconomy

Revision as of 00:59, 1 March 2024 by Ricewind (talk | contribs) (Add rounding)

Documentation for this module may be created at Module:Calculator/ItemEconomy/doc

local p = {}

local shared = require('Module:Shared')
local eco = require("Module:ItemEconomy")

ECOIN = "INPUT"
ECOOUT = "OUTPUT"

local function parseEconomy(eco)
	if eco == nil then
		return ECOOUT
	end
	
	if eco:upper() == ECOIN then
        return ECOIN
    elseif eco:upper() == ECOOUT then
        return ECOOUT
    end
    
    return ECOOUT
end

--
-- Returns the estimated output items and TRUE/FALSE if the Ring of Wealth has a benefit.
--
local function calculateOutput(itemAmount, pChance, dChance, eChance)
	local estimatedOutput = eco.estimatedOutput(itemAmount, pChance, dChance, eChance)
	local canUseRoW = eco.ringOfWealthHasEffect(pChance, dChance, eChance)
	
	return math.floor(estimatedOutput), canUseRoW
end

--
-- Returns the estimated input items and TRUE/FALSE if the Ring of Wealth has a benefit.
--
local function calculateInput(itemAmount, pChance, dChance, eChance)
	local estimatedInput = eco.estimatedInput(itemAmount, pChance, dChance, eChance)
	
	local baseModifier = eco.estimatedInput(1, pChance, dChance, eChance)
	local rowModifier = eco.estimatedInput(1, pChance - 3, dChance + 7, eChance)

	return math.ceil(estimatedInput), rowModifier > baseModifier
end

local function addTableRow(tbl, c1, c2)
	tbl:tag("tr")
		:tag("th"):wikitext(c1)
		:tag("td"):wikitext(c2)
	
	return tbl
end

local function calculateFactor(a, b)
    local highest = math.max(a, b)
    local lowest = math.min(a, b)

    if lowest == 0 then
    	-- This shouldn't ever be possible!
        error("Div by zero")
    end

    local factor = highest / lowest
    return string.format("x%.2f", factor)
end

local function createTable(userAmount, calcAmount, useRoW, ecoType)
	local RoWYN = useRoW and "Yes" or "No"
	
	local tbl = mw.html.create("table")
		:addClass("wikitable sticky-header text-align-right align-left-1")
		
	if ecoType == ECOIN then
		addTableRow(tbl, "Desired Output", shared.formatnum(userAmount))
		addTableRow(tbl, "Estimated Input", shared.formatnum(calcAmount))
	else
		addTableRow(tbl, "Starting Items", shared.formatnum(userAmount))
		addTableRow(tbl, "Estimated Output", shared.formatnum(calcAmount))
	end
	
	addTableRow(tbl, "Economy Factor", calculateFactor(userAmount, calcAmount))
	addTableRow(tbl, "[[Ring of Wealth]] benefits", RoWYN)
	
	return tbl
end

function p.main(frame)
	local args = frame:getParent().args
	return p._main(args)
end

function p._main(args)
	local itemAmount = args.targetAmount
	local economyType = parseEconomy(args.economyType)
	
	local pChance = shared.toNumberOrDefault(args.preservationChance, 0)
	local dChance = shared.toNumberOrDefault(args.duplicationChance, 0)
	local eChance = shared.toNumberOrDefault(args.extraItemChance, 0)
	
	local result = 0
	local row = false
	
	if economyType == ECOOUT then
		result, row = calculateOutput(itemAmount, pChance, dChance, eChance)
	else
		result, row = calculateInput(itemAmount, pChance, dChance, eChance)
	end

	local tbl = createTable(itemAmount, result, row, economyType)
        
    return tostring(tbl)
end

return p