Module:Sandbox/User:Suity/MasterworkCalc

From the RuneScape Wiki, the wiki for all things RuneScape
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Template:Module sandbox/doc. [edit] [history] [purge]
Module:Sandbox/User:Suity/MasterworkCalc requires Module:Coins.
Module:Sandbox/User:Suity/MasterworkCalc requires Module:ExchangeLite.
Module:Sandbox/User:Suity/MasterworkCalc loads data from Module:Sandbox/User:Suity/msdata.

This module is a sandbox for Suity. It can be used to test changes to existing modules, prototype new modules, or just experimenting with lua features.

Invocations of this sandbox should be kept in userspace; if the module is intended for use in other namespaces, it should be moved out of the sandbox into a normal module and template.

This default documentation can be overridden by creating the /doc subpage of this module, as normal.

local p = {}
local data = mw.loadData('Module:Sandbox/User:Suity/msdata')
local gemw = require('Module:ExchangeLite')
local coins = require('Module:Coins')

local lang = mw.getContentLanguage() -- Number format helper function.
function fnum(x)
    if type(x) == 'number' then return lang:formatNum(x) end
return x end

function plink(name, opts)
    local file = name.. '.png'
    local link = name
    local text = name
    if type(opts) == 'table' then
        if opts.txt then
            text = opts.txt
        end
        if opts.img then
            file = opts.img
        end
    end
    if text ~= '' then
        text = string.format(' [[%s|%s]]', link,text)
    end

    return string.format('[[File:%s|link=%s]]%s', file, link, text)
end
function plinkp(name, img)
    return plink(name, {img = img, txt = ''})
end

function clock(x)	-- Convert time into HH:MM string
	local x = tonumber(x) * 0.6
	if x <= 0 then
		return "00:00"
	else
		hours = string.format("%02.f", math.floor(x/3600))
		mins = string.format("%02.f", math.floor(x/60 - (hours*60)))
		secs = string.format("%02.f", math.floor(x - hours*3600 - mins *60));
		return hours..":"..mins..":"..secs
	end
end

function p.main(frame)
	local args = frame:getParent().args
	local mining_level = tonumber(args.mining_level) or 1		-- Mining level
    local str_level = tonumber(args.str_level) or 1				-- Strength level
    local smith_level = tonumber(args.smith_level) or 1 		-- Smithing level
    local fm_level = tonumber(args.fm_level) or 1				-- Firemaking level
	local ironring = tonumber(args.ironring)					-- Ring of Forging
	local blast = tonumber(args.blast)							-- Blast furnace
	local ignoredoublesmelt = tonumber(args.ignoredoublesmelt)	-- Ignore double smelting chance
	local varrock = data.varrock[args.varrock]					-- Varrock armour
	local newvar = data.newvar[args.newvar]						-- New varrock tasks
	local mw_bbc = tonumber(args.mw_helm) + tonumber(args.mw_body) + tonumber(args.mw_legs) + tonumber(args.mw_gloves) + tonumber(args.mw_boots)	-- How many masterwork items are being made (base bar cost)
	local shf = tonumber(args.shf)								-- Superheat Form
	local shi = tonumber(args.shi)								-- Superheat item
	local pick = data.picks[args.pickaxe]						-- Pickaxe
    local method_m = data.method_m[args.method_m] or 'Active'	-- Method chosen (mining)
    local aura = data.auras[args.aura]							-- Aura
    local scrimshaw = data.scrimshaw[args.scrimshaw]			-- Scrimshaw
    local capem = tonumber(args.capem)							-- Mining skillcape
    local addon = tonumber(args.addon)							-- Modified Blacksmith's Helmet
    local familiar = data.familiar_m[args.familiar]				-- Familiar
    local outfit = data.outfit_m[args.outfit]					-- Outfit selected
    local ring = data.rings[args.ring]							-- Ring
    local trah = tonumber(args.trah)							-- Trahaearn Hour
    local spirits = tonumber(args.spirits)						-- Stone spirits
    local honed = data.honed[args.honed]						-- Honed perk
    local ramhammer = data.ramhammer[args.ramhammer]			-- Dwarven Ramhammer
    local skillchompa = data.skillchompa[args.skillchompa]		-- Skillchompas
    local oldbane = tonumber(args.oldbane)						-- Mining Banite Ore Before Rework
    local tmw = tonumber(args.tmw)								-- Trimmed Masterwork Armour
    local unlock = tonumber(args.unlock)						-- Masterwork unlock
    local newbars = tonumber(args.newbars)						-- Buying new bars
    local method_s = data.method_s[args.method_s]				-- Smithing method selected
    local injector = tonumber(args.injector)					-- Luminite Injector
	local tinker = data.tinker[args.tinker]						-- Tinker perk
	local hammer = tonumber(args.hammer)						-- Crystal hammer
	local juju = tonumber(args.juju)							-- Perfect juju smithing potion
	local rapid = data.rapid[args.rapid]						-- Rapid perk
	local method_refill = method_s.refill 						-- table from mw.loadData is read-only but we need to change it if shi is active
	
	-- Variables for totals
	local total_mining = 0
	local total_smelting = 0
	local total_cost = gemw.price('Leather') * mw_bbc
	local total_unlock = 0
	local unlock_bars = data.mw_unlock
	local tmw_bars = 1
	if unlock == 0 then unlock_bars = 0 end
	if tmw == 0 then tmw_bars = 0 end
	
-- Critical hit bonus for Mining
local crit_bonus = 0
for i = 1,20,1 do
    if mining_level >= data.crit_bonus_level[i] 
    then crit_bonus = data.crit_bonus[i]
    else break end
end
crit_bonus = crit_bonus + skillchompa.bonus	-- Skillchompas critical hit bonus

-- Mining boosts
if mining_level < 99 then capem = 0 end			-- Turn off skillcape if selected without 99 mining
local mining_level = mining_level				-- Mining level boosts (currently not added)
local damage_bonus = familiar + ring.damage		-- Damage bonus

-- Heat values
local max_heat = 300 + (smith_level * 3) + (fm_level * 3)	-- Maximum heat pool (using the old formula temporarily)
local heat_range = data.high_heat
if shf == 1 then heat_range = data.low_heat end				-- If superheat form is active, high heat players can drop to 33% heat without penalty
local high_heat = math.floor(max_heat * heat_range)
local heat_diff = max_heat - high_heat -- How much heat will give the high heat bonus
local heat_loss = data.heat_loss * rapid.heat -- Heat lost per strike
	
-- Table headers for Mining
local mt = mw.html.create('table')
mt:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Mining')	:attr('colspan', 8)	:done()
:tag('tr')
:tag('th')	:wikitext('Rock')	:done()
:tag('th')	:wikitext('Ore Needed')	:done()
:tag('th')	:wikitext('Net Hardness')	:done()
:tag('th')	:wikitext('Crit Chance')	:done()
:tag('th')	:wikitext('Double Ore Chance')	:done()
:tag('th')	:wikitext('Ore Per Hour')	:done()
:tag('th')	:wikitext('Time Spent')	:done()
:done()

-- Table headers for Smelting
local st = mw.html.create('table')
st:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Smelting')	:attr('colspan', 3)	:done()
:tag('tr')
:tag('th')	:wikitext('Metal')							:done()
:tag('th')	:wikitext('Bars Needed')					:done()
:tag('th')	:wikitext('Time Spent')						:done()
:done()

-- Table headers for Smithing (unlocking masterwork)
local ut = mw.html.create('table')
ut:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Unlocking Masterwork')	:attr('colspan', 2)	:done()
:tag('tr')
:tag('th')	:wikitext('Item')										:done()
:tag('th')	:wikitext('Time Spent')									:done()
:done()


local unlock_loop = {
	{name = plink('Elder rune full helm + 5'),			bbc = 2,	show = tonumber(args.mw_helm),		mw = plinkp('Masterwork helm')},
	{name = plink('Elder rune platebody + 5'),			bbc = 5,	show = tonumber(args.mw_body),		mw = plinkp('Masterwork platebody')},
	{name = plink('Elder rune platelegs + 5'),			bbc = 3,	show = tonumber(args.mw_legs),		mw = plinkp('Masterwork platelegs')},
	{name = plink('Elder rune gauntlets + 5'),			bbc = 1,	show = tonumber(args.mw_gloves),	mw = plinkp('Masterwork gloves')},
	{name = plink('Elder rune armoured boots + 5'),		bbc = 1,	show = tonumber(args.mw_boots),		mw = plinkp('Masterwork boots')},
}
local mw_img = ""
local tmw_img = ""

-- Table headers for Grand Total
local tt = mw.html.create('table')
tt:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Grand Totals')	:attr('colspan', 2)	:done()
:tag('tr')
:tag('th')	:wikitext('Action')		:done()
:tag('th')	:wikitext('Time Spent')	:done()
:done()

-- Table headers for Total Cost
local tc = mw.html.create('table')
tc:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Total Cost')	:attr('colspan', 3)	:done()
:tag('tr')
:tag('th')	:wikitext('Item')		:done()
:tag('th')	:wikitext('Quantity')	:done()
:tag('th')	:wikitext('Cost')		:done()
:tag('tr')
:tag('td')	:wikitext('[[File:Leather.png|link=]] [[Soft leather]]')	:done()
:tag('td')	:wikitext(mw_bbc)			:css('text-align', 'center')	:done()
:tag('td')	:wikitext(coins._amount(total_cost))						:done()
:done()

for index,i in ipairs(data.metals) do

-- Bars needed
	-- Extra smelting chance (free bars smelted)
	local double_chance = data.double_bars + addon
	local double_chance_rune = {data.double_bars+addon, data.double_bars+addon}
	local effective_chance = 0
	local effective_chance_rune = {}	-- Rune needs to be dealt with separately since half of the bars are used in elder rune bars
	local bars_needed = 0
	local bars_flat = 0 				-- How many bars are needed if purchased
	-- Varrock armour
	if i.name == '[[Rune bar|Rune]]' then
		if varrock.no == 4 then double_chance_rune[2] = double_chance_rune[2] + (data.varrock['Varrock armour 4']['effect'] * newvar[2]) end
		if i.varrock[varrock.no] == 1 then double_chance_rune[1] = double_chance_rune[1] + (data.varrock[i.varrock_no]['effect'] * newvar[2]) end
		effective_chance_rune[1] = 1 + double_chance_rune[1] + (2*(double_chance_rune[1])^2) + (4*(double_chance_rune[1])^3) + (8*(double_chance_rune[1])^4) + (16*(double_chance_rune[1])^5) -- Chance for rune bars
		effective_chance_rune[2] = 1 + double_chance_rune[2] + (2*(double_chance_rune[2])^2) + (4*(double_chance_rune[2])^3) + (8*(double_chance_rune[2])^4) + (16*(double_chance_rune[2])^5) -- Chance for elder bars
		local elder = i.mw_amount[2]
		if tmw == 1 then elder = elder + tmw_bars end
		if unlock == 1 then elder = elder + unlock_bars end
		if newbars == 1 then elder = 0 end
		if ignoredoublesmelt == 1 then 
			bars_needed = (i.mw_amount[1] + elder) * mw_bbc
			bars_flat = (i.mw_amount[1] + elder) * mw_bbc
		else bars_needed = math.ceil((i.mw_amount[1] * mw_bbc) / effective_chance_rune[1]) + math.ceil((elder * mw_bbc) / effective_chance_rune[2]) 
			 bars_flat = (i.mw_amount[1] * mw_bbc) + math.ceil((elder * mw_bbc) / effective_chance_rune[2])	end
	else
		if varrock.no > 0 then
			if i.varrock[varrock.no] == 1 then
				double_chance = double_chance + (data.varrock[i.varrock_no]['effect'] * newvar[2])
			end
		end
		effective_chance = 1 + double_chance + (2*(double_chance)^2) + (4*(double_chance)^3) + (8*(double_chance)^4) + (16*(double_chance)^5)
		if i.name == '[[Elder rune bar|Elder Rune]]' then 
			bars_needed = (i.mw_amount + unlock_bars + tmw_bars) * mw_bbc
			bars_flat = (i.mw_amount + unlock_bars + tmw_bars) * mw_bbc
		else bars_needed = i.mw_amount * mw_bbc
			 bars_flat = i.mw_amount * mw_bbc end
		if ignoredoublesmelt == 0 then bars_needed = math.ceil(bars_needed / effective_chance) end
	end

-- Unlocking masterwork (creating +5s)
if i.name == '[[Elder rune bar|Elder Rune]]' then	
	for l,x in ipairs(unlock_loop) do
		if x.show > 0 then
		local item_total = 0
		-- Double progress chance
		local double_progress = tinker + hammer + juju
		-- Varrock armour
		if varrock.no == 4 then double_progress = double_progress + (data.varrock[i.varrock_no]['effect'] * newvar[3]) end	-- Only varrock armour 4 applies to Elder rune
		-- Progress per strike (PPS)
		local pps_base = data.base_progress + injector + 1
		if args.method == '2-Ticking' then pps_base = pps_base + (data.smithing_cape / 2) end
		local pps = 0
		if shf == 1 then pps = pps_base * method_s.superheat else pps = pps_base * method_s.progress end
		pps = (pps + (pps * double_progress)) * rapid.progress
		-- Reheat rate (the amount of ticks it take to reheat an item from 0 to full)
		if shi == 1 then method_refill = 0 end	-- Turn off reheating if using Superheat item
		local reheat_rate = data.reheats[2]
		-- Ticks wasted creating each item
		local tw = 0
		if method_refill == 0 then tw = data.tickwaste_afk
		else tw = data.tickwaste_max end
		
		-- Reheats past the initial creation (this section only applies to high heat smithing without superheat item)
		local reheat_strikes = (math.ceil(heat_diff / heat_loss)) * data.strike -- Number of ticks spent on strikes per reheat
		local reheat_progress = reheat_strikes * pps							-- Amount of progress made per reheat
		local reheat_rate_repeat = math.ceil(reheat_rate * heat_range)			-- Reheats past the initial creation aren't done from 0 so will use a % of reheat_rate
		if reheat_rate_repeat < 1 then reheat_rate_repeat = 1 end				-- Minimum 1 tick to reheat
		local tw_reheat = (data.tw_turn * 2) + data.tw_delay + reheat_rate_repeat -- Total ticks wasted per reheat (excluding the initial creation)
		if method_refill == 0 then tw_reheat = 0 end
		
		-- Base calculations
		local progress_base = i.progress * x.bbc
		local reheats_base = math.ceil((progress_base - reheat_progress) / reheat_progress) * tw_reheat	-- Ticks wasted on further reheats past the initial creation phase
		if reheats_base < 0 then reheats_base = 0 end													-- Can't have negative number of ticks wasted due to reheats
		local ticks_item_base = (math.ceil(progress_base / pps) * data.strike) + reheats_base + tw		-- Ticks per item = strikes per item + reheat ticks wasted + tickwaste for initial item
		
		-- +X Calculations
		local progress = {}
		local reheats = {}
		local ticks_item = {}
		for z = 1,5,1 do
			progress[z] = progress_base * data.progress_mult[z]
			reheats[z] = math.ceil((progress[z] - reheat_progress) / reheat_progress) * tw_reheat
			if reheats[z] < 0 then reheats[z] = 0 end
			ticks_item[z] = (math.ceil(progress[z] / pps) * data.strike) + reheats[z] + tw
		end
		-- Totals and table
		mw_img = mw_img..x.mw
		item_total = ticks_item_base + ticks_item[1] + ticks_item[2] + ticks_item[3] + ticks_item[4] + ticks_item[5]
		total_unlock = total_unlock + item_total
		ut:tag('tr')
		:tag('td')	:wikitext(x.name)	:done()
		:tag('td')	:wikitext(clock(item_total))	:css('text-align', 'center')	:done()
		:done()
		end
	end
end

local price = 0
if args.oldbars == 'Yes (At Pre-Rework Prices)' then
	if i.old == 1 then
		price = i.price * bars_flat
		tc:tag('tr')
		:tag('td')	:wikitext(i.img..' '..i.name)									:done()
		:tag('td')	:wikitext(fnum(bars_flat))		:css('text-align', 'center')	:done()
		:tag('td')	:wikitext(coins._amount(price))									:done()
		bars_needed = 0
		total_cost = total_cost + price
	end
elseif args.oldbars == 'Yes (At Post-Rework Estimated Settled Prices)' then
	if i.old == 1 then
		price = i.est_ge * bars_flat
		tc:tag('tr')
		:tag('td')	:wikitext(i.img..' '..i.name)									:done()
		:tag('td')	:wikitext(fnum(bars_flat))		:css('text-align', 'center')	:done()
		:tag('td')	:wikitext(coins._amount(price))									:done()
		bars_needed = 0
		total_cost = total_cost + price
end end
if newbars == 1 then
	if i.old == 0 then
		price = i.est_ge * bars_flat
		tc:tag('tr')
		:tag('td')	:wikitext(i.img..' '..i.name)									:done()
		:tag('td')	:wikitext(fnum(bars_flat))		:css('text-align', 'center')	:done()
		:tag('td')	:wikitext(coins._amount(price))									:done()
		bars_needed = 0
		total_cost = total_cost + price
end end

-- Smelt Rate
local smelt_rate = data.smelt_rate[2] - shf
local smelt_ticks = bars_needed * smelt_rate

if bars_needed > 0 then
	total_smelting = total_smelting + smelt_ticks
st:tag('tr')
:tag('td')	:wikitext(i.img..' '..i.name)										:done()
:tag('td')	:wikitext(fnum(bars_needed))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(clock(smelt_ticks))		:css('text-align', 'center')	:done()
end end

st:tag('tr')
:tag('th')	:wikitext('Total Time Spent')			:attr('colspan', 2)	:done()
:tag('th')	:wikitext(clock(total_smelting))							:done()

for index,i in ipairs(data.rocks) do
if i.mw_req == 1 then
	
-- Ore needed
	-- Double smelting chance
	local double_chance = data.double_bars + addon
	local double_chance_two = {data.double_bars+addon, data.double_bars+addon}			-- Double chance where ore is used in two different bars
	local double_chance_three = {data.double_bars+addon, data.double_bars+addon, data.double_bars+addon}	-- Double chance where ore is used in three different bars (only luminite ore)
	local effective_chance = 0
	local effective_chance_mult = {}													-- Effective chance for ores that are used in different bars
	local ore_needed = 0
	-- Varrock armour
	if		i.name == "[[Iron ore|Iron]]" then		-- Iron is used in both iron and steel bars which both use the same varrock armour
		if i.varrock[varrock.no] == 1 then double_chance = double_chance + (data.varrock[i.varrock_no]['effect'] * newvar[2]) end
		effective_chance = 1 + double_chance + (2*(double_chance)^2) + (4*(double_chance)^3) + (8*(double_chance)^4) + (16*(double_chance)^5)
		ore_needed = ((i.mw_amount[1]/ironring) + i.mw_amount[2]) * mw_bbc	-- Half the amount of Iron needed for Iron bars if using Ring of Forging
		if ignoredoublesmelt == 0 then ore_needed = math.ceil(ore_needed / effective_chance) end
	elseif	i.name == "[[Concentrated coal rock|Concentrated Coal]]" then
		if varrock.no >= 2 then double_chance_two[2] = double_chance_two[2] + (data.varrock['Varrock armour 2']['effect'] * newvar[2]) end
		if varrock.no >= 1 then double_chance_two[1] = double_chance_two[1] + (data.varrock['Varrock armour 1']['effect'] * newvar[2]) end
		effective_chance_mult[1] = 1 + double_chance_two[1] + (2*(double_chance_two[1])^2) + (4*(double_chance_two[1])^3) + (8*(double_chance_two[1])^4) + (16*(double_chance_two[1])^5)
		effective_chance_mult[2] = 1 + double_chance_two[2] + (2*(double_chance_two[2])^2) + (4*(double_chance_two[2])^3) + (8*(double_chance_two[2])^4) + (16*(double_chance_two[2])^5)
		if ignoredoublesmelt == 1 then ore_needed = (i.mw_amount[1] + i.mw_amount[2]) * mw_bbc
		else ore_needed = math.ceil((i.mw_amount[1] * mw_bbc) / effective_chance_mult[1]) + math.ceil((i.mw_amount[2] * mw_bbc) / effective_chance_mult[2]) end
	elseif	i.name == "[[Runite ore|Runite]]" then
		if varrock.no == 4 then double_chance_two[2] = double_chance_two[2] + (data.varrock['Varrock armour 4']['effect'] * newvar[2]) end
		if varrock.no >= 3 then double_chance_two[1] = double_chance_two[1] + (data.varrock['Varrock armour 3']['effect'] * newvar[2]) end
		effective_chance_mult[1] = 1 + double_chance_two[1] + (2*(double_chance_two[1])^2) + (4*(double_chance_two[1])^3) + (8*(double_chance_two[1])^4) + (16*(double_chance_two[1])^5)
		effective_chance_mult[2] = 1 + double_chance_two[2] + (2*(double_chance_two[2])^2) + (4*(double_chance_two[2])^3) + (8*(double_chance_two[2])^4) + (16*(double_chance_two[2])^5)
		local elder = i.mw_amount[2]
		if tmw == 1 then elder = elder + tmw_bars end
		if unlock == 1 then elder = elder + unlock_bars end
		if newbars == 1 then elder = 0 end
		if ignoredoublesmelt == 1 then ore_needed = (i.mw_amount[1] + elder) * mw_bbc
		else ore_needed = math.ceil((i.mw_amount[1] * mw_bbc) / effective_chance_mult[1]) + math.ceil((elder * mw_bbc) / effective_chance_mult[2]) end
	elseif	i.name == '[[Luminite]]' then
		if varrock.no == 4 then double_chance_three[3] = double_chance_three[3] + (data.varrock['Varrock armour 4']['effect'] * newvar[2]) end
		if varrock.no >= 3 then double_chance_three[2] = double_chance_three[2] + (data.varrock['Varrock armour 3']['effect'] * newvar[2]) end
		if varrock.no >= 2 then double_chance_three[1] = double_chance_three[1] + (data.varrock['Varrock armour 2']['effect'] * newvar[2]) end
		effective_chance_mult[1] = 1 + double_chance_three[1] + (2*(double_chance_three[1])^2) + (4*(double_chance_three[1])^3) + (8*(double_chance_three[1])^4) + (16*(double_chance_three[1])^5)
		effective_chance_mult[2] = 1 + double_chance_three[2] + (2*(double_chance_three[2])^2) + (4*(double_chance_three[2])^3) + (8*(double_chance_three[2])^4) + (16*(double_chance_three[2])^5)
		effective_chance_mult[3] = 1 + double_chance_three[3] + (2*(double_chance_three[3])^2) + (4*(double_chance_three[3])^3) + (8*(double_chance_three[3])^4) + (16*(double_chance_three[3])^5)
		local elder = i.mw_amount[3]
		if tmw == 1 then elder = elder + tmw_bars end
		if unlock == 1 then elder = elder + unlock_bars end
		if newbars == 1 then elder = 0 end
		if ignoredoublesmelt == 1 then ore_needed = (i.mw_amount[1] + i.mw_amount[2] + elder) * mw_bbc
		else ore_needed = math.ceil((i.mw_amount[1] * mw_bbc) / effective_chance_mult[1]) + math.ceil((i.mw_amount[2] * mw_bbc) / effective_chance_mult[2]) + math.ceil((elder * mw_bbc) / effective_chance_mult[3])
		end
	else
		if varrock.no > 0 then
			if i.varrock[varrock.no] == 1 then
				double_chance = double_chance + (data.varrock[i.varrock_no]['effect'] * newvar[2])
			end
		end
		effective_chance = 1 + double_chance + (2*(double_chance)^2) + (4*(double_chance)^3) + (8*(double_chance)^4) + (16*(double_chance)^5)
		if i.name == '[[Light animica]]'..'; '.."[[Dark animica]]" then 
			ore_needed = (i.mw_amount + (2 * (unlock_bars + tmw_bars))) * mw_bbc
		else ore_needed = i.mw_amount * mw_bbc end
		
		if ignoredoublesmelt == 0 then ore_needed = math.ceil(ore_needed / effective_chance) end
	end
	if i.blast_furnace == 1 then ore_needed = ore_needed * blast end	-- If using blast furnace, some ores do not need to be mined


-- Net Hardness
local net_hardness = pick.pen - i.hardness
if net_hardness > 0 then net_hardness = 0 end

-- Critical hit chance
local crit_chance = 0
if		i.len_crit_chance_level == 2 then
    if		mining_level >= i.crit_chance_level[2] then crit_chance = data.crit_chances[2]
    elseif	mining_level >= i.crit_chance_level[1] then crit_chance = data.crit_chances[1]
    else												crit_chance = data.crit_chance_base end 
elseif	i.len_crit_chance_level == 1 then
    if		mining_level >= i.crit_chance_level[1] then crit_chance = data.crit_chances[1]
    else												crit_chance = data.crit_chance_base end
else													crit_chance = data.crit_chance_base end
crit_chance = crit_chance + aura.crit + scrimshaw.crit + outfit.crit

-- Base damage calculations
local net_crit_bonus = crit_bonus + net_hardness
if net_crit_bonus < 1 then net_crit_bonus = 1 end
local net_crit = net_crit_bonus * crit_chance
local damage = mining_level + math.floor(str_level/10) + net_hardness + net_crit + damage_bonus + pick.avg
if damage < 1 then damage = 1 end	-- If negative damage due to hardness then swings deal 1 damage.

-- Base ore calculations
local swings_ore = i.diff / damage							-- Average swings per ore
if swings_ore < 1 then swings_ore = 1 end					-- Apply damage hard cap
local ore_swing = 1 / swings_ore							-- Average ore per swing
local base_ore = ore_swing * data.swing_hr * method_m.xp	-- Average ore per hour
	-- Double ore chance
	local double_ore_chance = 0
	if		i.len_double_ore == 2 then
        if		mining_level >= i.double_ore_chance[2] then double_ore_chance = data.double_ore_chances[2]
        elseif	mining_level >= i.double_ore_chance[1] then double_ore_chance = data.double_ore_chances[1]
        else												double_ore_chance = data.double_ore_chance_base end
    elseif	i.len_double_ore == 1 then
        if		mining_level >= i.double_ore_chance[1] then double_ore_chance = data.double_ore_chances[1]
        else												double_ore_chance = data.double_ore_chance_base end
    else													double_ore_chance = data.double_ore_chance_base
    end
    double_ore_chance = double_ore_chance + honed + capem			-- Apply honed perk and mining skillcape if applicable
    -- Double ore chance (Varrock armour)
    if varrock.no > 0 then											-- Skips if no varrock armour is selected	
    	if i.core == 1 then											-- Skips if the rock is not a core rock
    		if i.varrock[varrock.no] == 1 then						-- Checks if the armour selected applies to the rock
    			double_ore_chance = double_ore_chance + (data.varrock[i.varrock_no]['effect'] * newvar[1])
    end end end
    -- Double ore chance (Trah hour)
    if trah == 1 then
    	if i.trah == 1 then double_ore_chance = double_ore_chance + data.trah_bonus end end
   local ore_boosts = i.ore + double_ore_chance	+ ramhammer.ore		-- Ore multiplier
   if i.spirits == 1 then ore_boosts = ore_boosts + spirits end		-- Stone spirits (checks if the rock can use a spirit)
   local total_ore = base_ore * ore_boosts
 
-- Rockertunities
	-- Rockertunity multiplier
	local rck_mult = 0
	 if i.len_rockertunity_level == 2 then
        if mining_level >= i.rockertunity_level[2] then rck_mult = data.rockertunity_mult[2]
        elseif mining_level >= i.rockertunity_level[1] then rck_mult = data.rockertunity_mult[1]
        else rck_mult = data.rockertunity_mult_base end
    elseif i.len_rockertunity_level == 1 then
        if mining_level >= i.rockertunity_level[1] then rck_mult = data.rockertunity_mult[1]
        else rck_mult = data.rockertunity_mult_base end
    else rck_mult = data.rockertunity_mult_base end
    rck_mult = rck_mult + outfit.rck								-- Add the magic golem's rockertunity multiplier
    -- Rockertunity Ore
    local rck_ore_loss = (rck_mult * ore_swing) - (data.rck_loss * ore_swing)
    if rck_ore_loss > 1 then rck_ore_loss = 1 end
    local rck_ore = data.rck_hr * rck_ore_loss
    if method_m.rck == 1 then total_ore = total_ore + rck_ore end
  
-- Ore time calculations
local ore_tick = 6000 / total_ore
local mining_ticks = math.ceil(ore_needed * ore_tick)

-- If already bought remove timers
if args.oldbars ~= 'No' then
	if i.old == 1 then ore_needed = 0 end end
if oldbane == 1 then
	if i.name == "[[Bane ore|Banite]]" then ore_needed = 0 end end
if newbars == 1 then
	if i.old == 0 then ore_needed = 0 end end
	
if ore_needed > 0 then
	total_mining = total_mining + mining_ticks
mt:tag('tr')
:tag('td')	:wikitext(i.img..' '..i.name)														:done()
:tag('td')	:wikitext(fnum(ore_needed))							:css('text-align', 'center')	:done()
:tag('td')  :wikitext(net_hardness)             				:css('text-align', 'center')    :done()
:tag('td')  :wikitext((crit_chance*100)..'%')   				:css('text-align', 'center')    :done()
:tag('td')  :wikitext((double_ore_chance*100)..'%') 			:css('text-align', 'center')    :done()
:tag('td')  :wikitext(fnum(math.floor(10 * total_ore)/10))      :css('text-align', 'center')    :done()
:tag('td')  :wikitext(clock(mining_ticks))    					:css('text-align', 'center')    :done()
:done()
end end end

-- Total mining 
mt:tag('tr')
:tag('th')	:wikitext('Total Time Spent')			:attr('colspan', 6) :done()
:tag('th')	:wikitext(clock(total_mining))								:done()
:done()

-- Total unlock
ut:tag('tr')
:tag('th')	:wikitext('Total Time Spent')	:done()
:tag('th')	:wikitext(clock(total_unlock))	:done()
:done()

-- Untempered and Rivets
	-- Double progress chance
	local double_progress = tinker + hammer + juju
	-- Progress per strike (PPS)
	local pps_base = data.base_progress + injector
	if args.method == '2-Ticking' then pps_base = pps_base + (data.smithing_cape / 2) end
	local pps = 0
	if shf == 1 then pps = pps_base * method_s.superheat else pps = pps_base * method_s.progress end
	pps = (pps + (pps * double_progress)) * rapid.progress
	-- Reheat rate (the amount of ticks it takes to reheat an item from 0 to full)
	if shi == 1 then method_refill = 0 end -- Turn off reheating if using Superheat item
	local reheat_rate = data.reheat_base
	-- Ticks wasted creating each item
	local tw = 0
	if method_refill == 0 then tw = data.tickwaste_afk
	else tw = data.tickwaste + reheat_rate end
	-- Reheats past the initial creation (this section only applies to high heat smithing without superheat ietm)
	local reheat_strikes = (math.ceil(heat_diff / heat_loss)) * data.strike -- Number of ticks spent on strikes per reheat
	local reheat_progress = reheat_strikes * pps							-- Amount of progress made per reheat
	local reheat_rate_repeat = math.ceil(reheat_rate * heat_range)			-- Reheats past the initial creation aren't done from 0 so will use a % of reheat_rate
	if reheat_rate_repeat < 1 then reheat_rate_repeat = 1 end				-- Minimum 1 tick to reheat
	local tw_reheat = (data.tw_turn * 2) + data.tw_delay + reheat_rate_repeat -- Total ticks wasted per reheat (excluding the initial creation)
	if method_refill == 0 then tw_reheat = 0 end
	
	local progress = {data.mw_rivets, data.mw_mw_plate, data.mw_curved_plate, data.mw_untempered, data.tmw_inlay, data.tmw_complete}
	local untempered = 0
	local rivets = 0
	local inlays = 0
	local complete = 0
	for i = 1,6,1 do
		local progress_base = progress[i]
		local reheats_base = math.ceil((progress_base - reheat_progress) / reheat_progress) * tw_reheat	-- Ticks wasted on further reheats past the initial creation phase
		if reheats_base < 0 then reheats_base = 0 end													-- Can't have negative number of ticks wasted due to reheats
		local ticks_item_base = (math.ceil(progress_base / pps) * data.strike) + reheats_base + tw		-- Ticks per item = strikes per item + reheat ticks wasted + tickwaste for initial item
		local ticks_item_bbc = ticks_item_base * mw_bbc
		if i == 1 then rivets = ticks_item_bbc
		elseif i == 5 then inlays = ticks_item_bbc
		elseif i == 6 then complete = ticks_item_bbc
		else untempered = untempered + ticks_item_bbc end
	end

-- Table for Masterwork
local mwt = mw.html.create('table')
local immaculate = data.mw_bar_imm_total * mw_bbc
local glorious = data.mw_bar_glorious * mw_bbc
local lined = (data.mw_armour_piece + data.mw_lined) * mw_bbc
local completed = data.mw_unf_total * mw_bbc
local total_mw = immaculate + glorious + lined + completed + rivets + untempered
mwt:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Masterwork')							:attr('colspan', 2)		:done()
:tag('tr')
:tag('th')	:wikitext('Action')		:done()
:tag('th')	:wikitext('Time Spent')	:done()
:tag('tr')
:tag('td')	:wikitext(plink('Immaculate alloy bar')..'s')							:done()
:tag('td')	:wikitext(clock(immaculate))		:css('text-align', 'center')    	:done()	
:tag('tr')
:tag('td')	:wikitext(plink('Glorious bar')..'s')									:done()
:tag('td')	:wikitext(clock(glorious))			:css('text-align', 'center')    	:done()
:tag('tr')
:tag('td')	:wikitext(plink('Masterwork rivets'))									:done()
:tag('td')	:wikitext(clock(rivets))			:css('text-align', 'center')		:done()
:tag('tr')
:tag('td')	:wikitext(plink('Untempered masterwork armour piece')..'s')				:done()
:tag('td')	:wikitext(clock(untempered))			:css('text-align', 'center')    :done()
:tag('tr')
:tag('td')	:wikitext(plink('Lined masterwork armour piece')..'s')					:done()
:tag('td')	:wikitext(clock(lined))				:css('text-align', 'center')		:done()	
:tag('tr')
:tag('td')	:wikitext(mw_img..' [[Masterwork equipment|Completed Armour]]')			:done()
:tag('td')	:wikitext(clock(completed))			:css('text-align', 'center')		:done()	
:tag('tr')
:tag('th')	:wikitext('Total Time Spent')	:done()
:tag('th')	:wikitext(clock(total_mw))		:done()
:done()

-- Table for trimmed masterwork
local tmwt = mw.html.create('table')
local essence = data.tmw_essence * mw_bbc
local total_tmw = inlays + essence + completed
local malevolent = math.ceil(data.malevolent_min * mw_bbc)
local torva = math.ceil(data.torva_min * mw_bbc)
tmwt:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Trimmed Masterwork')		:attr('colspan', 2)		:done()
:tag('tr')
:tag('th')	:wikitext('Action')		:done()
:tag('th')	:wikitext('Time Spent')	:done()
:tag('tr')
:tag('td')	:wikitext(plink('Praesulic essence'))							:done()
:tag('td')	:wikitext(clock(essence))		:css('text-align', 'center')    :done()	
:tag('tr')
:tag('td')	:wikitext(plink('Malevolent essence'))							:done()
:tag('td')	:wikitext(clock(essence))		:css('text-align', 'center')    :done()	
:tag('tr')
:tag('td')	:wikitext(plink('Masterwork trim')..'s')						:done()
:tag('td')	:wikitext(clock(inlays))		:css('text-align', 'center')    :done()	
:tag('tr')
:tag('td')	:wikitext('Completed Armour')									:done()
:tag('td')	:wikitext(clock(complete))		:css('text-align', 'center')    :done()	
:tag('tr')
:tag('th')	:wikitext('Total Time Spent')	:done()
:tag('th')	:wikitext(clock(total_tmw))		:done()
:done()
if tmw == 1 then
	total_cost = total_cost + torva + malevolent
	tc:tag('tr')
	:tag('td')	:wikitext(plink('Praesulic essence'))				:done()
	:tag('td')	:wikitext(mw_bbc)	:css('text-align', 'center')    :done()
	:tag('td')	:wikitext(coins._amount(torva))						:done()
	:tag('tr')
	:tag('td')	:wikitext(plink('Malevolent essence'))				:done()
	:tag('td')	:wikitext(mw_bbc)	:css('text-align', 'center')    :done()
	:tag('td')	:wikitext(coins._amount(malevolent))				:done()
	:done()
end

-- Total for cost
tc:tag('tr')
:tag('th')	:wikitext('Total Spent')	:attr('colspan', 2)	:done()
:tag('th')	:wikitext(coins._amount(total_cost))			:done()
:done()

-- Remaining cells for grand totals table
local grand_total = total_mining + total_smelting + total_mw
if total_mining > 0 then
tt:tag('tr')
:tag('td')	:wikitext('Mining')														:done()
:tag('td')	:wikitext(clock(total_mining))			:css('text-align', 'center')    :done() end
if total_smelting > 0 then
tt:tag('tr')
:tag('td')	:wikitext('Smelting')													:done()
:tag('td')	:wikitext(clock(total_smelting))		:css('text-align', 'center')    :done() end
tt:tag('tr')
:tag('td')	:wikitext('Masterwork')													:done()
:tag('td')	:wikitext(clock(total_mw))				:css('text-align', 'center')    :done()
if unlock == 1 then
	grand_total = grand_total + total_unlock
tt:tag('tr')
:tag('td')	:wikitext('Unlock')														:done()
:tag('td')	:wikitext(clock(total_unlock))			:css('text-align', 'center')	:done() end
if tmw == 1 then
	grand_total = grand_total + total_tmw
	tt:tag('tr')
	:tag('td')	:wikitext('Trimmed Masterwork')										:done()
	:tag('td')	:wikitext(clock(total_tmw))			:css('text-align', 'center')	:done() end
tt:tag('tr')
:tag('th')	:wikitext('Grand Total')												:done()
:tag('th')	:wikitext(clock(grand_total))											:done()
:done()

local tables = tostring(tt)..tostring(tc)
if total_mining > 0 then tables = tables..tostring(mt) end
if total_smelting > 0 then tables = tables..tostring(st) end
if unlock == 1 then tables = tables..tostring(ut) end
tables = tables..tostring(mwt)
if tmw == 1 then tables = tables..tostring(tmwt) end


return tables
end
return p