Module:Skills/Archaeology: Difference between revisions

From Melvor Idle
(_getDigSiteArtefactValue: Amend calculation of +1 and double consumable bonus GP values)
(_getDigSiteArtefactValue: Adjust wording of average value text)
Line 117: Line 117:
table.insert(result, '\r\n|}')
table.insert(result, '\r\n|}')
table.insert(result, '\r\nThe average value of one action is '..Icons.GP(Shared.round(lootValue, 2, 0))..'.')
table.insert(result, '\r\nThe average value of one action is '..Icons.GP(Shared.round(lootValue, 2, 0))..', ')
table.insert(result, '\r\n\r\nThe average value of one action with the +1 Minimum Items refinement is '..Icons.GP(Shared.round(lootValue + plusOneMinimumRefinementValue, 2, 0))..'.')
table.insert(result, 'increasing to '..Icons.GP(Shared.round(lootValue + plusOneMinimumRefinementValue, 2, 0))..' when the +1 Minimum Items refinement is active.')
if doubleConsumableRefinementValue > 0 then
if doubleConsumableRefinementValue > 0 then
table.insert(result, '\r\n\r\nThe average value of one action with the x2 Consumables refinement is '..Icons.GP(Shared.round(lootValue + doubleConsumableRefinementValue, 2, 0))..'.')
table.insert(result, '\r\n\r\nThe average value of one action with the x2 Consumables refinement is '..Icons.GP(Shared.round(lootValue + doubleConsumableRefinementValue, 2, 0))..'.')

Revision as of 20:34, 25 October 2023

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
--Crucially, stuff that involves both MUST go here
--Because otherwise we get circular references, which are Not Fun.
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 Cartography = require('Module:Skills/Cartography')

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

function p.getDigSite(name)
	name = string.gsub(name, "%%27", "'")
	name = string.gsub(name, "'", "'")
	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!!Type!!Qty')
	table.insert(result, '!!Price!!colspan="2"|Chance')
	
	local lootTable = Shared.shallowClone(digSite.artefacts[string.lower(size)])
	local lootValue = 0
	local plusOneMinimumRefinementValue = 0
	local doubleConsumableRefinementValue = 0
	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, '||'..thisItem.type..'')
		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)..'%')
		-- Setting average gp values with various parameters
		local artefactAvgValue = dropChance * thisItem.sellsFor * ((row.minQuantity + row.maxQuantity) / 2)
		lootValue = lootValue + artefactAvgValue
		plusOneMinimumRefinementValue = plusOneMinimumRefinementValue + (dropChance * thisItem.sellsFor) 
		-- Checking if item is a consumable, then adding its value a second time
        if Items._canItemUseSlot(thisItem, 'Consumable') then
            doubleConsumableRefinementValue = doubleConsumableRefinementValue + artefactAvgValue
        end
	end
	
	table.insert(result, '\r\n|}')
	table.insert(result, '\r\nThe average value of one action is '..Icons.GP(Shared.round(lootValue, 2, 0))..', ')
	table.insert(result, 'increasing to '..Icons.GP(Shared.round(lootValue + plusOneMinimumRefinementValue, 2, 0))..' when the +1 Minimum Items refinement is active.')
	if doubleConsumableRefinementValue > 0 then
		table.insert(result, '\r\n\r\nThe average value of one action with the x2 Consumables refinement is '..Icons.GP(Shared.round(lootValue + doubleConsumableRefinementValue, 2, 0))..'.')
	end
	
	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

--Trying something new this time. Building the entire infobox in Lua and then passing it to the module.
function p.getDigSiteInfobox(frame)
	local name = frame.args ~= nil and frame.args[1] or frame
	name = string.gsub(name, "%%27", "'")
	name = string.gsub(name, "&#39;", "'")
	
	local digSite = p.getDigSite(name)
	
	if digSite == nil then
		return Shared.printError('No Dig Site named '..name..' found')
	end
	
	local poi = Cartography.getPointOfInterestForDigSite(digSite.id)
	local hex = Cartography.getHexByAxial(poi.coords.q, poi.coords.r)
	local coordX, coordY = Cartography.convertAxialToXY(poi.coords)
	
	local resultArray = {}
	
	table.insert(resultArray, '{| class="wikitable infobox"')
	--Expansion Symbol + Name
	table.insert(resultArray, '\r\n!')
	table.insert(resultArray, Icons.getExpansionIcon(digSite.id))
	table.insert(resultArray, digSite.name)
	--Image
	table.insert(resultArray, '\r\n|-\r\n| style="text-align:center" |')
	table.insert(resultArray, Icons.Icon({digSite.name, type='poi', size=250, notext='true'}))
	--ID
	table.insert(resultArray, "\r\n|-\r\n|'''ID:''' ")
	table.insert(resultArray, digSite.id)
	--Coordinates
	table.insert(resultArray, "\r\n|-\r\n|'''Coordinates:''' ")
	table.insert(resultArray, '('..coordX..', '..coordY..')')
	--Requirements
	table.insert(resultArray, "\r\n|-\r\n|'''Discovery Requirements:''' ")
	local reqTable = Cartography._getPOIRequirements(poi)
	if Shared.tableCount(reqTable) == 0 then
		table.insert(resultArray, 'None')
	else
		table.insert(resultArray, '\r\n* '..table.concat(reqTable, '\r\n* '))
	end
	table.insert(resultArray, "\r\n|-\r\n|'''Archaeology Level:''' ")
	table.insert(resultArray, Icons._SkillReq('Archaeology', digSite.level))
	--Description
	table.insert(resultArray, '\r\n|-\r\n| style="text-align:center" |')
	table.insert(resultArray, "''"..poi.description.."''")
	
	table.insert(resultArray, '\r\n|}')
	table.insert(resultArray, '\n[[Category:Dig Sites]]')
	
	
	return table.concat(resultArray, '')
end

return p