Module:LevelUpTable/Data: Difference between revisions

From Melvor Idle
(Add farming plot data)
(Remove deprecated code)
 
(10 intermediate revisions by the same user not shown)
Line 8: Line 8:
local Items = require('Module:Items')
local Items = require('Module:Items')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local Constants = require('Module:Constants')
local FL = require('Module:FunList')


local UnlockData = {}
local UnlockData = {}
UnlockData.__index = UnlockData
UnlockData.__index = UnlockData


function UnlockData.new(id, name, level, skill)
function UnlockData.new(id, name, level, skill, category)
     local self = setmetatable({}, UnlockData)
     local self = setmetatable({}, UnlockData)
     self.name = name
     self.name = name
     self.level = level
     self.level = level
     self.skill = skill
     self.skill = skill
    self.category = category or skill
     self.id = id
     self.id = id
    self.otherRequirements = nil
     return self
     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 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
end


Line 49: Line 32:
return 'melvorD:Melvor'
return 'melvorD:Melvor'
end
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
end


Line 62: Line 37:
function getWoodcuttingData(realm)
function getWoodcuttingData(realm)
local skillID = 'Woodcutting'
local skillID = 'Woodcutting'
local data = getDataSet(SkillData.Woodcutting.trees, realm)
 
return FL.new(SkillData.Woodcutting.trees)
return Select(data, function(x)  
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
end)
:toTable()
end
end


function getMiningData(realm)
function getMiningData(realm)
local skillID = 'Mining'
local skillID = 'Mining'
local data = getDataSet(SkillData.Mining.rockData, realm)
 
return FL.new(SkillData.Woodcutting.rockData)
return Select(data, function(x)  
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
end)
:toTable()
end
end


function getFishingData(realm)
function getFishingData(realm)
local skillID = 'Fishing'
local skillID = 'Fishing'
local data = getDataSet(SkillData.Fishing.fish, realm)
 
return FL.new(SkillData.Woodcutting.fish)
return Select(data, function(x)  
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
end)
:toTable()
end
end


function getThievingData(realm)
function getThievingData(realm)
local skillID = 'Thieving'
local skillID = 'Thieving'
local data = getDataSet(SkillData.Thieving.npcs, realm)
 
return FL.new(SkillData.Woodcutting.npcs)
return Select(data, function(x)  
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID)
:select(function(x) return UnlockData.new(x.id, x.name, Skills.getRecipeLevel(skillID, x), skillID) end)
end)
:toTable()
end
end


function getFarmingData(realm)
function getFarmingData(realm)
local skillID = 'Farming'
local skillID = 'Farming'
local data = getDataSet(SkillData.Farming.recipes, realm)
-- Create lookup for plot category name.
-- Create lookup for plot category name.
local plotLookup = {}
local plotLookup = FL.new(SkillData.Farming.categories)
for _, plot in ipairs(SkillData.Farming.categories) do
:toDictionary(function(k) return k.id end,
        plotLookup[plot.id] = plot.name
  function(v) return v.name end)
    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


local seeds = Select(data, function(x)  
function getFletchingData(realm)
local productItem = Items.getItemByID(x.productId)
local skillID = 'Fletching'
return UnlockData.new(productItem.id, productItem.name, Skills.getRecipeLevel(skillID, x), skillID)
end)
local plotData = getDataSetId(SkillData.Farming.plots, realm)
return FL.new(SkillData.Fletching.recipes)
local plots = Select(plotData, function(x)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
return UnlockData.new(x.id, plotLookup[x.categoryID], Skills.getRecipeLevel(skillID, x), "Farming Plot")
:select(function(x)
end)
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'
 
return FL.new(SkillData.Herblore.recipes)
:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
:select(function(x)
local lastPotID = FL.new(x.potionIDs):last()
local lastPot = Items.getItemByID(lastPotID)
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 Concat(seeds, plots)
return data
end):toTable()
end
end


function p.test()
function p.test()
--local realmName = 'Abyssal Realm'
local realmName = 'Abyssal Realm'
local realm = Skills.getRealmFromName(realmName)
local realm = Skills.getRealmFromName(realmName)
Debug.log(getFarmingData(realm))
Debug.log(getAstrologyRequirements('Herblore', realm))
end
end


p.UnlockData = UnlockData
p.UnlockData = UnlockData
return p
return p

Latest revision as of 16:45, 20 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 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

--==== 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'

	return FL.new(SkillData.Herblore.recipes)
		:where(function(x) return Skills.getRecipeRealm(x) == realm.id end)
		:select(function(x)
			local lastPotID = FL.new(x.potionIDs):last()
			local lastPot = Items.getItemByID(lastPotID)
			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