2,869
edits
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'] = | ['pillar'] = 6, | ||
['prayer'] = | ['spell'] = 7, | ||
['gathering'] = | ['prayer'] = 8, | ||
['artisan'] = | ['thieving'] = 9, | ||
['item'] = | ['constellation'] = 10, | ||
['combatArea'] = | ['gathering'] = 11, | ||
['slayerArea'] = | ['artisan'] = 12, | ||
['dungeon'] = | ['item'] = 13, | ||
['shop'] = | ['combatArea'] = 14, | ||
['trader'] = | ['slayerArea'] = 15, | ||
['obstacle'] = | ['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'] = ' | ['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 | ||
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 subType = args.subType | local subType = args.subType | ||
local subTypeParam = args.subTypeParam | local subTypeParam = args.subTypeParam | ||
Line 947: | Line 947: | ||
end) | end) | ||
for i, item in ipairs(itemList) do | for i, item in ipairs(itemList) do | ||
local processed = {} | local processed = {} | ||
Line 974: | Line 973: | ||
end) | end) | ||
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'] = ' | table.insert(entityList, {['entityName'] = 'Passive Pillars', ['entityType'] = 'pillar', ['subType'] = 'pillar', ['skillLevel'] = 99, ['otherReqs'] = {}}) | ||
table.insert(entityList, {['entityName'] = 'Elite Passive Pillars', ['entityType'] = ' | 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. | 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 | ||
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 | ||
if req.count > 1 then | if req.count > 1 then | ||
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 | ||
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, | 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 | 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 = | 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 == ' | 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) | ||
-- Now loop through the stuff relevant to this skill | if not itemsOnly then | ||
entityList = p._addShopPurchasesWithSkillRequirements(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 | local args = frame.args ~= nil and frame.args or frame | ||
return p._getSkillUnlockTable(skillName | local skillName = args[1] | ||
return p._getSkillUnlockTable(skillName, args) | |||
end | end | ||
return p | return p |
edits