Module:Barrows calculator

From Old School RuneScape Wiki
Jump to: navigation, search

This module does not have any documentation. Please consider adding documentation at Module:Barrows calculator/doc.


local geprice = require('Module:Exchange')._price
local coins = require('Module:Coins')._amount

local p = {}

local combatLevels = {
	Torag = 115,
	Dharok = 115,
	Verac = 115,
	Guthan = 115,
	Karil = 98,
	Ahrim = 98
}

local brothersOrder = {'Ahrim', 'Dharok', 'Guthan', 'Karil', 'Torag', 'Verac'}
local barrowsEquipment = {
	Torag = {"Torag's helm", "Torag's platebody", "Torag's platelegs", "Torag's hammers"},
	Dharok = {"Dharok's helm", "Dharok's platebody", "Dharok's platelegs", "Dharok's greataxe"},
	Verac = {"Verac's helm", "Verac's brassard", "Verac's plateskirt", "Verac's flail"},
	Guthan = {"Guthan's helm", "Guthan's platebody", "Guthan's chainskirt", "Guthan's warspear"},
	Karil = {"Karil's coif", "Karil's leathertop", "Karil's leatherskirt", "Karil's crossbow"},
	Ahrim = {"Ahrim's hood", "Ahrim's robetop", "Ahrim's robeskirt", "Ahrim's staff"}
}

local ammoBounds = {
	{item = "Coins", low = 1, high = 380, divisor = 0.5},
	{item = "Mind rune", low = 381, high = 505, divisor = 1.5, rune = true},
	{item = "Chaos rune", low = 506, high = 630, divisor = 4.5, rune = true},
	{item = "Death rune", low = 631, high = 755, divisor = 9, rune = true},
	{item = "Blood rune", low = 756, high = 880, divisor = 20, rune = true},
	{item = "Bolt rack", low = 881, high = 1005, divisor = 25},
	{item = "Loop half of key", low = 1006, high = 1008, divisor = 1000},
	{item = "Tooth half of key", low = 1009, high = 1011, divisor = 1000},
	{item = "Dragon med helm", low = 1012, high = 1012, divisor = 1000}
}

function getRewardPotential(brothers, totalcombat)
	for _, v in ipairs(brothers) do
		totalcombat = totalcombat + combatLevels[v]
	end
	return math.min(1000, totalcombat) + 2 * #brothers
end

function p.main(frame)
	local args = frame:getParent().args
	local brothersKilled = {}
	for _, bro in ipairs(brothersOrder) do
		if args[bro] == 'yes' then
			table.insert(brothersKilled, bro)
		end		
	end
	local rp = getRewardPotential(brothersKilled, args.cryptCombatLevels)
	local rolls = #brothersKilled + 1
	
	local rollsLine = "Killing "
	local bolds = {}
	for i, bro in ipairs(brothersKilled) do
		table.insert(bolds, "'''" .. bro .. "'''")
	end
	local rollsWord = "rolls"
	if #brothersKilled == 0 then
		rollsLine = rollsLine .. "no brothers"
		rollsWord = "roll"
	else
		rollsLine = rollsLine .. table.concat(bolds, ", ")
	end
	rollsLine = rollsLine .. " gives a total of '''" .. tostring(rolls) .. "''' " .. rollsWord .. " for the Barrows chest."
	
	local denominator = 450 - 58 * #brothersKilled
	localRatesLine = ""
	local totalEquipmentExpectation = 0.0
	if rolls == 1 then 
		ratesLine = "No Barrows brothers were killed, so there is no chance for Barrows equipment."
	else
		ratesLine = "Each roll gives a '''1/" .. tostring(denominator) .. "''' chance at a piece of Barrows equipment. There are '''" .. tostring(4 * #brothersKilled) .. "''' eligible pieces, so each is '''1/" .. tostring(denominator * 4 * #brothersKilled) .. "''' per roll. On average you will get 1/" .. string.format('%.2f', denominator/rolls) .. " Barrows items per chest."
		
		local barrowsTable = mw.html.create('table')
		barrowsTable:addClass('wikitable')
		barrowsTable:addClass('align-center-1')
		:tag('tr')
			:tag('th')
				:wikitext('Item')
				:attr('colspan', 2)
			:done()
			:tag('th')
				:wikitext('Price')
			:done()
			:tag('th')
				:wikitext('Expected per chest')
			:done()
			:tag('th')
				:wikitext('Expected value')
			:done()
		local singlePieceExpectation = 1.0 * rolls / (denominator * 4 * #brothersKilled)
		for _, bro in ipairs(brothersKilled) do
			for _, item in ipairs(barrowsEquipment[bro]) do
				local price = geprice(item)
				totalEquipmentExpectation = totalEquipmentExpectation + price * singlePieceExpectation
				barrowsTable:tag('tr')
					:tag('td')
						:wikitext('[[File:' .. item .. '.png|link=' .. item .. ']]')
					:done()
					:tag('td')
						:wikitext('[[' .. item .. ']]')
					:done()
					:tag('td')
						:wikitext(coins(price))
					:done()
					:tag('td')
						:wikitext(string.format('%.3f%%', 100 * singlePieceExpectation ))
					:done()	
					:tag('td')
						:wikitext(coins(price * singlePieceExpectation))
					:done()	
			end
		end
		
		barrowsTable:tag('tr')
			:tag('th')
				:attr('colspan', 4)
			:done()
			:tag('th')
				:wikitext(coins(totalEquipmentExpectation))
			:done()
		ratesLine = ratesLine .. tostring(barrowsTable)
	end
	
	local ammoLine = "Killing an additional '''" .. tostring(args.cryptCombatLevels) .. "''' combat levels worth of crypt monsters gives a total of '''" .. tostring(rp) .. "''' reward points (" .. string.format('%.1f%%', 100 * rp / 1012) .. " of max). That makes you eligible for the following rewards:"
	
	local ammoTable = mw.html.create('table')
	ammoTable:addClass('wikitable')
	ammoTable:addClass('align-center-1')
		:tag('tr')
			:tag('th')
				:wikitext('Item')
				:attr('colspan', 2)
			:done()
			:tag('th')
				:wikitext('Quantity per roll')
			:done()
			:tag('th')
				:wikitext('Price')
			:done()
			:tag('th')
				:wikitext('Chance per roll')
			:done()
			:tag('th')
				:wikitext('Expected per chest')
			:done()
			:tag('th')
				:wikitext('Expected value')
			:done()
	
	local totalAmmoExpectation = 0.0
	for _, ammo in ipairs(ammoBounds) do
		if ammo['low'] > rp then
			break
		end
		high = math.min(ammo['high'], rp)
		local lowQty = math.floor(ammo['low'] / ammo['divisor'])
		local highQty = math.floor( (high - 1) / ammo['divisor'])
		local chancePerRoll = (1 - 1/denominator) * (high - ammo['low'] + 1) / rp
		local runesMultiplier = 1.0
		if args.morytaniaHard == 'yes' and ammo['rune'] then
			runesMultiplier = 1.5
			lowQty = math.floor(lowQty * 1.5)
			highQty = math.floor(highQty * 1.5)
		end
		local expectedCount = 0.0
		for rand = ammo['low'], high do
			expectedCount = expectedCount + math.floor(runesMultiplier * math.floor(rand / ammo['divisor']))
		end
		expectedCount = (1 - 1/denominator) * rolls * expectedCount / rp
		local qtyRange = tostring(lowQty)
		if lowQty ~= highQty then
			qtyRange = tostring(lowQty) .. '-' .. tostring(highQty)
		end
		local item = ammo['item']
		local price = 1
		if item ~= "Coins" then
			price = geprice(item)
		end
		totalAmmoExpectation = totalAmmoExpectation + price * expectedCount
		ammoTable:tag('tr')
			:tag('td')
				:wikitext('[[File:' .. item .. '.png|link=' .. item .. ']]')
			:done()
			:tag('td')
				:wikitext('[[' .. item .. ']]')
			:done()
			:tag('td')
				:wikitext(qtyRange)
			:done()
			:tag('td')
				:wikitext(coins(price))
			:done()
			:tag('td')
				:wikitext(string.format('%.3f%%', 100 * chancePerRoll))
			:done()
			:tag('td')
				:wikitext(string.format('%.2f', expectedCount))
			:done()
			:tag('td')
				:wikitext(coins(price * expectedCount))
			:done()
	end
	
	ammoTable:tag('tr')
		:tag('th')
			:attr('colspan', 6)
		:done()
		:tag('th')
			:wikitext(coins(totalAmmoExpectation))
		:done()
	
	rollsLine = rollsLine .. " This chest has an expected value of '''" .. coins(totalAmmoExpectation + totalEquipmentExpectation) .. "'''."
	return rollsLine .. '\n\n' .. ammoLine .. '\n\n' .. tostring(ammoTable) .. '\n\n' .. ratesLine
	
end

return p