Module:LevelUpTable/Data
From Melvor Idle
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 FL = require('Module:FunList')
local UnlockData = {}
UnlockData.__index = UnlockData
function UnlockData.new(id, name, level, skill, category)
local self = setmetatable({}, UnlockData)
self.name = name
self.level = level
self.skill = skill
self.category = category or skill
self.id = id
self.otherRequirements = nil
return self
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'
return FL.new(SkillData.Woodcutting.trees)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
:toTable()
end
function getMiningData(realm)
local skillID = 'Mining'
return FL.new(SkillData.Woodcutting.rockData)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
:toTable()
end
function getFishingData(realm)
local skillID = 'Fishing'
return FL.new(SkillData.Woodcutting.fish)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
:toTable()
end
function getThievingData(realm)
local skillID = 'Thieving'
return FL.new(SkillData.Woodcutting.npcs)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
:toTable()
end
function getFarmingData(realm)
local skillID = 'Farming'
-- Create lookup for plot category name.
local plotLookup = FL.new(SkillData.Farming.categories)
:toDictionary(function(k) return k.id end,
function(v) return v.name end)
local seeds = FL.new(SkillData.Farming.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local productItem = Items.getItemByID(x.productId)
return UnlockData.new(productItem.id, productItem.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
local plots = FL.new(SkillData.Farming.plots)
:where(function(x) return getRealmFromID(x) == realm.id end)
:select(function(x)
return UnlockData.new(x.id, plotLookup[x.categoryID], Skills.getRecipeLevel(skillID, x), skillID, "Farming Plot")
end)
return seeds:concat(plots)
:toTable()
end
function getAstrologyData(realm)
local skillID = 'Astrology'
return FL.new(SkillData.Woodcutting.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
:toTable()
end
function getAgilityData(realm)
local skillID = 'Agility'
local pillarLevels = {
melvorF = 99,
melvorTotH = 120,
melvorItA = 60
}
local pillars = FL.new(SkillData.Agility.pillars)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local ns, _ = Shared.getLocalID(x.id)
return UnlockData.new(x.id, x.name, pillarLevels[ns], skillID)
end)
return pillars:concat(getAgilityRequirements(skillID, realm))
:toTable()
end
function getFiremakingData(realm)
local skillID = 'Firemaking'
return FL.new(SkillData.Firemaking.logs)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local logs = Items.getItemByID(x.logID)
return UnlockData.new(x.id, logs.name, Skills.getRecipeLevel(skillID, x), skillID)
end):toTable()
end
function getCookingData(realm)
local skillID = 'Cooking'
return FL.new(SkillData.Cooking.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local foodItem = Items.getItemByID(x.productID)
return UnlockData.new(foodItem.id, foodItem.name, Skills.getRecipeLevel(skillID, x), skillID, x.categoryID)
end):toTable()
end
function getSmithingData(realm)
local skillID = 'Smithing'
return FL.new(SkillData.Smithing.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local product = Items.getItemByID(x.productID)
return UnlockData.new(product.id, product.name, Skills.getRecipeLevel(skillID, x), skillID, x.categoryID)
end):toTable()
end
function getFletchingData(realm)
local skillID = 'Fletching'
return FL.new(SkillData.Fletching.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local product = Items.getItemByID(x.productID)
return UnlockData.new(product.id, product.name, Skills.getRecipeLevel(skillID, x), skillID)
end):toTable()
end
function getCraftingData(realm)
local skillID = 'Crafting'
return FL.new(SkillData.Crafting.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local product = Items.getItemByID(x.productID)
return UnlockData.new(product.id, product.name, Skills.getRecipeLevel(skillID, x), skillID)
end):toTable()
end
function getRunecraftingData(realm)
local skillID = 'Runecrafting'
return FL.new(SkillData.Runecrafting.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local product = Items.getItemByID(x.productID)
return UnlockData.new(product.id, product.name, Skills.getRecipeLevel(skillID, x), skillID)
end):toTable()
end
function getHerbloreData(realm)
local skillID = 'Herblore'
local data = getDataSet(SkillData.Herblore.recipes, realm)
function getLastPotion(potion)
local lastID = FL.new(potion.potionIDs):last()
return Items.getItemByID(lastID)
end
return FL.new(SkillData.Herblore.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local lastPot = getLastPotion(x)
return UnlockData.new(lastPot.id, lastPot.name, Skills.getRecipeLevel(skillID, x), skillID)
end):toTable()
end
function getSummoningData(realm)
local skillID = 'Summoning'
return FL.new(SkillData.Summoning.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local product = Items.getItemByID(x.productID)
return UnlockData.new(x.id, product.name, Skills.getRecipeLevel(skillID, x), skillID)
end):toTable()
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
local mod = FL.new(constellation.abyssalModifiers):firstOrDefault(function(mod)
return mod.unlockRequirements ~= nil and
FL.new(mod.unlockRequirements):any(function(req) return req.skillID == skillID end)
end, nil)
return mod and mod.unlockRequirements or nil
end
return FL.new(SkillData.Astrology.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id and getUnlockReqs(x) end)
:select(function(const)
local unlockReqs = FL.new(getUnlockReqs(const))
local myUnlocks = unlockReqs:first(function(req) return req.skillID == skillID end)
local otherUnlocks = unlockReqs:where(function(req) return req.skillID ~= skillID end)
local data = UnlockData.new(const.id, const.name, myUnlocks.level, skill, "Astrology")
data.otherRequirements = {}
table.insert(data.otherRequirements, UnlockData.new(const.id, const.name, Skills.getRecipeLevel(AstroID, const), AstroID))
for _, req in pairs(otherUnlocks) do
table.insert(data.otherRequirements, UnlockData.new(const.id, const.name, req.level, req.type))
end
return data
end):toTable()
end
function getAgilityRequirements(skill, realm)
local skillID = Constants.getSkillID(skill)
local AgilitySkillID = Constants.getSkillID('Agility')
local AgilityID = 'Agility'
-- Filter obstacles by realm.
local obstacles = FL.new(SkillData.Agility.obstacles)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
-- If the skill is something other than the Agility skill, filter obstacles that contain
-- the provided skill as a requirement.
if skill ~= AgilityID then
obstacles:where(function(obstacle)
return obstacle.skillRequirements ~= nil and
FL.new(obstacle.skillRequirements):any(function(req) return req.skillID == skillID end)
end)
end
-- Add agility skill requirement to requirements list.
return obstacles:select(function(o)
local reqs = FL.new(o.skillRequirements)
:select(function(req) return { level = req.level, skillID = req.skillID } end)
:append({ level = Skills.getRecipeLevelRealm('Agility', o), skillID = AgilitySkillID})
local myUnlock = reqs:first(function(req) return req.skillID == skillID end)
local otherUnlocks = reqs:where(function(req) return req.skillID ~= skillID end)
local data = UnlockData.new(o.id, o.name, myUnlock.level, skill, 'AgilityObstacle')
data.otherRequirements = otherUnlocks:select(function(req)
local _, skillName = GameData.getLocalID(req.skillID)
return UnlockData.new(o.id, o.name, req.level, skillName)
end):toTable()
return data
end):toTable()
end
function p.test()
local realmName = 'Abyssal Realm'
local realm = Skills.getRealmFromName(realmName)
Debug.log(getAstrologyRequirements('Herblore', realm))
end
p.UnlockData = UnlockData
return p