Module:Skills/Archaeology

From Melvor Idle
< Module:Skills
Revision as of 16:22, 15 September 2023 by Falterfire (talk | contribs) (Created initial version with getDigSite and getDigSiteArtefactTable)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Skills/Archaeology/doc

--New module for Archaeology-related tables
--Unavoidably has some overlap with Module:Skills/Cartography
local p = {}

local Shared = require('Module:Shared')
local Constants = require('Module:Constants')
local GameData = require('Module:GameData')
local SkillData = GameData.skillData
local Items = require('Module:Items')
local Icons = require('Module:Icons')

local sizes = {'small', 'tiny', 'medium', 'large'}

function p.getDigSite(name)
	name = string.gsub(name, "%%27", "'")
	name = string.gsub(name, "&#39;", "'")
	for i, digSite in ipairs(SkillData.Archaeology.digSites) do
		if digSite.name == name then
			return digSite
		end
	end
	return nil
end

function p.getDigSiteByID(id)
	for i, digSite in ipairs(SkillData.Archaeology.digSites) do
		if digSite.id == id then
			return digSite
		end
	end
	return nil
end

function p._getDigSiteArtefactTable(digSite, size)
	if not Shared.contains(sizes, string.lower(size)) then
		return Shared.printError(size..' is an invalid size for Archeology artefacts.')
	end
	
	local result = {}
	table.insert(result, '{|class="wikitable sortable" id="itemdrops"')
	table.insert(result, '\r\n!Item!!Qty')
	table.insert(result, '!!Price!!colspan="2"|Chance')
	
	local lootTable = Shared.shallowClone(digSite.artefacts[string.lower(size)])
	local totalWt = 0
	for i, row in ipairs(lootTable) do
		totalWt = totalWt + row.weight
	end
	table.sort(lootTable, function(a, b)
			if a.weight == b.weight then
				local aItem, bItem = Items.getItemByID(a.itemID), Items.getItemByID(b.itemID)
				if aItem ~= nil and bItem ~= nil then
					return aItem.name < bItem.name
				else
					return a.itemID < b.itemID
				end
			else
				return a.weight > b.weight
			end
	end)
	for i, row in ipairs(lootTable) do
		local thisItem = Items.getItemByID(row.itemID)
		
		if thisItem ~= nil then
			table.insert(result, '\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}))
		else
			table.insert(result, '\r\n|-\r\n|Unknown Item[[Category:Pages with script errors]]')
		end
		table.insert(result, '||style="text-align:right" data-sort-value="'..row.maxQuantity..'"|')

		if row.maxQuantity > row.minQuantity then
			table.insert(result, Shared.formatnum(row.minQuantity) .. ' - ')
		end
		table.insert(result, Shared.formatnum(row.maxQuantity))

		--Adding price columns
		local itemPrice = 0
		if thisItem == nil then
			table.insert(result, '||data-sort-value="0"|???')
		else
			itemPrice = thisItem.sellsFor ~= nil and thisItem.sellsFor or 0
			if itemPrice == 0 or row.maxQuantity == row.minQuantity then
				table.insert(result, '||'..Icons.GP(itemPrice * row.minQuantity))
			else
				table.insert(result, '||'..Icons.GP(itemPrice * row.minQuantity, itemPrice * row.maxQuantity))
			end
		end

		--Getting the drop chance
		local dropChance = (row.weight / totalWt)
		if dropChance < 100 then
			--Show fraction as long as it isn't going to be 1/1
			table.insert(result, '||style="text-align:right" data-sort-value="'..row.weight..'"')
			table.insert(result, '|'..Shared.fraction(row.weight, totalWt))
			table.insert(result, '||')
		else
			table.insert(result, '||colspan="2" data-sort-value="'..row.weight..'"')
		end
		-- If chance is less than 0.10% then show 2 significant figures, otherwise 2 decimal places
		local fmt = (dropChance < 0.10 and '%.2g') or '%.2f'
		table.insert(result, 'style="text-align:right"|'..string.format(fmt, dropChance * 100)..'%')
	end
	
	table.insert(result, '\r\n|}')
	
	return table.concat(result, '')
end

function p.getDigSiteArtefactTable(frame)
	local name = frame.args ~= nil and frame.args[1] or frame[1]
	local size = frame.args ~= nil and frame.args[2] or frame[2]
	
	local digSite = p.getDigSite(name)
	
	if digSite == nil then
		return Shared.printError('No Dig Site named '..name..' found')
	end
	
	return p._getDigSiteArtefactTable(digSite, size)
end

return p