Module:Skills/Archaeology: Difference between revisions

From Melvor Idle
No edit summary
m (Fixed shop link)
 
(6 intermediate revisions by 3 users not shown)
Line 6: Line 6:


local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local Common = require('Module:Common')
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
Line 33: Line 34:
end
end
return nil
return nil
end
function p._getArtefactType(item)
if item.isArtefact then
if item.isGenericArtefact then
return 'Generic'
elseif item.validSlots ~= nil then
local searchSlots = { 'Consumable', 'Gem' }
for i, slotID in ipairs(searchSlots) do
if Shared.contains(item.validSlots, slotID) then
return Common.getEquipmentSlotLink(slotID)
end
end
end
return 'Other'
end
end
end


Line 75: Line 92:
end
end
table.insert(result, '||'..thisItem.type..'')
table.insert(result, '||' .. p._getArtefactType(thisItem) .. '')
table.insert(result, '||style="text-align:right" data-sort-value="'..row.maxQuantity..'"|')
table.insert(result, '||style="text-align:right" data-sort-value="'..row.maxQuantity..'"|')
if row.maxQuantity > row.minQuantity then
if row.maxQuantity > row.minQuantity then
table.insert(result, Shared.formatnum(row.minQuantity) .. ' - ')
table.insert(result, Shared.formatnum(row.minQuantity) .. ' - ')
end
end
table.insert(result, Shared.formatnum(row.maxQuantity))
table.insert(result, Shared.formatnum(row.maxQuantity))
 
-- Adding price columns
--Adding price columns
local itemPrice = 0
local itemPrice = 0
if thisItem == nil then
if thisItem == nil then
Line 95: Line 110:
end
end
end
end
 
-- Getting the drop chance
--Getting the drop chance
local dropChance = (row.weight / totalWt)
local dropChance = (row.weight / totalWt)
if dropChance < 100 then
if dropChance < 100 then
Line 109: Line 123:
local fmt = (dropChance < 0.10 and '%.2g') or '%.2f'
local fmt = (dropChance < 0.10 and '%.2g') or '%.2f'
table.insert(result, 'style="text-align:right"|'..string.format(fmt, dropChance * 100)..'%')
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 + (dropChance * thisItem.sellsFor * ((row.minQuantity + row.maxQuantity)/ 2))
lootValue = lootValue + artefactAvgValue
plusOneMinimumRefinementValue = plusOneMinimumRefinementValue + (dropChance * thisItem.sellsFor * (((row.minQuantity+1) + (row.maxQuantity+1))/ 2))
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
end
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\nThe average value of one action with the +1 Minimum Items refinement is '..Icons.GP(Shared.round(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 > lootValue then
if doubleConsumableRefinementValue > 0 then
table.insert(result, '\r\nThe average value of one action with the x2 Consumables refinement is '..Icons.GP(Shared.round(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))..'.')
end
end
Line 190: Line 207:
return table.concat(resultArray, '')
return table.concat(resultArray, '')
end
function p._getMuseumRewards(reward)
local rewardTable = {}
local equipment = nil
if reward.gp ~= nil then
table.insert(rewardTable, Icons.GP(reward.gp))
end
if reward.items ~= nil then
for _, reward in ipairs(reward.items) do
local item = Items.getItemByID(reward.id)
table.insert(rewardTable, Icons.Icon({item.name, type='item', qty=reward.quantity}))
if item.category == 'Archaeology' then
equipment = item.name
end
end
end
if reward.modifiers ~= nil then
for modifier, value in pairs(reward.modifiers) do
table.insert(rewardTable, Constants._getModifierText(modifier, value, true))
end
end
if equipment ~= nil then
table.insert(rewardTable, 'Unlocks the ability to purchase '..equipment..' from the '..Icons.Icon({'Shop'}))
end
return rewardTable
end
function p.getMuseumRewardsTable(frame)
-- Build the table
local resultTable = mw.html.create('table')
resultTable:addClass('wikitable sortable lighttable')
resultTable:tag('tr'):addClass('headerRow-0')
:tag('th'):wikitext('Donations')
:tag('th'):wikitext('Rewards')
for _, reward in ipairs(SkillData.Archaeology.museumRewards) do
local tr = mw.html.create('tr')
tr:tag('td'):wikitext(reward.museumCount)
tr:tag('td'):wikitext(table.concat(p._getMuseumRewards(reward), '<br/>'))
resultTable:node(tr)
end
return tostring(resultTable)
end
end


return p
return p

Latest revision as of 05:38, 17 March 2024

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 Common = require('Module:Common')
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, "&#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._getArtefactType(item)
	if item.isArtefact then
		if item.isGenericArtefact then
			return 'Generic'
		elseif item.validSlots ~= nil then
			local searchSlots = { 'Consumable', 'Gem' }
			for i, slotID in ipairs(searchSlots) do
				if Shared.contains(item.validSlots, slotID) then
					return Common.getEquipmentSlotLink(slotID)
				end
			end
		end
		return 'Other'
	end
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, '||' .. p._getArtefactType(thisItem) .. '')
		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

function p._getMuseumRewards(reward)
	local rewardTable = {}
	local equipment = nil
	if reward.gp ~= nil then
		table.insert(rewardTable, Icons.GP(reward.gp))
	end
	if reward.items ~= nil then
		for _, reward in ipairs(reward.items) do
			local item = Items.getItemByID(reward.id)
			table.insert(rewardTable, Icons.Icon({item.name, type='item', qty=reward.quantity}))
			if item.category == 'Archaeology' then
				equipment = item.name
			end
		end
	end
	if reward.modifiers ~= nil then
		for modifier, value in pairs(reward.modifiers) do
			table.insert(rewardTable, Constants._getModifierText(modifier, value, true))
		end
	end
	if equipment ~= nil then
		table.insert(rewardTable, 'Unlocks the ability to purchase '..equipment..' from the '..Icons.Icon({'Shop'}))
	end
	return rewardTable
end

function p.getMuseumRewardsTable(frame)
	-- Build the table
	local resultTable = mw.html.create('table')
	resultTable:addClass('wikitable sortable lighttable')
	resultTable:tag('tr'):addClass('headerRow-0')
		:tag('th'):wikitext('Donations')
		:tag('th'):wikitext('Rewards')
		
	for _, reward in ipairs(SkillData.Archaeology.museumRewards) do
		local tr = mw.html.create('tr')
		tr:tag('td'):wikitext(reward.museumCount)
		tr:tag('td'):wikitext(table.concat(p._getMuseumRewards(reward), '<br/>'))
		resultTable:node(tr)
	end
	return tostring(resultTable)
end

return p