Module:LevelUpTable/Data: Difference between revisions
From Melvor Idle
(Add additional requirements for Astrology) |
(Add agility requirements) |
||
Line 31: | Line 31: | ||
end | end | ||
return result | return result | ||
end | |||
function First(list, predicate) | |||
for _, item in ipairs(list) do | |||
if predicate(item) == true then | |||
return item | |||
end | |||
end | |||
error('No item found that matches predicate.') | |||
end | end | ||
Line 138: | Line 147: | ||
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) | return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) | ||
end) | end) | ||
end | |||
function getAgilityData(realm) | |||
return getAgilityRequirements('Agility', realm) | |||
end | end | ||
Line 160: | Line 173: | ||
return nil | return nil | ||
end | end | ||
local filterFunc = function(x) | local filterFunc = function(x) | ||
return Skills.getRecipeRealm(x) == realm.id and getUnlockReqs(x) | return Skills.getRecipeRealm(x) == realm.id and getUnlockReqs(x) | ||
Line 185: | Line 181: | ||
return Select(constellations, function(const) | return Select(constellations, function(const) | ||
local unlockReqs = getUnlockReqs(const) | local unlockReqs = getUnlockReqs(const) | ||
local myUnlocks = | local myUnlocks = First(unlockReqs, function(req) return req.skillID == skillID end) | ||
local otherUnlocks = | local otherUnlocks = Where(unlockReqs, function(req) return req.skillID ~= skillID end) | ||
local data = UnlockData.new(const.id, const.name, myUnlocks.level, skill) | local data = UnlockData.new(const.id, const.name, myUnlocks.level, skill) | ||
Line 193: | Line 189: | ||
for _, req in ipairs(otherUnlocks) do | for _, req in ipairs(otherUnlocks) do | ||
table.insert(data.otherRequirements, UnlockData.new(const.id, const.name, req.level, req.type)) | table.insert(data.otherRequirements, UnlockData.new(const.id, const.name, req.level, req.type)) | ||
end | |||
return data | |||
end) | |||
end | |||
function getAgilityRequirements(skill, realm) | |||
local skillID = Constants.getSkillID(skill) | |||
local AgilitySkillID = Constants.getSkillID('Agility') | |||
local AgilityID = 'Agility' | |||
function hasSkill(obstacle) | |||
if obstacle.skillRequirements == nil then | |||
return false | |||
end | |||
for _, req in pairs(obstacle.skillRequirements) do | |||
if req.skillID == skillID then return true end | |||
end | |||
return false | |||
end | |||
function flattenRequirements(obstacle) | |||
local skillRequirements = {} | |||
for _, req in pairs(obstacle.skillRequirements) do | |||
table.insert(skillRequirements, { level = req.level, skillID = req.skillID }) | |||
end | |||
table.insert(skillRequirements, { level = Skills.getRecipeLevelRealm('Agility', obstacle), skillID = AgilitySkillID }) | |||
return skillRequirements | |||
end | |||
local filterFunc = function(x) | |||
return Skills.getRecipeRealm(x) == realm.id and hasSkill(x) | |||
end | |||
local obstacles = nil | |||
if skill == 'Agility' then | |||
obstacles = getDataSet(SkillData.Agility.obstacles, realm) | |||
else | |||
obstacles = GameData.getEntities(SkillData.Agility.obstacles, filterFunc) | |||
end | |||
-- Add agility skill requirement to requirements list. | |||
return Select(obstacles, function(o) | |||
local unlockReqs = flattenRequirements(o) | |||
local myUnlock = First(unlockReqs, function(req) return req.skillID == skillID end) | |||
local otherUnlocks = Where(unlockReqs, function(req) return req.skillID ~= skillID end) | |||
local data = UnlockData.new(o.id, o.name, myUnlock.level, skill) | |||
data.otherRequirements = {} | |||
for _, req in ipairs(otherUnlocks) do | |||
local _, skillName = GameData.getLocalID(req.skillID) | |||
table.insert(data.otherRequirements, UnlockData.new(o.id, o.name, req.level, skillName)) | |||
end | end | ||
return data | return data | ||
Line 201: | Line 249: | ||
local realmName = 'Abyssal Realm' | local realmName = 'Abyssal Realm' | ||
local realm = Skills.getRealmFromName(realmName) | local realm = Skills.getRealmFromName(realmName) | ||
Debug.log( | Debug.log(getAgilityData(realm)) | ||
end | end | ||
p.UnlockData = UnlockData | p.UnlockData = UnlockData | ||
return p | return p |
Revision as of 20:22, 5 July 2024
Documentation for this module may be created at Module:LevelUpTable/Data/doc
-- SkillData object that acts as an interface for data shared between skills.
local p = {}
local Debug = require('Module:Debug') -- < Remove when module is finished.
local GameData = require('Module:GameData')
local SkillData = GameData.skillData
local Skills = require('Module:Skills')
local Items = require('Module:Items')
local Shared = require('Module:Shared')
local Constants = require('Module:Constants')
local UnlockData = {}
UnlockData.__index = UnlockData
function UnlockData.new(id, name, level, skill)
local self = setmetatable({}, UnlockData)
self.name = name
self.level = level
self.skill = skill
self.id = id
self.otherRequirements = nil
return self
end
--==== Helper functions ====--
-- Mimicks the C# Select method.
function Select(list, selector)
local result = {}
for _, item in ipairs(list) do
table.insert(result, selector(item))
end
return result
end
function First(list, predicate)
for _, item in ipairs(list) do
if predicate(item) == true then
return item
end
end
error('No item found that matches predicate.')
end
-- Mimicks the C# Where method.
function Where(tbl, predicate)
local result = {}
for _, v in ipairs(tbl) do
if predicate(v) then
table.insert(result, v)
end
end
return result
end
function Concat(...)
local args = {...}
local result = {}
for _, tbl in ipairs(args) do
for _, value in ipairs(tbl) do
table.insert(result, value)
end
end
return result
end
function getRealmFromID(obj)
local ns, _ = Shared.getLocalID(obj.id)
if ns == 'melvorItA' then
return 'melvorItA:Abyssal'
else
return 'melvorD:Melvor'
end
end
function getDataSet(skillData, realm)
return GameData.getEntities(skillData, function(x) return Skills.getRecipeRealm(x) == realm.id end)
end
function getDataSetId(skillData, realm)
return GameData.getEntities(skillData, function(x) return getRealmFromID(x) == realm.id end)
end
--==== Skill Data Collection ====--
function getWoodcuttingData(realm)
local skillID = 'Woodcutting'
local data = getDataSet(SkillData.Woodcutting.trees, realm)
return Select(data, function(x)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
end
function getMiningData(realm)
local skillID = 'Mining'
local data = getDataSet(SkillData.Mining.rockData, realm)
return Select(data, function(x)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
end
function getFishingData(realm)
local skillID = 'Fishing'
local data = getDataSet(SkillData.Fishing.fish, realm)
return Select(data, function(x)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
end
function getThievingData(realm)
local skillID = 'Thieving'
local data = getDataSet(SkillData.Thieving.npcs, realm)
return Select(data, function(x)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
end
function getFarmingData(realm)
local skillID = 'Farming'
local data = getDataSet(SkillData.Farming.recipes, realm)
-- Create lookup for plot category name.
local plotLookup = {}
for _, plot in ipairs(SkillData.Farming.categories) do
plotLookup[plot.id] = plot.name
end
local seeds = Select(data, function(x)
local productItem = Items.getItemByID(x.productId)
return UnlockData.new(productItem.id, productItem.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
local plotData = getDataSetId(SkillData.Farming.plots, realm)
local plots = Select(plotData, function(x)
return UnlockData.new(x.id, plotLookup[x.categoryID], Skills.getRecipeLevel(skillID, x), "Farming Plot")
end)
return Concat(seeds, plots)
end
function getAstrologyData(realm)
local skillID = 'Astrology'
local data = getDataSet(SkillData.Astrology.recipes, realm)
return Select(data, function(x)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
end
function getAgilityData(realm)
return getAgilityRequirements('Agility', realm)
end
--==== Other Requirements Collection ====--
function getAstrologyRequirements(skill, realm)
-- Only Abyssal Astrology has level unlock requirements as of V1.3
local skillID = Constants.getSkillID(skill)
local AstroID = 'Astrology'
-- Find if this constellation has the provided skill as an unlock requirement.
function getUnlockReqs(constellation)
if constellation.abyssalModifiers == nil then return nil end
for _, mod in ipairs(constellation.abyssalModifiers) do
if mod.unlockRequirements then
for _, req in ipairs(mod.unlockRequirements) do
if req.skillID == skillID then
-- Return the unlockRequirements table, so we can reuse this function later to retrieve unlock data.
return mod.unlockRequirements
end
end
end
end
return nil
end
local filterFunc = function(x)
return Skills.getRecipeRealm(x) == realm.id and getUnlockReqs(x)
end
local constellations = GameData.getEntities(SkillData.Astrology.recipes, filterFunc)
return Select(constellations, function(const)
local unlockReqs = getUnlockReqs(const)
local myUnlocks = First(unlockReqs, function(req) return req.skillID == skillID end)
local otherUnlocks = Where(unlockReqs, function(req) return req.skillID ~= skillID end)
local data = UnlockData.new(const.id, const.name, myUnlocks.level, skill)
data.otherRequirements = {}
table.insert(data.otherRequirements, UnlockData.new(const.id, const.name, Skills.getRecipeLevel(AstroID, const), AstroID))
for _, req in ipairs(otherUnlocks) do
table.insert(data.otherRequirements, UnlockData.new(const.id, const.name, req.level, req.type))
end
return data
end)
end
function getAgilityRequirements(skill, realm)
local skillID = Constants.getSkillID(skill)
local AgilitySkillID = Constants.getSkillID('Agility')
local AgilityID = 'Agility'
function hasSkill(obstacle)
if obstacle.skillRequirements == nil then
return false
end
for _, req in pairs(obstacle.skillRequirements) do
if req.skillID == skillID then return true end
end
return false
end
function flattenRequirements(obstacle)
local skillRequirements = {}
for _, req in pairs(obstacle.skillRequirements) do
table.insert(skillRequirements, { level = req.level, skillID = req.skillID })
end
table.insert(skillRequirements, { level = Skills.getRecipeLevelRealm('Agility', obstacle), skillID = AgilitySkillID })
return skillRequirements
end
local filterFunc = function(x)
return Skills.getRecipeRealm(x) == realm.id and hasSkill(x)
end
local obstacles = nil
if skill == 'Agility' then
obstacles = getDataSet(SkillData.Agility.obstacles, realm)
else
obstacles = GameData.getEntities(SkillData.Agility.obstacles, filterFunc)
end
-- Add agility skill requirement to requirements list.
return Select(obstacles, function(o)
local unlockReqs = flattenRequirements(o)
local myUnlock = First(unlockReqs, function(req) return req.skillID == skillID end)
local otherUnlocks = Where(unlockReqs, function(req) return req.skillID ~= skillID end)
local data = UnlockData.new(o.id, o.name, myUnlock.level, skill)
data.otherRequirements = {}
for _, req in ipairs(otherUnlocks) do
local _, skillName = GameData.getLocalID(req.skillID)
table.insert(data.otherRequirements, UnlockData.new(o.id, o.name, req.level, skillName))
end
return data
end)
end
function p.test()
local realmName = 'Abyssal Realm'
local realm = Skills.getRealmFromName(realmName)
Debug.log(getAgilityData(realm))
end
p.UnlockData = UnlockData
return p