Module:Skills/Archaeology
From Melvor Idle
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
lootValue = lootValue + (dropChance * thisItem.sellsFor * ((row.minQuantity + row.maxQuantity)/ 2))
plusOneMinimumRefinementValue = plusOneMinimumRefinementValue + (dropChance * thisItem.sellsFor * (((row.minQuantity+1) + (row.maxQuantity+1))/ 2))
-- Checking if item is a consumable, then adding its value a second time
if Items._canItemUseSlot(thisItem, 'Consumable') ~= nil then
doubleConsumableRefinementValue = lootValue + (dropChance * thisItem.sellsFor * ((row.minQuantity + row.maxQuantity)/ 2))
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, '\r\n\nThe average value of one action with the +1 Minimum Items refinement is '..Icons.GP(Shared.round(plusOneMinimumRefinementValue, 2, 0))..'.')
if doubleConsumableRefinementValue > lootValue then
table.insert(result, '\r\nThe average value of one action with the x2 Consumables refinement is '..Icons.GP(Shared.round(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, "'", "'")
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