2,875
edits
No edit summary |
No edit summary |
||
(13 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 12: | Line 14: | ||
local CombatAreas = require('Module:CombatAreas') | local CombatAreas = require('Module:CombatAreas') | ||
local Shop = require('Module:Shop') | local Shop = require('Module:Shop') | ||
local Township = require('Module:Township') | |||
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 | |||
local SKILL_CHECK_MAP = { | local SKILL_CHECK_MAP = { | ||
['Attack'] = {}, | ['Attack'] = {}, | ||
Line 24: | Line 29: | ||
['Prayer'] = {'prayers'}, | ['Prayer'] = {'prayers'}, | ||
['Slayer'] = {'areas'}, | ['Slayer'] = {'areas'}, | ||
['Farming'] = {' | ['Farming'] = {'mastery', 'gatheringitems', 'farmingplots'}, | ||
['Township'] = {}, | ['Township'] = {'townshipunlocks'}, | ||
['Woodcutting'] = {' | ['Woodcutting'] = {'mastery', 'gatheringitems'}, | ||
['Fishing'] = {' | ['Fishing'] = {'mastery', 'gatheringitems'}, | ||
['Firemaking'] = {'firemaking'}, | ['Firemaking'] = {'mastery', 'firemaking'}, | ||
['Cooking'] = {' | ['Cooking'] = {'mastery', 'artisanitems'}, | ||
['Mining'] = {' | ['Mining'] = {'mastery', 'gatheringitems'}, | ||
['Smithing'] = {' | ['Smithing'] = {'mastery', 'artisanitems'}, | ||
['Thieving'] = {' | ['Thieving'] = {'mastery', 'thieving'}, | ||
['Fletching'] = {' | ['Fletching'] = {'mastery', 'artisanitems'}, | ||
['Crafting'] = {' | ['Crafting'] = {'mastery', 'artisanitems'}, | ||
['Runecrafting'] = {' | ['Runecrafting'] = {'mastery', 'artisanitems'}, | ||
['Herblore'] = {' | ['Herblore'] = {'mastery', 'artisanitems'}, | ||
['Agility'] = {}, | ['Agility'] = {'mastery', 'agilityslots'}, | ||
['Summoning'] = {' | ['Summoning'] = {'mastery', 'artisanitems'}, | ||
['Astrology'] = {}, | ['Astrology'] = {'mastery', 'constellations'}, | ||
['Alt. Magic'] = {'altmagic'}, | ['Alt. Magic'] = {'altmagic'}, | ||
} | } | ||
local TYPE_SORT_ORDER = { | local TYPE_SORT_ORDER = { | ||
['spell'] = | ['special'] = 1, | ||
['prayer'] = | ['biome'] = 2, | ||
['gathering'] = | ['building'] = 3, | ||
['artisan'] = | ['plot'] = 4, | ||
['item'] = | ['obstacleslot'] = 5, | ||
['combatArea'] = | ['pillar'] = 6, | ||
['slayerArea'] = | ['spell'] = 7, | ||
['dungeon'] = | ['prayer'] = 8, | ||
['thieving'] = 9, | |||
['constellation'] = 10, | |||
['gathering'] = 11, | |||
['artisan'] = 12, | |||
['item'] = 13, | |||
['combatArea'] = 14, | |||
['slayerArea'] = 15, | |||
['dungeon'] = 16, | |||
['shop'] = 17, | |||
['trader'] = 18, | |||
['obstacle'] = 19 | |||
} | } | ||
local VERBS_PER_SUBTYPE = { | local VERBS_PER_SUBTYPE = { | ||
Line 58: | Line 74: | ||
['Magic Book'] = 'Wield', | ['Magic Book'] = 'Wield', | ||
['Ranged Weapon'] = 'Wield', | ['Ranged Weapon'] = 'Wield', | ||
['Ammo'] = ' | ['Ammo'] = 'Wield', | ||
['Equipment'] = 'Wear', | ['Equipment'] = 'Wear', | ||
['Armour'] = 'Wear', | ['Armour'] = 'Wear', | ||
Line 75: | Line 91: | ||
['ancient'] = 'Cast', | ['ancient'] = 'Cast', | ||
['archaic'] = 'Cast', | ['archaic'] = 'Cast', | ||
['prayer'] = ' | ['prayer'] = 'Use', | ||
['altMagic'] = 'Cast', | ['altMagic'] = 'Cast', | ||
['tree'] = 'Cut', | ['tree'] = 'Cut', | ||
Line 89: | Line 105: | ||
['melvorF:SkillPotions'] = 'Brew', | ['melvorF:SkillPotions'] = 'Brew', | ||
['melvorF:CombatPotions'] = 'Brew', | ['melvorF:CombatPotions'] = 'Brew', | ||
['log'] = 'Burn' | ['log'] = 'Burn', | ||
['npc'] = 'Pickpocket', | |||
['constellation'] = 'Study', | |||
['shop'] = 'Purchase', | |||
['plot'] = 'New', | |||
['biome'] = 'Access', | |||
['basicBuilding'] = 'Build', | |||
['trader'] = 'Trade for', | |||
['obstacle'] = 'Build', | |||
['obstacleslot'] = 'Build', | |||
['pillar'] = 'Build' | |||
} | } | ||
local SUBTYPE_OVERRIDES = { | local SUBTYPE_OVERRIDES = { | ||
Line 108: | Line 134: | ||
} | } | ||
local SUBTYPE_SORT_OVERRIDES = { | local SUBTYPE_SORT_OVERRIDES = { | ||
['melvorD:Bars'] = '1', | |||
['melvorF:StandardRunes'] = '1', | ['melvorF:StandardRunes'] = '1', | ||
['log'] = '1' | ['log'] = '1' | ||
Line 627: | 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 795: | Line 828: | ||
['level'] = 40, | ['level'] = 40, | ||
['entities'] = {'Yew Longbow', 'Yew Shortbow'} | ['entities'] = {'Yew Longbow', 'Yew Shortbow'} | ||
}, | |||
{ | |||
['verb'] = 'Purchase', | |||
['name'] = 'Skill Hats', | |||
['level'] = 10, | |||
['entities'] = {'Blacksmiths Hat', 'Burning Mans Hat', 'Crafters Hat', 'Fishermans Hat', 'Fletchers Hat', 'Miners Hat', 'Performance Enhancing Hat', 'Potion Makers Hat', 'Runecrafters Hat', 'Star Gazing Hat', 'Woodcutters Hat'} | |||
}, | |||
{ | |||
['verb'] = 'Purchase', | |||
['name'] = 'Skill Bodies', | |||
['level'] = 20, | |||
['entities'] = {'Blacksmiths Body', 'Burning Mans Body', 'Crafters Body', 'Fishermans Body', 'Fletchers Body', 'Miners Body', 'Performance Enhancing Body', 'Potion Makers Body', 'Runecrafters Body', 'Star Gazing Body', 'Woodcutters Body'} | |||
}, | |||
{ | |||
['verb'] = 'Purchase', | |||
['name'] = 'Skill Leggings', | |||
['level'] = 40, | |||
['entities'] = {'Blacksmiths Leggings', 'Burning Mans Leggings', 'Crafters Leggings', 'Fishermans Leggings', 'Fletchers Leggings', 'Miners Leggings', 'Performance Enhancing Leggings', 'Potion Makers Leggings', 'Runecrafters Leggings', 'Star Gazing Leggings', 'Woodcutters Leggings'} | |||
}, | |||
{ | |||
['verb'] = 'Purchase', | |||
['name'] = 'Skill Boots', | |||
['level'] = 60, | |||
['entities'] = {'Blacksmiths Boots', 'Burning Mans Boots', 'Crafters Boots', 'Fishermans Boots', 'Fletchers Boots', 'Miners Boots', 'Performance Enhancing Boots', 'Potion Makers Boots', 'Runecrafters Boots', 'Star Gazing Boots', 'Woodcutters Boots'} | |||
} | } | ||
} | } | ||
Line 814: | Line 871: | ||
end | end | ||
end | end | ||
return otherReqs | return otherReqs | ||
Line 865: | Line 911: | ||
return reqs | return reqs | ||
end | |||
function p._addEntities(frame) | |||
local args = frame.args ~= nil and frame.args or frame | |||
local entityList = args[1] | |||
local data = args[2] | |||
local entityType = args.type | |||
local typeParam = args.typeParam | |||
local subType = args.subType | |||
local subTypeParam = args.subTypeParam | |||
local otherReqsFunc = args.otherReqsFunc | |||
for i, entity in ipairs(data) do | |||
local processed = {} | |||
processed.entityName = entity.name | |||
processed.entityType = p._getEntityTrueSubtype(typeParam ~= nil and entity[typeParam] or entityType) | |||
processed.subType = subTypeParam ~= nil and entity[subTypeParam] or subType | |||
processed.skillLevel = entity.level | |||
processed.otherReqs = otherReqsFunc ~= nil and otherReqsFunc(entity) or {} | |||
table.insert(entityList, processed) | |||
end | |||
return entityList | |||
end | end | ||
Line 878: | Line 947: | ||
end) | end) | ||
for i, item in ipairs(itemList) do | for i, item in ipairs(itemList) do | ||
local processed = {} | local processed = {} | ||
Line 907: | Line 975: | ||
for i, area in ipairs(areaList) do | for i, area in ipairs(areaList) do | ||
local processed = {} | local processed = {} | ||
processed.entityName = area.name | processed.entityName = area.name | ||
processed.entityType = area.type | processed.entityType = area.type | ||
Line 923: | Line 990: | ||
end | end | ||
function p. | function p._addShopPurchasesWithSkillRequirements(entityList, skillName) | ||
local purchaseList = Shop.getPurchases(function(purchase) | |||
local hasSkillReq = false | |||
for i, req in ipairs(purchase.purchaseRequirements) do | |||
if req.type == 'SkillLevel' and req.skillID == Constants.getSkillID(skillName) then | |||
hasSkillReq = true | |||
end | |||
end | |||
return hasSkillReq | |||
end) | |||
for i, purchase in ipairs(purchaseList) do | |||
-- Skip skillcapes here, as we handle them with items | |||
if purchase.category ~= 'melvorD:Skillcapes' and purchase.category ~= 'melvorTotH:SuperiorSkillcapes' then | |||
local processed = {} | |||
processed.entity = purchase | |||
processed.entityName = Shop._getPurchaseName(purchase) | |||
processed.entityType = 'shop' | |||
processed.subType = Shop._getPurchaseType(purchase) | |||
for a, req in ipairs(purchase.purchaseRequirements) do | |||
if req.type == 'SkillLevel' and req.skillID == Constants.getSkillID(skillName) then | |||
processed.skillLevel = req.level | |||
end | |||
end | |||
processed.otherReqs = p._getOtherSkillReqs(purchase.purchaseRequirements, skillName) | |||
table.insert(entityList, processed) | |||
end | |||
end | |||
return entityList | |||
end | |||
function p._addTraderItemsWithSkillRequirements(entityList, skillName) | |||
-- Iterate over each tradable resource, then each item you can get with it | |||
for i, tsResource in ipairs(Township.Township.itemConversions.fromTownship) do | |||
for j, tsPurchase in ipairs(tsResource.items) do | |||
-- Does this purchase require the current skill? | |||
local hasCurrentSkill = false | |||
local currentSkillLevel = 0 | |||
for k, req in ipairs(tsPurchase.unlockRequirements) do | |||
if req.type == 'SkillLevel' and req.skillID == Constants.getSkillID(skillName) then | |||
hasCurrentSkill = true | |||
currentSkillLevel = req.level | |||
end | |||
end | |||
if hasCurrentSkill then | |||
local item = Items.getItemByID(tsPurchase.itemID) | |||
local processed = {} | |||
processed.entity = item | |||
processed.entityName = item.name | |||
processed.entityType = 'trader' | |||
processed.subType = 'trader' | |||
processed.skillLevel = currentSkillLevel | |||
processed.otherReqs = p._getOtherSkillReqs(tsPurchase.unlockRequirements, skillName) | |||
table.insert(entityList, processed) | |||
end | |||
end | |||
end | |||
return entityList | |||
end | |||
function p._addAgilityObstaclesWithSkillRequirements(entityList, skillName) | |||
for i, obstacle in ipairs(SkillData.Agility.obstacles) do | |||
for j, req in ipairs(obstacle.skillRequirements) do | |||
-- Does this obstacle require the current skill? | |||
local hasCurrentSkill = false | |||
local currentSkillLevel = 0 | |||
if req.type == 'SkillLevel' and req.skillID == Constants.getSkillID(skillName) then | |||
hasCurrentSkill = true | |||
currentSkillLevel = req.level | |||
end | |||
if hasCurrentSkill then | |||
local processed = {} | |||
processed.entity = obstacle | |||
processed.entityName = obstacle.name | |||
processed.entityType = 'obstacle' | |||
-- Category is zero-indexed | |||
processed.subType = 'Obstacle ' .. tostring(obstacle.category + 1) | |||
processed.skillLevel = currentSkillLevel | |||
processed.otherReqs = p._getOtherSkillReqs(obstacle.skillRequirements, skillName) | |||
table.insert(entityList, processed) | |||
end | |||
end | |||
end | |||
return entityList | |||
end | |||
function p._addSpells(entityList, skillName) | |||
-- Alt. Magic is in a separate function | -- Alt. Magic is in a separate function | ||
local SPELL_TYPES = {'standardSpells', 'auroraSpells', 'curseSpells', 'ancientSpells', 'archaicSpells'} | local SPELL_TYPES = {'standardSpells', 'auroraSpells', 'curseSpells', 'ancientSpells', 'archaicSpells'} | ||
Line 929: | Line 1,088: | ||
-- Iterate through each spell type and each spell within that type | -- Iterate through each spell type and each spell within that type | ||
for i, spellType in ipairs(SPELL_TYPES) do | for i, spellType in ipairs(SPELL_TYPES) do | ||
entityList = p._addEntities({entityList, GameData.rawData[spellType], type='spell', subTypeParam='spellBook', otherReqsFunc=p._getSpellReqs}) | |||
end | end | ||
Line 944: | Line 1,094: | ||
end | end | ||
function p. | function p._addAltMagic(entityList, skillName) | ||
entityList = p._addEntities({entityList, GameData.getSkillData('melvorD:Magic')['altSpells'], type='spell', subType='altMagic', otherReqsFunc=p._getSpellReqs}) | |||
return entityList | |||
end | |||
function p._addPrayers(entityList, skillName) | |||
entityList = p._addEntities({entityList, GameData.rawData.prayers, type='prayer', subType='prayer'}) | |||
return entityList | |||
end | |||
function p._addFiremakingActions(entityList, skillName) | |||
for i, fireLog in ipairs(SkillData.Firemaking.logs) do | |||
local processed = {} | local processed = {} | ||
local logItem = Items.getItemByID(fireLog.logID) | |||
processed.entityName = | processed.entityName = logItem.name | ||
processed.entityType = ' | processed.entityType = 'item' | ||
processed.subType = | processed.subType = 'log' | ||
processed.skillLevel = | processed.skillLevel = fireLog.level | ||
processed.otherReqs = | processed.otherReqs = {} | ||
table.insert(entityList, processed) | table.insert(entityList, processed) | ||
end | end | ||
Line 959: | Line 1,119: | ||
end | end | ||
function p. | function p._addThievingTargets(entityList, skillName) | ||
for i, | entityList = p._addEntities({entityList, SkillData.Thieving.npcs, type='thieving', subType='npc'}) | ||
return entityList | |||
end | |||
function p._addConstellations(entityList, skillName) | |||
entityList = p._addEntities({entityList, SkillData.Astrology.recipes, type='constellation', subType='constellation'}) | |||
return entityList | |||
end | |||
function p._addFarmingPlots(entityList, skillName) | |||
for i, plot in ipairs(SkillData.Farming.plots) do | |||
local plotName = 'Unknown Plot' | |||
if plot.categoryID == 'melvorD:Allotment' then | |||
plotName = 'Allotment Plot' | |||
elseif plot.categoryID == 'melvorD:Herb' then | |||
plotName = 'Herb Plot' | |||
elseif plot.categoryID == 'melvorD:Tree' then | |||
plotName = 'Tree Plot' | |||
end | |||
local processed = {} | local processed = {} | ||
processed.entityName = plotName | |||
processed.entityName = | processed.entityType = 'plot' | ||
processed.entityType = ' | processed.subType = plot.categoryID | ||
processed.subType = | processed.skillLevel = plot.level | ||
processed.skillLevel = | |||
processed.otherReqs = {} | processed.otherReqs = {} | ||
table.insert(entityList, processed) | table.insert(entityList, processed) | ||
Line 974: | Line 1,152: | ||
end | end | ||
function p. | function p._addTownshipUnlocks(entityList, skillName) | ||
for i, | -- This one is weird, because some of the data uses tiers and not levels | ||
-- Add all of the biomes | |||
for i, biome in ipairs(Township.Township.biomes) do | |||
local tierReqs = Township._getTierRequirements(biome.tier) | |||
local processed = {} | |||
processed.entityName = biome.name | |||
processed.entityType = 'biome' | |||
processed.subType = 'biome' | |||
processed.skillLevel = tierReqs.level | |||
processed.otherReqs = {['population'] = tierReqs.population} | |||
table.insert(entityList, processed) | |||
end | |||
-- Add all of the buildings | |||
for i, building in ipairs(Township.Township.buildings) do | |||
local tierReqs = Township._getTierRequirements(building.tier) | |||
local processed = {} | |||
processed.entityName = building.name == 'Statues' and 'Statue of Worship' or building.name | |||
processed.entityType = 'building' | |||
processed.subType = building.upgradesFrom ~= nil and 'upgradedBuilding' or 'basicBuilding' | |||
processed.upgradesFrom = Township._getBuildingDowngrade(building) | |||
processed.skillLevel = tierReqs.level | |||
processed.otherReqs = {['population'] = tierReqs.population} | |||
table.insert(entityList, processed) | |||
end | |||
-- Add the fact that health starts decreasing at level 15 | |||
local specialHealth = { | |||
['entityType'] = 'special', | |||
['subType'] = 'special', | |||
['skillLevel'] = 15, | |||
['overrideText'] = 'Township health has a 25% chance to decrease by 1% per update' | |||
} | |||
table.insert(entityList, specialHealth) | |||
return entityList | |||
end | |||
function p._addAgilityObstacleSlotsAndPillars(entityList, skillName) | |||
for i, level in ipairs(SkillData.Agility.obstacleUnlockLevels) do | |||
local processed = {} | local processed = {} | ||
processed.entityName = 'Obstacle ' .. i | |||
processed.entityName = | processed.entityType = 'obstacleslot' | ||
processed.entityType = ' | processed.subType = 'obstacleslot' | ||
processed.subType = ' | processed.skillLevel = level | ||
processed.skillLevel = | |||
processed.otherReqs = {} | processed.otherReqs = {} | ||
table.insert(entityList, processed) | table.insert(entityList, processed) | ||
end | end | ||
-- Manually add pillars | |||
table.insert(entityList, {['entityName'] = 'Passive Pillars', ['entityType'] = 'pillar', ['subType'] = 'pillar', ['skillLevel'] = 99, ['otherReqs'] = {}}) | |||
table.insert(entityList, {['entityName'] = 'Elite Passive Pillars', ['entityType'] = 'pillar', ['subType'] = 'pillar', ['skillLevel'] = 120, ['otherReqs'] = {}}) | |||
return entityList | return entityList | ||
end | end | ||
function p. | function p._addGatherables(entityList, skillName) | ||
-- Figure out what to look up based on the skill | -- Figure out what to look up based on the skill | ||
local sourceData = {} | local sourceData = {} | ||
Line 1,019: | 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,034: | Line 1,254: | ||
end | end | ||
function p. | function p._addRecipes(entityList, skillName) | ||
-- Figure out what to look up based on the skill | -- Figure out what to look up based on the skill | ||
local sourceData = SkillData[skillName].recipes | local sourceData = SkillData[skillName].recipes | ||
Line 1,056: | 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,062: | Line 1,289: | ||
local SOURCE_FUNCS = { | local SOURCE_FUNCS = { | ||
['areas'] = p._addAreasWithSkillRequirement, | ['areas'] = p._addAreasWithSkillRequirement, | ||
['spells'] = p. | ['spells'] = p._addSpells, | ||
['altmagic'] = p. | ['altmagic'] = p._addAltMagic, | ||
['prayers'] = p. | ['prayers'] = p._addPrayers, | ||
[' | ['gatheringitems'] = p._addGatherables, | ||
[' | ['artisanitems'] = p._addRecipes, | ||
['firemaking'] = p. | ['firemaking'] = p._addFiremakingActions, | ||
['thieving'] = p._addThievingTargets, | |||
['constellations'] = p._addConstellations, | |||
['shop'] = p._addShopPurchasesWithSkillRequirements, | |||
['farmingplots'] = p._addFarmingPlots, | |||
['townshipunlocks'] = p._addTownshipUnlocks, | |||
['agilityslots'] = p._addAgilityObstacleSlotsAndPillars, | |||
['mastery'] = p._addSkillMastery | |||
} | } | ||
Line 1,081: | 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,089: | 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,105: | 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,119: | Line 1,355: | ||
function p._prepareSingleEntity(entity, skillName) | function p._prepareSingleEntity(entity, skillName) | ||
-- | -- Special children that need extra attention | ||
if entity.overrideText then | |||
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 | |||
if skillName == 'Farming' and entity.seed then | if skillName == 'Farming' and entity.seed then | ||
return 'Plant ' .. Icons.Icon({entity.seed.name, type='item'}) .. ' to grow ' .. Icons.Icon({entity.entityName, type='item'}) | return 'Plant ' .. Icons.Icon({entity.seed.name, type='item'}) .. ' to grow ' .. Icons.Icon({entity.entityName, type='item'}) | ||
end | |||
if skillName == 'Township' and entity.upgradesFrom then | |||
return 'Upgrade ' .. Icons.Icon({entity.upgradesFrom.name, type='building'}) .. ' to ' .. Icons.Icon({entity.entityName, type='building'}) | |||
end | |||
-- What are you doing with the thing you unlock? ("verbs") | -- What are you doing with the thing you unlock? ("verbs") | ||
Line 1,134: | Line 1,379: | ||
-- Icon overrides | -- Icon overrides | ||
local iconType = entity.entityType | local iconType = entity.entityType | ||
local | local iconLink = entity.entityName | ||
local iconText = entity.entityName | |||
local iconImg = entity.entityName | |||
local noLink = '' | |||
if entity.entityType == 'slayerArea' then | if entity.entityType == 'slayerArea' then | ||
iconType = 'combatArea' | iconType = 'combatArea' | ||
Line 1,144: | 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 | ||
iconType = entity.subType | iconType = entity.subType | ||
end | end | ||
iconLink = entity.item.name | |||
end | end | ||
if entity.entityType == 'artisan' then | if entity.entityType == 'artisan' or entity.entityType == 'trader' then | ||
iconType = 'item' | iconType = 'item' | ||
end | |||
if entity.entityType == 'shop' then | |||
iconType = string.lower(entity.subType) | |||
end | |||
if entity.entityType == 'plot' then | |||
iconType = 'skill' | |||
iconLink = 'Farming' | |||
iconImg = 'Farming' | |||
noLink = 'true' | |||
end | |||
if entity.entityType == 'obstacle' then | |||
iconType = 'agility' | |||
end | |||
if entity.entityType == 'obstacleslot' then | |||
iconType = 'agility' | |||
iconLink = 'Obstacles' | |||
end | |||
if entity.entityType == 'pillar' then | |||
iconType = 'agility' | |||
iconLink = 'Passive_Pillars' | |||
end | end | ||
-- Any other requirements? | -- Any other requirements or post-scripts? | ||
local extraReqs = p._prepareOtherReqs(entity) | local extraReqs = p._prepareOtherReqs(entity) | ||
local extraPost = '' | |||
if entity.entityType == 'obstacle' then | |||
extraPost = ' in ' .. entity.subType | |||
end | |||
return verb .. Icons.Icon({ | return verb .. Icons.Icon({iconLink, iconText, img=iconImg, type=iconType, nolink=noLink}) .. extraPost .. extraReqs | ||
end | end | ||
Line 1,178: | 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 | -- 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) | ||
for i, dataSource in ipairs(SKILL_CHECK_MAP[skillName]) do | |||
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,230: | Line 1,522: | ||
-- Skip this one if it's in a gear set we've already listed | -- Skip this one if it's in a gear set we've already listed | ||
local entityGearSet = nil | local entityGearSet = nil | ||
if entity.entityType == 'item' then | if entity.entityType == 'item' or entity.entityType == 'shop' then | ||
for i, gearSet in ipairs(GEAR_SETS) do | for i, gearSet in ipairs(GEAR_SETS) do | ||
if Shared.contains(gearSet.entities, entity.entityName) then | if Shared.contains(gearSet.entities, entity.entityName) then | ||
Line 1,273: | 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