Module:Sandbox/User:LegendOfBrian

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:LegendOfBrian requires Module:ExchangeLite.
Module:Sandbox/User:LegendOfBrian loads data from Module:Sandbox/User:LegendOfBrian/Database.

This module is a sandbox for LegendOfBrian. 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:LegendOfBrian/Database')
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 mining_level = tonumber(args.mining_level) or 1		-- Mining level
	local str_level = tonumber(args.str_level) or 1				-- Strength level
	local pick = data.picks[args.pickaxe]						-- Pickaxe
	local method = data.method_m[args.method] or 'Active'		-- Method chosen
	local aura = data.auras[args.aura]							-- Aura
	local scrimtmp = args.scrimshaw or 'None'
	local scrimshaw = data.scrimshaw[scrimtmp]					-- Scrimshaw
	local tmpvarrock = args.varrock or 'None'
	local varrock = data.varrock[tmpvarrock]					-- Varrock armour
	local newvar = tonumber(args.newvar) or 1					-- New varrock tasks
	local familiar = data.familiar_m[args.familiar] or 0		-- Familiar
	local gmo = data.outfit_s[args.gmo] or 0					-- Golden mining outfit pieces unlocked
	local outfittmp = args.outfit or 'None'
	local outfit = data.outfit_m[outfittmp]						-- Outfit selected
	local cape = tonumber(args.cape) or 0						-- Mining skillcape
	local ringtmp = args.ring or 'None'
	local ring = data.rings[ringtmp]							-- Ring
	local avatar = data.avatar[args.avatar] or 0				-- Avatar
	local spelltmp = args.spell or 'None'
	local spell = data.spells_m[spelltmp]						-- Crystallise / Light Form
	local trah = tonumber(args.trah) or 0						-- Trahaearn Hour
	local spirits = tonumber(args.spirits) or 0					-- Stone spirits
	local honed = data.honed[args.honed] or 0					-- Honed perk
	local wise = data.wise[args.wise] or 0						-- Wise perk
	local furnace = data.furnace[args.furnace] or 0				-- Furnace perk
	local urns = data.urns[args.urns]							-- Urns
	local ramtmp = args.ramhammer or 'None'
	local ramhammer = data.ramhammer[ramtmp]					-- Dwarven Ramhammer
	local refined = data.refined[args.refined] or 0				-- Refined
	local raf = tonumber(args.raf) or 0							-- Refer a friend bonus
	local bxp = tonumber(args.bxp)								-- Bonus XP
	local dxp = tonumber(args.dxp) or 0							-- Double XP Weekend
	local skillctmp = args.skillchompa or 'None'
	local skillchompa = data.skillchompa[skillctmp]				-- Skillchompas
	local custom = tonumber(args.custom) / 100					-- Custom XP boost
	if dxp == 1 then raf = raf * 2 end							-- Refer a friend bonus gets doubled on Double XP Weekend
	
	local meta = data.metamorphic_chance + ring.meta					-- Chance for metamorphic geode

	local t = mw.html.create('table')	-- Create the headers of the table
	t:addClass('wikitable sortable')
	:tag('tr')
	:tag('th')  :wikitext('Level')              :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('Rock')               :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('Hardness Penalty')   :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('Crit Chance')        :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('Double ore chance')  :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('XP Per Hour')        :attr('colspan', 3) :done()
	:tag('th')  :wikitext('Ore Per Hour')       :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('Geode Chance')       :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('Geodes Per Hour')    :attr('rowspan', 2) :done()
	:tag('th')  :wikitext('GP Per Hour')    :attr('rowspan', 2) :done()
	:done()
	:tag('tr')
	:tag('th')  :wikitext('Min')                                    :done()
	:tag('th')  :wikitext('Avg')                                    :done()
	:tag('th')  :wikitext('Max')                                    :done()
	:done()
	
	-- Critical hit bonus
	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 level boosts
	if mining_level < 99 then cape = 0 end		-- Turn off skillcape if selected without 99 mining
	local mining_level = mining_level			-- Mining level boosts
	local damage_bonus = familiar + ring.damage	-- Damage bonus
	
	-- Experience boosts (direct XP modifiers)
	local xp_boosts = 1 + avatar + aura.xp + wise + urns + bxp + dxp + raf + furnace + ramhammer.xp + custom
	if outfit.gmo == 1 then xp_boosts = xp_boosts + gmo end -- If the selected outfit applies the golden mining outfit bonus then add it to xp boosts
	if args.method == 'AFK' then spell = data.spells_m['None'] end -- Turn off crystallise if AFK

	for index,r in ipairs(data.rocks) do
		if mining_level >= r.level then	-- Remove rocks that cannot be mined at the selected mining level
			
			-- Net hardness
			local net_hardness = pick.pen - r.hardness
			if net_hardness > 0 then net_hardness = 0 end
			
			-- Critical hit chance
			local crit_chance = 0
			if		r.len_crit_chance_level == 2 then
				if		mining_level >= r.crit_chance_level[2] then crit_chance = data.crit_chances[2]
				elseif	mining_level >= r.crit_chance_level[1] then crit_chance = data.crit_chances[1]
				else												crit_chance = data.crit_chance_base end 
			elseif	r.len_crit_chance_level == 1 then
				if		mining_level >= r.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
			if args.outfit == 'Starfury Outfit' then -- Starfury's crit chance only applies to Seren stones
				if r.name == '[[Seren stones]]' then crit_chance = crit_chance + outfit.crit end
			else
				crit_chance = crit_chance + outfit.crit
			end
			
			--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_base = mining_level + math.floor(str_level/10) + net_hardness + net_crit + damage_bonus
			local damage_min = damage_base + pick.min
			local damage_avg = damage_base + pick.avg
			local damage_max = damage_base + pick.max
			
			if damage_min < 1 then damage_min = 1 end -- If negative damage due to hardness then swings do 1 damage.
			if damage_avg < 1 then damage_avg = 1 end
			if damage_max < 1 then damage_max = 1 end
			
			--XP calculations
			local xp_swing_min = math.floor(10 * damage_min * r.xp * data.base_xp)/10
			local xp_swing_avg = math.floor(10 * damage_avg * r.xp * data.base_xp)/10
			local xp_swing_max = math.floor(10 * damage_max * r.xp * data.base_xp)/10
			local xp_hr_min = xp_swing_min * data.swing_hr * method.xp
			local xp_hr_avg = xp_swing_avg * data.swing_hr * method.xp
			local xp_hr_max = xp_swing_max * data.swing_hr * method.xp
			
			--Ore calculations (average only)
			local swings_ore = r.diff / damage_avg -- Average swings per ore
			if swings_ore < 1 then swings_ore = 1 end -- Apply damage cap
			local ore_swing = 1 / swings_ore -- Average ore per swing
			local base_ore = ore_swing * (data.swing_hr * (1 - furnace)) * method.xp -- Average ore per hour
			-- Double ore chance
			local double_ore_chance = 0
			if		r.len_double_ore == 2 then
				if		mining_level >= r.double_ore_chance[2] then double_ore_chance = data.double_ore_chances[2]
				elseif	mining_level >= r.double_ore_chance[1] then double_ore_chance = data.double_ore_chances[1]
				else												double_ore_chance = data.double_ore_chance_base end
			elseif	r.len_double_ore == 1 then
				if		mining_level >= r.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 + cape -- Apply honed perk and mining cape if applicable
			-- Double ore chance (Varrock armour)
			if varrock.no > 0 then					-- Skips if no varrock armour is selected
				if r.core == 1 then					-- Skips if the rock is not a core rock
					if r.varrock[varrock.no] == 1 then	-- Checks if the armour selected applies to the rock
						double_ore_chance = double_ore_chance + (data.varrock[r.varrock_no]['effect'] * newvar)
					end
				end
			end
			-- Double ore chance (Trah hour)
			if trah == 1 then
				if r.trah == 1 then double_ore_chance = double_ore_chance + data.trah_bonus end
			end
			
			local ore_boosts = r.ore + double_ore_chance + ramhammer.ore	-- Ore multiplier
			if r.spirits == 1 then ore_boosts = ore_boosts + spirits end	-- Stone spirits
			local total_ore = base_ore * ore_boosts
			
			-- Geode chance
			local geode_chance = 0
			if		r.len_geode_chance == 2 then
				if		mining_level >= r.geode_chance_level[2] then geode_chance = data.geode_chances[2]
				elseif	mining_level >= r.geode_chance_level[1] then geode_chance = data.geode_chances[1]
				else												 geode_chance = data.geode_chance_base end
			elseif	r.len_geode_chance == 1 then
				if		mining_level >= r.geode_chance_level[1] then geode_chance = data.geode_chances[1]
				else												 geode_chance = data.geode_chance_base end
			else													 geode_chance = data.geode_chance_base end
			geode_chance = geode_chance + aura.geode + scrimshaw.geode + refined
			
			-- Rockertunities
			-- Rockertunity multiplier
			local rck_mult = 0
			if r.len_rockertunity_level == 2 then
				if mining_level >= r.rockertunity_level[2] then rck_mult = data.rockertunity_mult[2]
				elseif mining_level >= r.rockertunity_level[1] then rck_mult = data.rockertunity_mult[1]
				else rck_mult = data.rockertunity_mult_base end
			elseif r.len_rockertunity_level == 1 then
				if mining_level >= r.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
			
			-- Rockertunity XP
			local rck_xp_min = data.rck_hr * ((rck_mult * xp_swing_min) - (data.rck_loss * xp_swing_min))
			local rck_xp_avg = data.rck_hr * ((rck_mult * xp_swing_avg) - (data.rck_loss * xp_swing_avg))
			local rck_xp_max = data.rck_hr * ((rck_mult * xp_swing_max) - (data.rck_loss * xp_swing_max))
			if method.rck == 1 then
				if r.core == 1 then
					xp_hr_min = math.floor(xp_hr_min + rck_xp_min)
					xp_hr_avg = math.floor(xp_hr_avg + rck_xp_avg)
					xp_hr_max = math.floor(xp_hr_max + rck_xp_max)
					total_ore = total_ore + rck_ore
				end
			end
			
			if r.diff == 1 then total_ore = 0 end -- Remove ore for unknown HP (seren stones / arc) temporary until their HP has been decided
			
			-- Apply experience boosts and crystallise
			if r.core == 1 then
				total_ore = math.floor(10 * total_ore * spell.ore)/10
				xp_hr_min = math.floor(xp_hr_min * (xp_boosts + spell.xp))
				xp_hr_avg = math.floor(xp_hr_avg * (xp_boosts + spell.xp))
				xp_hr_max = math.floor(xp_hr_max * (xp_boosts + spell.xp))
			else
				total_ore = math.floor(10 * total_ore)/10
				xp_hr_min = math.floor(xp_hr_min * xp_boosts)
				xp_hr_avg = math.floor(xp_hr_avg * xp_boosts)
				xp_hr_max = math.floor(xp_hr_max * xp_boosts)
			end
			
			-- Total Geodes
			local geodes = ""
			if r.core == 1 then												-- Geodes only work with core rocks
				if method.rck == 1 then geodes = (base_ore + rck_ore) * geode_chance
				else					geodes = base_ore * geode_chance end
				if r.geode == 'Sedimentary' then geodes = '[[File:Sedimentary geode.png|Sedimentary geode|link=Sedimentary geode]] '..(math.floor(100*geodes)/100)
				else geodes = '[[File:Igneous geode.png|Igneous geode|link=Igneous geode]] '..(math.floor(100*(geodes*(1-meta)))/100)..' [[File:Metamorphic geode.png|Metamorphic geode|link=Metamorphic geode]] '..(math.floor(100*(geodes*meta))/100) end
			end
			
			-- Clean up values and ignore zero values for a cleaner looking calculator
			if net_hardness == 0 then net_hardness = "" end
			if total_ore == 0 then total_ore = "" end
			if r.core == 0 then geode_chance = ""
			else geode_chance = (geode_chance*100)..'%'
			end
			
			-- Calculate GPH for best ore in the category
			local gold_per_hour = -1
			if (nil == r.name_GrandExchange) == false then
				local maximal_price = 0
				for index,name in pairs(r.name_GrandExchange) do maximal_price = math.max(maximal_price, gemw.price(name)) end
				gold_per_hour = total_ore * maximal_price
			else
				gold_per_hour = 0
			end
			
			-- Populating the remaining cells in the table
			t:tag('tr')
			:tag('td')  :wikitext(r.level)                  			:css('text-align', 'center')    :done()
			:tag('td')  :wikitext(r.img..' '..r.name)           		                    	        :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(xp_hr_min))          			:css('text-align', 'center')    :done()
			:tag('td')  :wikitext("'''"..fnum(xp_hr_avg).."'''")		:css('text-align', 'center')	:done()
			:tag('td')  :wikitext(fnum(xp_hr_max))						:css('text-align', 'center')    :done()
			:tag('td')  :wikitext(fnum(total_ore) or "")       			:css('text-align', 'center')    :done()
			:tag('td')  :wikitext(geode_chance)							:css('text-align', 'center')    :done()
			:tag('td')  :wikitext(geodes)								:css('text-align', 'center')    :done()
			:tag('td')  :wikitext(fnum(gold_per_hour))					:css('text-align', 'center')    :done()
			:done()
		end
	end
	return t
end

return p