Module:Calculator/Summoning Interval Efficiency: Difference between revisions

From Melvor Idle
m (Round where data is formatted for output instead)
mNo edit summary
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
local number = require('Module:Number')
local number = require('Module:Number')
local economy = require('Module:ItemEconomy')
local economy = require('Module:ItemEconomy')
local TimeSpan = require('Module:TimeSpan')


local p = {}
local p = {}


-- Calculates the time economy of using summoning synergies that decrease action interval
-- based on the player's stats.
local function calculateTimeEfficiency(playerStats)
local function calculateTimeEfficiency(playerStats)
local result = {
local result = {
Line 18: Line 21:
return result
return result
end
end
-- Calculate item economy for tablet output
local eco = economy.ItemEconomy:new()
eco.outputsPerAction = playerStats.tabletsMade
eco.duplicationChance = playerStats.tabletDoubleChance
-- Values below are not included, but might be available as boosts.
eco.extraItemChance = 0
eco.extraItemAmount = 0
eco.flatExtraItems = 0
eco.extraBaseItemChance = 0
eco.extraBaseItems = 0
-- Calculate total amount of tablets made, including double chance
-- Calculate total amount of tablets made, including double chance
local averageTabletsMade = economy.estimatedOutput(
local averageTabletsMade = 1 * economy.estimatedOutputMultiplier(eco)
playerStats.tabletsMade,
0,
playerStats.tabletDoubleChance)


-- Calculate the effective amount of tablets the player has from one craft, including tablet save chance
-- Calculate the effective amount of tablets the player has from one craft, including tablet save chance
Line 45: Line 56:
end
end


-- Add a row to the table
-- Adds a row to a table.
-- If the value parameter is a negative number, colour the cell red.
-- Optionally adds a suffix to the 'value' parameter.
local function addTableRow(tbl, header, value)
local function addTableRow(tbl, header, value, suffix)
     local row = tbl:tag("tr")
     local row = tbl:tag("tr")
     local cell = row:tag("td")
     local headerCell = row:tag("th")
      
     local valueCell = row:tag("td")
    row:tag("th"):wikitext(header)
 
-- Check if the value is, or can be converted to a number.
local numValue = tonumber(value)


    if type(value) == "number" and value < 0 then
if suffix then
         cell:css('color', 'red'):wikitext(value)
value = value .. suffix
    else
end
        cell:wikitext(value)
-- If the numeric value is negative, colour the cell red.
    if numValue and numValue < 0 then
         valueCell = valueCell:css('color', 'red')
     end
     end
   
    -- Fill cells with data.
    headerCell:wikitext(header)
    valueCell:wikitext(value)
   
     return tbl
     return tbl
end
end


-- Format the calculated data and output a table.
local function createTable(calcResult)
local function createTable(calcResult)
local tableData = {
local tableData = {
Line 77: Line 99:
else
else
-- Calculate time saved in seconds for two and three tablet synergy
-- Calculate time saved in seconds for two and three tablet synergy
local twoTab = number.actionTimeToTimeSpan(calcResult.twoTabletTimeSave)
local twoTab = TimeSpan.fromSeconds(calcResult.twoTabletTimeSave)
     local threeTab = number.actionTimeToTimeSpan(calcResult.threeTabletTimeSave)
     local threeTab = TimeSpan.fromSeconds(calcResult.threeTabletTimeSave)
     tableData.effectiveTablets = number.round(calcResult.effectiveTablets, 2)
     tableData.effectiveTablets = number.round(calcResult.effectiveTablets, 2)
tableData.twoTabletTimeSave = number.round(twoTab.totalSeconds, 2)
tableData.twoTabletTimeSave = number.round(twoTab:getTotalSeconds(), 2)
tableData.threeTabletTimeSave = number.round(threeTab.totalSeconds, 2)
tableData.threeTabletTimeSave = number.round(threeTab:getTotalSeconds(), 2)
end
end


addTableRow(tbl, "Effective tablets", tableData.effectiveTablets)
addTableRow(tbl, "Effective tablets", tableData.effectiveTablets)
addTableRow(tbl, "Two tablet time save", tableData.twoTabletTimeSave)
addTableRow(tbl, "Two tablet time save", tableData.twoTabletTimeSave, ' sec')
addTableRow(tbl, "Three tablet time save", tableData.threeTabletTimeSave)
addTableRow(tbl, "Three tablet time save", tableData.threeTabletTimeSave, ' sec')
return tbl
return tbl
end
end
Line 97: Line 119:
function p._main(args)
function p._main(args)
-- Parse inputs and turn intervals into integers (hundreds of a second)
-- Parse inputs and turn intervals into integers (hundreds of a second)
local summoningInterval = number.toNumberOrError(args.summoningInterval) * 100
local summoningInterval = number.toNumberOrError(args.summoningInterval)
local actionTimeSaved = number.toNumberOrError(args.actionTimeSaved) * 100
local actionTimeSaved = number.toNumberOrError(args.actionTimeSaved)
local tabletsMade = number.toNumberOrError(args.tabletsMade)
local tabletsMade = number.toNumberOrError(args.tabletsMade)
local tabletDoubleChance = number.toNumberOrDefault(args.tabletDoubleChance, 0)
local tabletDoubleChance = number.toNumberOrDefault(args.tabletDoubleChance, 0)

Latest revision as of 21:19, 13 April 2024

Documentation for this module may be created at Module:Calculator/Summoning Interval Efficiency/doc

local number = require('Module:Number')
local economy = require('Module:ItemEconomy')
local TimeSpan = require('Module:TimeSpan')

local p = {}

-- Calculates the time economy of using summoning synergies that decrease action interval
-- based on the player's stats.
local function calculateTimeEfficiency(playerStats)
	local result = {
		isInfinite = false,
		twoTabletTimeSave = -1,
		threeTabletTimeSave = -1,
		effectiveTablets = -1
	}
	
	-- It is possible to get 100% tablet save chance. The rest of the calculation is irrelevant
	-- since the amount of time saved is infinite.
	if playerStats.tabletSaveChance >= 100 then
		result.isInfinite = true
		return result
	end
	
	-- Calculate item economy for tablet output
	local eco = economy.ItemEconomy:new()
	eco.outputsPerAction = playerStats.tabletsMade
	eco.duplicationChance = playerStats.tabletDoubleChance
	-- Values below are not included, but might be available as boosts.
	eco.extraItemChance = 0
	eco.extraItemAmount = 0
	eco.flatExtraItems = 0
	eco.extraBaseItemChance = 0
	eco.extraBaseItems = 0
	
	-- Calculate total amount of tablets made, including double chance
	local averageTabletsMade = 1 * economy.estimatedOutputMultiplier(eco)

	-- Calculate the effective amount of tablets the player has from one craft, including tablet save chance
	local tabletSaveChance = number.clamp(playerStats.tabletSaveChance, 0, 99)
	local effectiveTablets = averageTabletsMade / (1 - tabletSaveChance / 100)
	
	-- The effective time per tablet.
	-- two if the player was using tablets anyway
	-- three if the player is using tablets specifically for the time save synergy
	local twoTabletTime = (playerStats.actionTimeSaved / 2) * effectiveTablets
	local threeTabletTime = (playerStats.actionTimeSaved / 3) * effectiveTablets
	
	-- Subtract the total time saved by the time it takes to create the tablets.
	local twoTabletTimeSave = twoTabletTime - playerStats.summoningInterval
	local threeTabletTimeSave = threeTabletTime - playerStats.summoningInterval
	
	result.effectiveTablets = effectiveTablets
	result.twoTabletTimeSave = twoTabletTimeSave
	result.threeTabletTimeSave = threeTabletTimeSave
	return result
end

-- Adds a row to a table.
-- Optionally adds a suffix to the 'value' parameter.
local function addTableRow(tbl, header, value, suffix)
    local row = tbl:tag("tr")
    local headerCell = row:tag("th")
    local valueCell = row:tag("td")

	-- Check if the value is, or can be converted to a number.
	local numValue = tonumber(value)

	if suffix then
		value = value .. suffix
	end
	
	-- If the numeric value is negative, colour the cell red.
    if numValue and numValue < 0 then
        valueCell = valueCell:css('color', 'red')
    end
    
    -- Fill cells with data.
    headerCell:wikitext(header)
    valueCell:wikitext(value)
    
    return tbl
end

-- Format the calculated data and output a table.
local function createTable(calcResult)
	local tableData = {
    	effectiveTablets,
    	twoTabletTimeSave,
    	threeTabletTimeSave
    }

	local tbl = mw.html.create("table")
        :addClass("wikitable sticky-header text-align-right align-left-1")

	if calcResult.isInfinite then
		tableData.effectiveTablets = 'Infinite'
		tableData.twoTabletTimeSave = 'Infinite'
		tableData.threeTabletTimeSave = 'Infinite'
	else
		-- Calculate time saved in seconds for two and three tablet synergy
		local twoTab = TimeSpan.fromSeconds(calcResult.twoTabletTimeSave)
    	local threeTab = TimeSpan.fromSeconds(calcResult.threeTabletTimeSave)
    	tableData.effectiveTablets = number.round(calcResult.effectiveTablets, 2)
		tableData.twoTabletTimeSave = number.round(twoTab:getTotalSeconds(), 2)
		tableData.threeTabletTimeSave = number.round(threeTab:getTotalSeconds(), 2)
	end

	addTableRow(tbl, "Effective tablets", tableData.effectiveTablets)
	addTableRow(tbl, "Two tablet time save", tableData.twoTabletTimeSave, ' sec')
	addTableRow(tbl, "Three tablet time save", tableData.threeTabletTimeSave, ' sec')
	return tbl
end

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

function p._main(args)
	-- Parse inputs and turn intervals into integers (hundreds of a second)
	local summoningInterval = number.toNumberOrError(args.summoningInterval)
	local actionTimeSaved = number.toNumberOrError(args.actionTimeSaved)
	local tabletsMade = number.toNumberOrError(args.tabletsMade)
	local tabletDoubleChance = number.toNumberOrDefault(args.tabletDoubleChance, 0)
	local tabletSaveChance = number.toNumberOrDefault(args.tabletSaveChance, 0)

	local playerStats = {
		summoningInterval = summoningInterval,
		tabletsMade = tabletsMade,
		tabletDoubleChance = tabletDoubleChance,
		tabletSaveChance = tabletSaveChance,
		actionTimeSaved = actionTimeSaved
	}
	
	local calcResult = calculateTimeEfficiency(playerStats)
	local tbl = createTable(calcResult)
	
	return tostring(tbl)
end

return p