Module:SkillUnlocks: Difference between revisions

no edit summary
No edit summary
No edit summary
(10 intermediate revisions by 2 users not shown)
Line 1: Line 1:
local p = {}
local p = {}


--This module polls various game data sources to produce a full list of skill
-- This module polls various game data sources to produce a full list of skill
--level unlocks for each skill. The game has a hard-coded set of "milestones"
-- level unlocks for each skill. The game has a hard-coded set of "milestones"
--for each skill that does the same thing, but it is not exhaustive and not
-- for each skill that does the same thing, but it is not exhaustive and not
--permanently visible for most combat skills.
-- permanently visible for most combat skills.
 
-- TODO: Args to filter by level range and unlock type


local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
Line 15: Line 17:
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local SkillData = GameData.skillData
local SkillData = GameData.skillData
local Num = require('Module:Number')


-- This excludes certain checks pertinent to all skills, like equipment
-- This excludes certain checks pertinent to all skills, like equipment
Line 26: Line 29:
['Prayer'] = {'prayers'},
['Prayer'] = {'prayers'},
['Slayer'] = {'areas'},
['Slayer'] = {'areas'},
['Farming'] = {'gatheringitems', 'farmingplots'},
['Farming'] = {'mastery', 'gatheringitems', 'farmingplots'},
['Township'] = {'townshipunlocks'},
['Township'] = {'townshipunlocks'},
['Woodcutting'] = {'gatheringitems'},
['Woodcutting'] = {'mastery', 'gatheringitems'},
['Fishing'] = {'gatheringitems'},
['Fishing'] = {'mastery', 'gatheringitems'},
['Firemaking'] = {'firemaking'},
['Firemaking'] = {'mastery', 'firemaking'},
['Cooking'] = {'artisanitems'},
['Cooking'] = {'mastery', 'artisanitems'},
['Mining'] = {'gatheringitems'},
['Mining'] = {'mastery', 'gatheringitems'},
['Smithing'] = {'artisanitems'},
['Smithing'] = {'mastery', 'artisanitems'},
['Thieving'] = {'thieving'},
['Thieving'] = {'mastery', 'thieving'},
['Fletching'] = {'artisanitems'},
['Fletching'] = {'mastery', 'artisanitems'},
['Crafting'] = {'artisanitems'},
['Crafting'] = {'mastery', 'artisanitems'},
['Runecrafting'] = {'artisanitems'},
['Runecrafting'] = {'mastery', 'artisanitems'},
['Herblore'] = {'artisanitems'},
['Herblore'] = {'mastery', 'artisanitems'},
['Agility'] = {'agilityslots'},
['Agility'] = {'mastery', 'agilityslots'},
['Summoning'] = {'artisanitems'},
['Summoning'] = {'mastery', 'artisanitems'},
['Astrology'] = {'constellations'},
['Astrology'] = {'mastery', 'constellations'},
['Alt. Magic'] = {'altmagic'},
['Alt. Magic'] = {'altmagic'},
}
}
Line 50: Line 53:
['plot'] = 4,
['plot'] = 4,
['obstacleslot'] = 5,
['obstacleslot'] = 5,
['spell'] = 6,
['pillar'] = 6,
['prayer'] = 7,
['spell'] = 7,
['gathering'] = 8,
['prayer'] = 8,
['artisan'] = 9,
['thieving'] = 9,
['item'] = 10,  
['constellation'] = 10,
['combatArea'] = 11,
['gathering'] = 11,
['slayerArea'] = 12,
['artisan'] = 12,
['dungeon'] = 13,
['item'] = 13,  
['shop'] = 14,
['combatArea'] = 14,
['trader'] = 15,
['slayerArea'] = 15,
['obstacle'] = 16
['dungeon'] = 16,
['shop'] = 17,
['trader'] = 18,
['obstacle'] = 19
}
}
local VERBS_PER_SUBTYPE = {
local VERBS_PER_SUBTYPE = {
Line 85: Line 91:
['ancient'] = 'Cast',
['ancient'] = 'Cast',
['archaic'] = 'Cast',
['archaic'] = 'Cast',
['prayer'] = 'Cast',
['prayer'] = 'Use',
['altMagic'] = 'Cast',
['altMagic'] = 'Cast',
['tree'] = 'Cut',
['tree'] = 'Cut',
Line 648: Line 654:
['level'] = 40,
['level'] = 40,
['entities'] = {'Rune 2H Sword', 'Rune Battleaxe', 'Rune Dagger', 'Rune Scimitar', 'Rune Sword'}
['entities'] = {'Rune 2H Sword', 'Rune Battleaxe', 'Rune Dagger', 'Rune Scimitar', 'Rune Sword'}
},
{
['verb'] = 'Wear',
['name'] = 'Melee Slayer Gear (Basic)',
['level'] = 1,
['entities'] = {'Slayer Helmet (Basic)', 'Slayer Platebody (Basic)'}
},
},
{
{
Line 859: Line 871:
end
end
end
end
-- Sort it so the results are rendered consistently
--[[
table.sort(entityList, function(a, b)
if a.type ~= b.type then
return a.type < b.type
else
end
end)
--]]
return otherReqs
return otherReqs
Line 918: Line 919:
local entityType = args.type
local entityType = args.type
local typeParam = args.typeParam
local typeParam = args.typeParam
--local passedType = typeParam ~= nil and entity[typeParam] or entityType
local subType = args.subType
local subType = args.subType
local subTypeParam = args.subTypeParam
local subTypeParam = args.subTypeParam
Line 947: Line 947:
end)
end)
-- TODO: Squeeze this into _addEntities?
for i, item in ipairs(itemList) do
for i, item in ipairs(itemList) do
local processed = {}
local processed = {}
Line 974: Line 973:
end)
end)
-- TODO: Squeeze this into _addEntities
for i, area in ipairs(areaList) do
for i, area in ipairs(areaList) do
local processed = {}
local processed = {}
Line 1,205: Line 1,203:
-- Manually add pillars
-- Manually add pillars
table.insert(entityList, {['entityName'] = 'Passive Pillars', ['entityType'] = 'obstacleslot', ['subType'] = 'pillar', ['skillLevel'] = 99, ['otherReqs'] = {}})
table.insert(entityList, {['entityName'] = 'Passive Pillars', ['entityType'] = 'pillar', ['subType'] = 'pillar', ['skillLevel'] = 99, ['otherReqs'] = {}})
table.insert(entityList, {['entityName'] = 'Elite Passive Pillars', ['entityType'] = 'obstacleslot', ['subType'] = 'pillar', ['skillLevel'] = 120, ['otherReqs'] = {}})
table.insert(entityList, {['entityName'] = 'Elite Passive Pillars', ['entityType'] = 'pillar', ['subType'] = 'pillar', ['skillLevel'] = 120, ['otherReqs'] = {}})
return entityList
return entityList
Line 1,241: Line 1,239:
processed['entityName'] = gatherable.name
processed['entityName'] = gatherable.name
elseif skillName == 'Mining' then
elseif skillName == 'Mining' then
processed['subType'] = node.type
processed['subType'] = node.category
elseif skillName == 'Farming' then
elseif skillName == 'Farming' then
processed['entityName'] = gatherable.name
processed['entityName'] = gatherable.name
Line 1,278: Line 1,276:
table.insert(entityList, processed)
table.insert(entityList, processed)
end
end
return entityList
end
function p._addSkillMastery(entityList, skillName)
-- Add the "Skill Mastery" perk when relevant
table.insert(entityList, {['entityName'] = 'Skill Mastery', ['entityType'] = 'special', ['subType'] = 'skillmastery', ['skillLevel'] = 99, ['otherReqs'] = {}})
return entityList
return entityList
Line 1,295: Line 1,300:
['farmingplots'] = p._addFarmingPlots,
['farmingplots'] = p._addFarmingPlots,
['townshipunlocks'] = p._addTownshipUnlocks,
['townshipunlocks'] = p._addTownshipUnlocks,
['agilityslots'] = p._addAgilityObstacleSlotsAndPillars
['agilityslots'] = p._addAgilityObstacleSlotsAndPillars,
['mastery'] = p._addSkillMastery
}
}


Line 1,309: Line 1,315:
else
else
for i, req in ipairs(entity.otherReqs) do
for i, req in ipairs(entity.otherReqs) do
-- TODO: "Completion" requirement
-- TODO: "Completion" requirement? Might not be needed
-- TODO: Township buildings requirement
if req.type == 'SkillLevel' then
if req.type == 'SkillLevel' then
local skillInfo = Icons.Icon({Constants.getSkillName(req.skillID), type='skill', notext='true'}) .. ' ' .. req.level
local skillInfo = Icons.Icon({Constants.getSkillName(req.skillID), type='skill', notext='true'}) .. ' ' .. req.level
Line 1,318: Line 1,323:
-- If you only need to clear it once (Impending Darkness),
-- If you only need to clear it once (Impending Darkness),
-- don't bother listing the count
-- don't bother listing the count
local appendCount = ''
if req.count > 1 then
if req.count > 1 then
appendCount = ' ' .. req.count .. ' clears'
table.insert(extraReqs, Icons.Icon({dungeonName, type='dungeon', qty=req.count, notext=true}) .. ' clears')
else
table.insert(extraReqs, Icons.Icon({dungeonName, type='dungeon', notext=true}) .. ' cleared')
end
end
local dungeonInfo = Icons.Icon({dungeonName, type='dungeon', notext=true}) .. appendCount
table.insert(extraReqs, dungeonInfo)
elseif req.type == 'MonsterKilled' then
elseif req.type == 'MonsterKilled' then
local monsterName = GameData.getEntityByID('monsters', req.monsterID).name
local monsterName = GameData.getEntityByID('monsters', req.monsterID).name
Line 1,334: Line 1,338:
table.insert(extraReqs, Shop._getPurchaseIcon({req.purchase}))
table.insert(extraReqs, Shop._getPurchaseIcon({req.purchase}))
elseif req.type == 'totalMastery' then
elseif req.type == 'totalMastery' then
table.insert(extraReqs, Shared.formatnum(req.mastery) .. ' ' .. Icons.Icon({req.skill, type='skill', notext=true}) .. ' ' .. Icons.Icon({'Mastery'}))
table.insert(extraReqs, Num.formatnum(req.mastery) .. ' ' .. Icons.Icon({req.skill, type='skill', notext=true}) .. ' ' .. Icons.Icon({'Mastery'}))
elseif req.type == 'TownshipBuilding' then
local building = Township._getBuildingByID(req.buildingID)
table.insert(extraReqs, Icons.Icon({building.name, type='building', qty=req.count}))
end
end
end
end
Line 1,351: Line 1,358:
if entity.overrideText then
if entity.overrideText then
return entity.overrideText
return entity.overrideText
end
if entity.subType == 'skillmastery' then
return 'Gain ' .. Icons.Icon({skillName, type='skill', notext='true'}) .. ' [[Mastery#The_Mastery_Pool|Skill Mastery]]'
end
end
if skillName == 'Farming' and entity.seed then
if skillName == 'Farming' and entity.seed then
Line 1,382: Line 1,392:
if entity.subType == 'fish' then
if entity.subType == 'fish' then
iconType = 'item'
iconType = 'item'
elseif entity.subType == 'Essence' or entity.subType == 'Ore' or entity.subType == 'Gem' then
elseif Shared.contains({
'melvorD:Ore',
'melvorD:Essence',
'melvorD:Gem',
'melvorItA:AbyssalOre',
'melvorItA:AbyssalGem',
'melvorItA:Outcrop',
'melvorItA:AbyssalEssence'
}, entity.subType) then
iconType = 'rock'
iconType = 'rock'
else
else
Line 1,393: Line 1,411:
end
end
if entity.entityType == 'shop' then
if entity.entityType == 'shop' then
iconType = entity.entity.contains.petID and 'pet' or 'item'
iconType = string.lower(entity.subType)
end
end
if entity.entityType == 'plot' then
if entity.entityType == 'plot' then
Line 1,402: Line 1,420:
end
end
if entity.entityType == 'obstacle' then
if entity.entityType == 'obstacle' then
iconType = 'agility'
end
if entity.entityType == 'obstacleslot' then
iconType = 'agility'
iconType = 'agility'
iconLink = 'Obstacles'
iconLink = 'Obstacles'
end
end
if entity.entityType == 'obstacleslot' then
if entity.entityType == 'pillar' then
iconType = 'agility'
iconType = 'agility'
iconLink = 'Passive_Pillars'
iconLink = 'Passive_Pillars'
Line 1,437: Line 1,458:
end
end


function p._getSkillUnlockTable(skillName)
function p._getSkillUnlockTable(skillName, args)
local itemsOnly = args.itemsOnly ~= nil and args.itemsOnly or false
-- TODO: Pass these min/max level params along to filter by them
local minLevel = args.minLevel ~= nil and args.minLevel or 0
local maxLevel = args.maxLevel ~= nil and args.maxLevel or 999
-- What do we need to check for this skill? Avoid checking everything for
-- What do we need to check for this skill? Avoid checking everything for
-- every skill to save time, except for a few broad things
-- every skill to save time, except for a few broad things
local entityList = {}
local entityList = {}
entityList = p._addItemsWithSkillRequirement(entityList, skillName)
entityList = p._addItemsWithSkillRequirement(entityList, skillName)
entityList = p._addShopPurchasesWithSkillRequirements(entityList, skillName)
entityList = p._addTraderItemsWithSkillRequirements(entityList, skillName)
entityList = p._addAgilityObstaclesWithSkillRequirements(entityList, skillName)
-- Now loop through the stuff relevant to this skill
if not itemsOnly then
for i, dataSource in ipairs(SKILL_CHECK_MAP[skillName]) do
entityList = p._addShopPurchasesWithSkillRequirements(entityList, skillName)
entityList = SOURCE_FUNCS[dataSource](entityList, skillName)
entityList = p._addTraderItemsWithSkillRequirements(entityList, skillName)
entityList = p._addAgilityObstaclesWithSkillRequirements(entityList, skillName)
-- Now loop through the stuff relevant to this skill
for i, dataSource in ipairs(SKILL_CHECK_MAP[skillName]) do
entityList = SOURCE_FUNCS[dataSource](entityList, skillName)
end
end
end
Line 1,536: Line 1,565:


function p.getSkillUnlockTable(frame)
function p.getSkillUnlockTable(frame)
local skillName = frame.args ~= nil and frame.args[1]
local args = frame.args ~= nil and frame.args or frame
return p._getSkillUnlockTable(skillName)
local skillName = args[1]
end
return p._getSkillUnlockTable(skillName, args)
 
function p.test()
local purchase = Shop.getPurchaseByID('melvorTotH:Corundum_Axe')
mw.log(Shop._getPurchaseIcon({purchase, notext='true'}))
end
end


return p
return p
2,875

edits