Module:Common: Difference between revisions

getRequirementString: Support requirement type MasteryLevel
No edit summary
(getRequirementString: Support requirement type MasteryLevel)
 
(8 intermediate revisions by 2 users not shown)
Line 14: Line 14:
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Num = require('Module:Number')


-- getSkillName: Given a valid namespaced skill ID, returns that skill's name
-- getSkillName: Given a valid namespaced skill ID, returns that skill's name
Line 30: Line 31:
end
end
end
end
end
-- getSkillRecipeKey: Given a skill ID, returns the key under which all recipes
-- for that skill reside. If the returned value is nil, then the skill has
-- no recipes (that is, the skill does not produce any items)
function p.getSkillRecipeKey(skillID)
-- Convert skillID to local ID if not already
local ns, localSkillID = Shared.getLocalID(skillID)
local recipeIDs = {
["Woodcutting"] = 'trees',
["Fishing"] = 'fish',
["Firemaking"] = 'logs',
["Mining"] = 'rockData',
["Thieving"] = 'npcs',
["Agility"] = 'obstacles',
["Cooking"] = 'recipes',
["Smithing"] = 'recipes',
["Farming"] = 'recipes',
["Summoning"] = 'recipes',
["Fletching"] = 'recipes',
["Crafting"] = 'recipes',
["Runecrafting"] = 'recipes',
["Herblore"] = 'recipes',
["Astrology"] = 'recipes',
["Harvesting"] = 'veinData',
["Township"] = 'buildings'
}
return recipeIDs[localSkillID]
end
end


Line 111: Line 140:
end
end


-- getPurchaseIcon: Accepts the same arguments as Icons.Icon(), except the first parameter is a
-- getPurchaseIconType: Given a purchase from shop dtaa, returns the icon type to be used within
-- shop purchase rather than the icon/linked page name
-- Icons.Icon() to retrieve the purchase's icon
function p.getPurchaseIcon(iconArgs)
function p.getPurchaseIconType(purchase)
local purchase = iconArgs[1]
local purchaseName = p.getPurchaseName(purchase)
local purchType = p.getPurchaseType(purchase)
local purchType = p.getPurchaseType(purchase)
local iconType = nil
if purchType == 'Item Bundle' then
if purchType == 'Item Bundle' then
local upgBundles = {
local upgBundles = {
Line 125: Line 151:
'melvorAoD:Combat_Supply_I',
'melvorAoD:Combat_Supply_I',
'melvorAoD:Combat_Supply_II',
'melvorAoD:Combat_Supply_II',
'melvorAoD:Combat_Supply_III'
'melvorAoD:Combat_Supply_III',
'melvorItA:Abyssal_Resupply',
'melvorItA:Blighted_Resupply',
'melvorItA:Withering_Resupply'
}
}
if Shared.contains(upgBundles, purchase.id) then
if Shared.contains(upgBundles, purchase.id) then
iconType = 'upgrade'
return 'upgrade'
else
else
iconType = 'item'
return 'item'
end
end
else
else
iconType = string.lower(purchType)
return string.lower(purchType)
end
end
end
-- getPurchaseIcon: Accepts the same arguments as Icons.Icon(), except the first parameter is a
-- shop purchase rather than the icon/linked page name
function p.getPurchaseIcon(iconArgs)
local purchase = iconArgs[1]
local purchaseName = p.getPurchaseName(purchase)
local iconType = p.getPurchaseIconType(purchase)
-- Amend iconArgs before passing to Icons.Icon()
-- Amend iconArgs before passing to Icons.Icon()
iconArgs[1] = purchaseName
iconArgs[1] = purchaseName
Line 145: Line 183:
-- for those costs. If there are no costs, returns the value specified by valueIfNone instead.
-- for those costs. If there are no costs, returns the value specified by valueIfNone instead.
-- Costs are in the format:
-- Costs are in the format:
-- { items = { ... }, gp = 0, sc = 0, rc = 0 }
-- { items = { ... }, currencies = { ... } }
function p.getCostString(costs, valueIfNone)
function p.getCostString(costs, valueIfNone, entryDecorator, entrySeparator)
local function formatLine(text)
if entryDecorator == nil then
return text
else
return entryDecorator(text)
end
end
local entrySep = entrySeparator
if type(entrySeparator) ~= 'string' then
entrySep = '<br>'
end
 
local costArray = {}
local costArray = {}
if type(costs.currencies) == 'table' and not Shared.tableIsEmpty(costs.currencies) then
for i, currCost in ipairs(costs.currencies) do
local currID = currCost.id or currCost.currencyID
if currCost.min ~= nil then
-- Cost is a range
table.insert(costArray, formatLine(Icons._Currency(currID, currCost.min, currCost.max)))
else
table.insert(costArray, formatLine(Icons._Currency(currID, currCost.quantity)))
end
end
end
if type(costs.items) == 'table' and not Shared.tableIsEmpty(costs.items) then
if type(costs.items) == 'table' and not Shared.tableIsEmpty(costs.items) then
for i, itemCost in ipairs(costs.items) do
for i, itemCost in ipairs(costs.items) do
local item = GameData.getEntityByID('items', itemCost.id)
local item = GameData.getEntityByID('items', itemCost.id)
if item ~= nil then
if item ~= nil then
table.insert(costArray, Icons.Icon({item.name, type='item', qty=itemCost.quantity}))
table.insert(costArray, formatLine(Icons.Icon({item.name, type='item', qty=itemCost.quantity})))
end
end
end
end
end
if costs.gp ~= nil and costs.gp > 0 then
table.insert(costArray, Icons.GP(costs.gp))
end
if costs.sc ~= nil and costs.sc > 0 then
table.insert(costArray, Icons.SC(costs.sc))
end
if costs.rc ~= nil and costs.rc > 0 then
table.insert(costArray, Icons.RC(costs.rc))
end
end
if Shared.tableIsEmpty(costArray) then
if Shared.tableIsEmpty(costArray) then
return valueIfNone
return valueIfNone
else
else
return table.concat(costArray, '<br/>')
return table.concat(costArray, entrySep)
end
end
end
end
Line 182: Line 234:
local reqArray = {}
local reqArray = {}
for i, req in ipairs(reqs) do
for i, req in ipairs(reqs) do
if req.type == 'AllSkillLevels' then
if req.type == 'AbyssalLevel' then
local skillName = p.getSkillName(req.skillID)
if skillName ~= nil then
table.insert(reqArray, Icons._SkillReq(skillName, req.level, nil, 'melvorItA:Abyssal'))
end
elseif req.type == 'AbyssDepthCompletion' then
local depth = GameData.getEntityByID('abyssDepths', req.depthID)
if depth ~= nil then
local depthStr = 'Complete ' .. Icons.Icon({depth.name, type='combatArea'})
if req.count > 1 then
depthStr = depthStr .. ' ' .. Num.formatnum(req.count) .. ' times'
end
table.insert(reqArray, depthStr)
end
elseif req.type == 'AllSkillLevels' then
local reqText = 'Level ' .. req.level .. ' in all skills'
local reqText = 'Level ' .. req.level .. ' in all skills'
if req.exceptions ~= nil and not Shared.tableIsEmpty(req.exceptions) then
if req.exceptions ~= nil and not Shared.tableIsEmpty(req.exceptions) then
Line 196: Line 262:
table.insert(reqArray, reqText)
table.insert(reqArray, reqText)
elseif req.type == 'ArchaeologyItemsDonated' then
elseif req.type == 'ArchaeologyItemsDonated' then
table.insert(reqArray, 'Donate ' .. Shared.formatnum(req.count) .. ' Artefacts to the Museum in ' .. Icons.Icon({'Archaeology', type='skill'}))
table.insert(reqArray, 'Donate ' .. Num.formatnum(req.count) .. ' Artefacts to the Museum in ' .. Icons.Icon({'Archaeology', type='skill'}))
elseif req.type == 'CartographyPOIDiscovery' then
elseif req.type == 'CartographyPOIDiscovery' then
local map = GameData.getEntityByID(GameData.skillData.Cartography.worldMaps, req.worldMapID)
local map = GameData.getEntityByID(GameData.skillData.Cartography.worldMaps, req.worldMapID)
Line 221: Line 287:
local dungStr = 'Complete ' .. Icons.Icon({dung.name, type='dungeon'})
local dungStr = 'Complete ' .. Icons.Icon({dung.name, type='dungeon'})
if req.count > 1 then
if req.count > 1 then
dungStr = dungStr .. ' ' .. Shared.formatnum(req.count) .. ' times'
dungStr = dungStr .. ' ' .. Num.formatnum(req.count) .. ' times'
end
end
table.insert(reqArray, dungStr)
table.insert(reqArray, dungStr)
Line 229: Line 295:
if item ~= nil then
if item ~= nil then
table.insert(reqArray, 'Find ' .. Icons.Icon({item.name, type='item'}))
table.insert(reqArray, 'Find ' .. Icons.Icon({item.name, type='item'}))
end
elseif req.type == 'MasteryLevel' then
local skill = GameData.getSkillData(req.skillID)
local recipeKey = p.getSkillRecipeKey(req.skillID)
if skill ~= nil then
local action = GameData.getEntityByID(skill[recipeKey], req.actionID)
if action ~= nil then
table.insert(reqArray, Icons._MasteryReq(action.name, req.level, true))
end
end
end
elseif req.type == 'MonsterKilled' then
elseif req.type == 'MonsterKilled' then
Line 251: Line 326:
end
end
elseif req.type == 'SlayerTask' then
elseif req.type == 'SlayerTask' then
table.insert(reqArray, 'Complete ' .. Shared.formatnum(req.count) .. ' ' .. req.tier .. ' Slayer Tasks')
local taskCategory = GameData.getEntityByID('slayerTaskCategories', req.category)
if taskCategory ~= nil then
table.insert(reqArray, 'Complete ' .. Num.formatnum(req.count) .. ' ' .. taskCategory.name .. ' or higher Slayer Tasks')
end
elseif req.type == 'TownshipBuilding' then
elseif req.type == 'TownshipBuilding' then
local tsData = GameData.getSkillData('melvorD:Township')
local tsData = GameData.getSkillData('melvorD:Township')
Line 257: Line 335:
local building = GameData.getEntityByID(tsData.buildings, req.buildingID)
local building = GameData.getEntityByID(tsData.buildings, req.buildingID)
if building ~= nil then
if building ~= nil then
table.insert(reqArray, 'Have ' .. Shared.formatnum(req.count) .. ' ' .. building.name .. ' actively built in Township')
table.insert(reqArray, 'Have ' .. Num.formatnum(req.count) .. ' ' .. building.name .. ' actively built in Township')
end
end
end
end
elseif req.type == 'TownshipTask' then
elseif req.type == 'TownshipTask' then
table.insert(reqArray, 'Complete ' .. Shared.formatnum(req.count) .. ' Township Tasks')
table.insert(reqArray, 'Complete ' .. Num.formatnum(req.count) .. ' Township Tasks')
else
else
table.insert(reqArray, Shared.printError('Unknown requirement: ' .. (req.type or 'nil')))
table.insert(reqArray, Shared.printError('Unknown requirement: ' .. (req.type or 'nil')))
Line 271: Line 349:
else
else
return table.concat(reqArray, '<br/>')
return table.concat(reqArray, '<br/>')
end
end
-- 123 => 00:02:03
function p.secondsToHMS(s)
local ONE_DAY = 24 * 60 * 60
if s > ONE_DAY then
return string.format('%d day%s, ', s/ONE_DAY, (math.floor(s/ONE_DAY) > 1) and "s" or "") .. os.date("!%X", s)
else
return os.date("!%X", s)
end
end
-- 123 => 2 minutes, 3 seconds
function p.secondsToHuman(s)
if s < 60 then
if s > 0 or s < 0 then
return string.format('%.1f seconds', s)
else
return string.format('0 seconds', s)
end
end
local days = math.floor(s / (24 * 60 * 60))
local hours = math.floor(s / (60 * 60) % (24))
local minutes = math.floor(s / 60 % 60)
local seconds = math.floor(s % (60))
local output = {}
if days > 0 then
table.insert(output, string.format('%d day%s', days, (days > 1) and "s" or ""))
end
if hours > 0 then
table.insert(output, string.format('%d hour%s', hours, (hours > 1) and "s" or ""))
end
if minutes > 0 then
table.insert(output, string.format('%d minute%s', minutes, (minutes > 1) and "s" or ""))
end
if seconds > 0 then
table.insert(output, string.format('%d second%s', seconds, (seconds > 1) and "s" or ""))
end
return table.concat(output, ", ")
end
function p.testSecondsToHuman(s)
output = {}
for i, s in ipairs(
{-1, 0, 0.5, 5 * 60, 5 * 60 + 20,
6 * 60 * 60, 6 * 60 * 60 + 20, 6 * 60 * 60 + 3 * 60 + 20,
1 * 24 * 60 * 60, 2 * 24 * 60 * 60 + 3 * 60 * 60 + 2 * 60 + 1}) do
table.insert(output, string.format('%s = %s', s, p.secondsToHuman(s)))
end
return table.concat(output, ' || ')
end
function p.prettyPrintTime(frame)
if frame == nil then
return '<invalid frame object>'
end
if frame.args[1] == nil then
return '<missing argument seconds>'
end
local seconds = tonumber(frame.args[1])
if frame.args["hms"] ~= "" then
return p.secondsToHMS(seconds)
else
return p.secondsToHuman(seconds)
end
end
end
end


return p
return p