Module:Sandbox/User:Suity/SmithingCalc

From the RuneScape Wiki, the wiki for all things RuneScape
Jump to: navigation, search
Module documentation
This documentation is transcluded from Template:Module sandbox/doc. [edit] [history] [purge]
Module:Sandbox/User:Suity/SmithingCalc requires Module:ExchangeLite.
Module:Sandbox/User:Suity/SmithingCalc 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 lang = mw.getContentLanguage() -- Number format helper function.
function fnum(x)
    if type(x) == 'number' then return lang:formatNum(x) end
return x end

function p.main(frame)
	local args = frame:getParent().args
	local smith_level = tonumber(args.smith_level)	-- Smithing level
	local fm_level = tonumber(args.fm_level)	-- Firemaking level
	local method = data.method_s[args.method]	-- Method selected
	local result = tostring(args.result)		-- Determines which table to show 
	local item = data.bbc[args.item]			-- Base bar cost multiplier based on item chosen
	local shf = tonumber(args.superheatform)	-- Superheat form
	local shi = tonumber(args.superheatitem)	-- Superheat item
	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 solemn = data.solemn[args.solemn]		-- Solemn Smithing upgrades
	local varrock = data.varrock[args.varrock]	-- Varrock armour
	local newvar = tonumber(args.newvar)		-- New varrock tasks
	local avatar = data.avatar[args.avatar]		-- Avatar buff
	local bxp = tonumber(args.bxp)				-- Bonus XP 
	local dxp = tonumber(args.dxp)				-- Double XP Weekend
	local outfit = data.outfit_s[args.outfit]	-- Blacksmith's outfit
	local aura = data.auras[args.aura]			-- Aura
	local wise = data.wise[args.wise]			-- Wise perk
	local scroll = tonumber(args.scroll)		-- Scroll of efficiency
	local raf = tonumber(args.raf)				-- Refer a friend bonus
	local method_refill = method.refill 		-- table from mw.loadData is read-only but we need to change it if shi is active
	if dxp == 1 then raf = raf * 2 end			-- Refer a friend bonus gets doubled on Double XP Weekend
	
	--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
	
	-- Experience boosts
	local xp_boost = 1 + avatar + bxp + dxp + outfit + aura.xp + wise + scroll + raf
	
local t = mw.html.create('table')
t:addClass('wikitable')
:tag('tr')
:tag('th')	:wikitext('Level')			:attr('rowspan', 2)	:done()
:tag('th')	:wikitext('Metal')			:attr('rowspan', 2)	:done()
:tag('th')	:wikitext(result)			:attr('colspan', 9)	:done()
:done()
:tag('th')	:wikitext('Base')								:done()
:tag('th')	:wikitext('+1')									:done()
:tag('th')	:wikitext('+2')									:done()
:tag('th')	:wikitext('+3')									:done()
:tag('th')	:wikitext('+4')									:done()
:tag('th')	:wikitext('+5')									:done()
:tag('th')	:wikitext('Burial')								:done()
:tag('th')	:wikitext('Burial Set')							:done()
:tag('th')	:wikitext('Base to Burial')						:done()
:done()

for index,i in ipairs(data.metals) do
	if smith_level >= i.level then
		
	local img = i['img'..item] -- Item image
	
	-- Double progress chance
	local double_progress = tinker + hammer + juju
		-- Varrock armour
		if varrock.no > 0 then -- Skips if no varrock armour is selected
			if i.varrock[varrock.no] == 1 then -- Checks if the selected armour applies to the metal
				double_progress = double_progress + (data.varrock[i.varrock_no]['effect'] * newvar)
			end
		end
	
	-- 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
		-- Levelling benefit (+1 PPS)
	if smith_level >= i.extra_progress then pps_base = pps_base + 1 end
	local pps = 0
	if shf == 1 then pps = pps_base * method.superheat else pps = pps_base * method.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 refilling if using Superheat item (because it's lossless)
	local reheat_rate = data.reheat_base	-- Determine how many ticks it takes to refill from 0 to full based on level
	if		smith_level >= i.reheat_level[2] then reheat_rate = data.reheats[2]
	elseif	smith_level >= i.reheat_level[1] then reheat_rate = data.reheats[1] end

	-- Ticks wasted creating each item (this also includes reheating to max if not already starting at max when the method uses refilling)
	local tw = 0
	if method_refill == 0 then tw = data.tickwaste_afk -- Doesn't waste ticks for reheating if the method doesn't call for it (shi, autoheater, zero heat)
	else
		if smith_level >= i.max_heat then	tw = data.tickwaste_max -- Doesn't waste ticks for reheating if you have the level for max heat
		else								tw = data.tickwaste + reheat_rate end 
	end		-- tw should be added to every 'ticks spent per item'
	
	-- 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 = item * i.progress
	local xp_base		= item * i.xp 
	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
			-- Strikes per item = (rounded up) progress / progress per strike(pps)
			-- Ticks per item = strikes per item + reheat ticks wasted + tickwaste for initial item
	local ticks_item_base = (math.ceil(progress_base / pps) * data.strike) + reheats_base + tw
	local items_hr_base = 6000 / ticks_item_base -- Items created per hour
	local xp_hr_base = items_hr_base * xp_base * xp_boost
	local bars_hr_base = items_hr_base * item
	local basecell = 0 -- Used for table cell
	
	-- +X Calculations
	local progress = {}
	local xp = {}
	local reheats = {}
	local ticks_item = {}
	local items_hr = {}
	local xp_hr = {}
	local bars_hr = {}
	local maxcell = {} -- Used for table cells
	for x = 1,5,1 do
		progress[x] = progress_base * data.progress_mult[x]
		xp[x]		= xp_base * data.bar_mult[x]
		reheats[x] = math.ceil((progress[x] - reheat_progress) / reheat_progress) * tw_reheat
		if reheats[x] < 0 then reheats[x] = 0 end
		ticks_item[x] = (math.ceil(progress[x] / pps) * data.strike) + reheats[x] + tw
		items_hr[x] = 6000 / ticks_item[x]
		xp_hr[x] = items_hr[x] * xp[x] * xp_boost
		bars_hr[x] = items_hr[x] * data.bar_mult[x] * item
		maxcell[x] = '-'
		if i.max >= x then 
			if result == 'XP Per Hour'					then maxcell[x] = math.floor(xp_hr[x])
			elseif result == 'Items Per Hour'			then maxcell[x] = math.floor(100 * items_hr[x]) / 100
			elseif result == 'Time Per Item (Seconds)'	then maxcell[x] = math.floor(10 * ticks_item[x] * 0.6) / 10
			elseif result == 'Bars Used Per Hour'		then maxcell[x] = math.floor(bars_hr[x])
			end
		end
	end
	
	-- Burial and Burial sets (bs)
	local progress_burial = 0
	local xp_burial = 0
	local reheats_burial = 0
	local ticks_item_burial = 0
	local items_hr_burial = 0
	local xp_hr_burial = 0
	local bars_hr_burial = 0
	local burialcell = '-'
	local progress_bs = 0
	local xp_bs = 0
	local reheats_bs = 0
	local ticks_item_bs = 0
	local items_hr_bs = 0
	local xp_hr_bs = 0
	local xp_mod_bs = 1 + data.burial_set_xp + solemn -- The additional base XP for making a burial set + Solemn smithing
	local burialsetcell = '-'
	
	if i.burial == 1 then
		-- Burial
		progress_burial = progress[i.max] / 2
		xp_burial = xp[i.max]
		reheats_burial = math.ceil((progress_burial - reheat_progress) / reheat_progress) * tw_reheat
		--if reheats_burial < 0 then reheats_burial = 0 end
		ticks_item_burial = (math.ceil(progress_burial / pps) * data.strike) + reheats_burial + tw
		items_hr_burial = 6000 / ticks_item_burial
		xp_hr_burial = items_hr_burial * xp_burial * xp_boost
		
		-- Burial sets
		progress_bs = ((data.progress_mult[i.max] * i.progress) / 2) * data.burial_set
		xp_bs = data.bar_mult[i.max] * i.xp * data.burial_set * xp_mod_bs
		reheats_bs = math.ceil((progress_bs - reheat_progress) / reheat_progress) * tw_reheat
		ticks_item_bs = (math.ceil(progress_bs / pps) * data.strike) + reheats_bs + tw
		items_hr_bs = 6000 / ticks_item_bs
		xp_hr_bs = items_hr_bs * xp_bs * xp_boost
	end
	
	-- Populating non +X cells
	if		result == 'XP Per Hour' then
		basecell =	math.floor(xp_hr_base)
		burialcell = math.floor(xp_hr_burial)
		burialsetcell = math.floor(xp_hr_bs)
	elseif	result == 'Items Per Hour' then
		basecell = math.floor(100 * items_hr_base) / 100
		burialcell = math.floor(100 * items_hr_burial) / 100
		burialsetcell = math.floor(100 * items_hr_bs) / 100
	elseif	result == 'Time Per Item (Seconds)' then
		basecell = math.floor(10 * ticks_item_base * 0.6) / 10
		burialcell = math.floor(10 * ticks_item_burial * 0.6) / 10
		burialsetcell = math.floor(10 * ticks_item_bs * 0.6) / 10
	elseif	result == 'Bars Used Per Hour' then
		basecell = math.floor(bars_hr_base)
		burialcell = math.floor(bars_hr_burial)
		burialsetcell = math.floor(bars_hr_burial)
	end
	if burialcell == 0 then 
		burialcell = '-'
		burialsetcell = '-' end

-- Populating the remaining table structure
t:tag('tr')
:tag('td')	:wikitext(i.level)				:css('text-align', 'center')	:done()
:tag('td')	:wikitext(img..' '..i.name)							:done()
:tag('td')	:wikitext(fnum(basecell))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(maxcell[1]))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(maxcell[2]))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(maxcell[3]))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(maxcell[4]))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(maxcell[5]))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(burialcell))		:css('text-align', 'center')	:done()
:tag('td')	:wikitext(fnum(burialsetcell))	:css('text-align', 'center')	:done()
end end

return t
end
return p