Module:Skills/Agility: Difference between revisions

From Melvor Idle
(Initial pass at creating the agility obstacle table)
No edit summary
 
(33 intermediate revisions by 4 users not shown)
Line 1: Line 1:
local p = {}
local p = {}
local ItemData = mw.loadData('Module:Items/data')
local SkillData = mw.loadData('Module:Skills/data')


local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local SkillData = GameData.skillData
local Skills = require('Module:Skills')
local Items = require('Module:Items')
local Items = require('Module:Items')
local ItemSourceTables = require('Module:Items/SourceTables')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
function p.getObstacleByID(obstID)
return GameData.getEntityByID(SkillData.Agility.obstacles, obstID)
end
function p.getObstacle(name)
return GameData.getEntityByName(SkillData.Agility.obstacles, name)
end
function p.getPillar(name)
local result = p.getPillars(
function(x)
return x.name == name
end
)
return result[1]
end
function p.getObstacles(checkFunc)
return GameData.getEntities(SkillData.Agility.obstacles, checkFunc)
end
function p.getPillars(checkFunc)
local result = nil
local keys = { 'pillars', 'elitePillars' }
for i, key in ipairs(keys) do
local pillars = GameData.getEntities(SkillData.Agility[key], checkFunc)
if result == nil then
result = pillars
else
for k, pillar in ipairs(pillars) do
table.insert(result, pillar)
end
end
end
if result == nil then
result = {}
end
return result
end
--- Gets all required levels to build the given obstacle.
function p.getObstacleRequirements(obstacle)
local levelRequirements = {}
-- Add agility level requirement.
levelRequirements['Agility'] = Skills.getRecipeLevel('Agility', obstacle)
-- Add other level requirements.
if type(obstacle.skillRequirements) == 'table' then
for i, skillReq in ipairs(obstacle.skillRequirements) do
local skillName = Constants.getSkillName(skillReq.skillID)
if skillName ~= nil then
levelRequirements[skillName] = skillReq.level
end
end
end
return levelRequirements
end
-- Gets all items and gp/sc costs required to build the given obstacle.
function p.getObstacleCosts(obstacle)
local costs = {}
if obstacle.gpCost > 0 then
costs['GP'] = obstacle.gpCost
end
if obstacle.scCost > 0 then
costs['SC'] = obstacle.scCost
end
for j, itemCost in ipairs(obstacle.itemCosts) do
local item = Items.getItemByID(itemCost.id)
costs[item.name] = itemCost.quantity
end
return costs
end
function p._getObstacleRequirements(obstacle)
local resultPart = {}
local requirements = p.getObstacleRequirements(obstacle)
for skill, level in pairs(requirements) do
table.insert(resultPart, Icons._SkillReq(skill, level))
end
return table.concat(resultPart, '<br/>')
end
function p._getObstacleCosts(obstacle)
local costs = {}
local obstacleCosts = p.getObstacleCosts(obstacle)
-- Make sure SC and GP appear at the top.
if obstacleCosts['GP'] then table.insert(costs, Icons.GP(obstacleCosts['GP'])) end
if obstacleCosts['SC'] then table.insert(costs, Icons.SC(obstacleCosts['SC'])) end
for item, amount in pairs(obstacleCosts) do
if item ~= 'GP' and item ~= 'SC' then
table.insert(costs, Icons.Icon({item, type='item', qty = amount, notext=true}))
end
end
return table.concat(costs, '<br/>')
end


function p.getObstacleCourseTable(frame)
function p.getObstacleCourseTable(frame)
  local result = ''
local result = ''


  result = '{| class="wikitable sortable stickyHeader"'
result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
result = result..'\r\n|- class="headerRow-0"'
  result = result..'!Name!!Slot!!XP!!GP!!Time!!XP/s!!GP/s!!Bonuses!!Requirements!!Cost'
result = result..'\r\n!Slot!!Name!!XP!!GP!!Time!!XP/s!!GP/s!!Bonuses!!Requirements!!Cost'


  for i, obst in Shared.skpairs(SkillData.Agility.Obstacles) do
local catLog = {}
    result = result..'\r\n|-'
local obstacles = p.getObstacles(function(obst) return true end)
    result = result..'\r\n|'..obst.name..'||'..(obst.category + 1)
table.sort(obstacles, function(a, b) return a.category < b.category end)


    --After the name & category, doing XP, GP, Time, and rates
local catCounts = {}
    local XP = obst.completionBonuses.xp
for i, obst in ipairs(obstacles) do
    local GP = obst.completionBonuses.gp
if catCounts[obst.category] == nil then
    local Time = obst.interval / 1000
catCounts[obst.category] = 1
    result = result..'||'..XP..'||data-sort-value="'..GP..'"|'..Icons.GP(GP)
else
    result = result..'||data-sort-value="'..Time..'"|'..Shared.timeString(Time)
catCounts[obst.category] = catCounts[obst.category] + 1
    result = result..'||'..Shared.round(XP / Time, 2, 2)
end
    result = result..'||data-sort-value="'..GP/Time..'"|'..Icons.GP(Shared.round(GP/Time, 2, 2))
end


    local bonuses = {}
for i, obst in ipairs(obstacles) do
    --After that, adding the bonuses
result = result..'\r\n|-'
    for bonusName, bonusValue in pairs(obst.modifiers) do
result = result..'\r\n|'
      table.insert(bonuses, Constants.getModifierText(bonusName, bonusValue))
if catLog[obst.category] == nil then
    end
local rowspan = catCounts[obst.category]
    if Shared.tableCount(bonuses) == 0 then
result = result..'rowspan="'..rowspan..'" style="border:1px solid black"|'..(obst.category + 1)..'||'
      table.insert(bonuses, '<span color="red">None :(</span>')
catLog[obst.category] = true
    end
end
    result = result..'||'..table.concat(bonuses, '<br/>')
result = result .. 'id="'..string.gsub(obst.name,' ', '')..'"|'.. Icons.getExpansionIcon(obst.id) .. obst.name


    --Grabbing requirements to create
--After the name & category, doing XP, GP, Time, and rates
    result = result..'||'
local XP = obst.baseExperience
    if obst.category > 0 then
local GP = obst.gpReward
      result = result..Icons._SkillReq('Agility', obst.category * 10)
local Time = obst.baseInterval / 1000
    end
result = result..'||'..XP..'||data-sort-value="'..GP..'"|'..Icons.GP(GP)
    if obst.requirements ~= nil and obst.requirements.skillLevel ~= nil then
result = result..'||data-sort-value="'..Time..'"|'..Shared.timeString(Time, true)
      for j, skillReq in Shared.skpairs(obst.requirements.skillLevel) do
-- Readded XP/Time and GP/Time (previously commented out)
        result = result..'<br/>'..Icons._SkillReq(Constants.getSkillName(skillReq[1]), skillReq[2])
result = result..'||'..Shared.round(XP / Time, 2, 2)
      end
result = result..'||data-sort-value="'..GP/Time..'"|'..Icons.GP(Shared.round(GP/Time, 2, 2))
    end


    --Finally, the cost
local bonuses = {}
    local costs = {}
--After that, adding the bonuses
    if obst.cost.gp > 0 then table.insert(costs, Icons.GP(obst.cost.gp)) end
for bonusName, bonusValue in pairs(obst.modifiers) do
    if obst.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(obst.cost.slayerCoins)) end
table.insert(bonuses, Constants._getModifierText(bonusName, bonusValue))
    for j, itemCost in Shared.skpairs(obst.cost.items) do
end
      local item = Items.getItemByID(itemCost[1])
if Shared.tableIsEmpty(bonuses) then
      table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2]}))
table.insert(bonuses, '<span style="color:red">None :(</span>')
    end
end
    result = result..'|| data-sort-value="'..obst.cost.gp..'"|'..table.concat(costs, '<br/>')
result = result..'||'..table.concat(bonuses, '<br/>')
  end


  result = result..'\r\n|}'
--Grabbing requirements to create
result = result..'|| ' .. p._getObstacleRequirements(obst)


  return result
--Finally, the cost
result = result..'|| data-sort-value="'..obst.gpCost..'"|'..p._getObstacleCosts(obst)
end
 
result = result..'\r\n|}'
 
return result
end
end


function p.getPassivePillarTable(frame)
function p.getPassivePillarTable(frame)
  local result = ''
local result = ''
  return result
 
result = '{| class="wikitable sortable stickyHeader"'
result = result..'\r\n|- class="headerRow-0"'
result = result..'\r\n!Name!!Bonuses!!Cost'
 
local pillars = p.getPillars(function(pillar) return true end)
for i, pill in ipairs(pillars) do
result = result..'\r\n|-'
result = result..'\r\n|' .. 'id="'..string.gsub(pill.name,' ', '')..'"|'..Icons.getExpansionIcon(pill.id) .. pill.name
 
--After that, adding the bonuses
local bonuses = {}
for bonusName, bonusValue in pairs(pill.modifiers) do
table.insert(bonuses, Constants._getModifierText(bonusName, bonusValue))
end
if Shared.tableIsEmpty(bonuses) then
table.insert(bonuses, '<span style="color:red">None :(</span>')
end
result = result..'||'..table.concat(bonuses, '<br/>')
 
--Finally, the cost
result = result..'|| data-sort-value="'..pill.gpCost..'"|'.. p._getObstacleCosts(pill)
end
 
result = result..'\r\n|}'
 
return result
end
 
function p.getObstaclesForItem(itemID)
local costFunc =
function(obst)
for i, itemCost in ipairs(obst.itemCosts) do
if itemCost.id == itemID then
return true
end
end
return false
end
local pillars = p.getPillars(costFunc)
 
local result = p.getObstacles(costFunc)
if result == nil or Shared.tableIsEmpty(result) then
result = pillars
else
for i, pillar in ipairs(pillars) do
table.insert(result, pillar)
end
end
 
return result
end
end


return p
return p

Latest revision as of 17:53, 22 April 2024

Documentation for this module may be created at Module:Skills/Agility/doc

local p = {}

local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local SkillData = GameData.skillData
local Skills = require('Module:Skills')
local Items = require('Module:Items')
local Icons = require('Module:Icons')

function p.getObstacleByID(obstID)
	return GameData.getEntityByID(SkillData.Agility.obstacles, obstID)
end

function p.getObstacle(name)
	return GameData.getEntityByName(SkillData.Agility.obstacles, name)
end

function p.getPillar(name)
	local result = p.getPillars(
		function(x)
			return x.name == name
		end
	)
	
	return result[1]
end

function p.getObstacles(checkFunc)
	return GameData.getEntities(SkillData.Agility.obstacles, checkFunc)
end

function p.getPillars(checkFunc)
	local result = nil
	local keys = { 'pillars', 'elitePillars' }
	for i, key in ipairs(keys) do
		local pillars = GameData.getEntities(SkillData.Agility[key], checkFunc)
		if result == nil then
			result = pillars
		else
			for k, pillar in ipairs(pillars) do
				table.insert(result, pillar)
			end
		end
	end
	if result == nil then
		result = {}
	end
	return result
end

--- Gets all required levels to build the given obstacle.
function p.getObstacleRequirements(obstacle)
	local levelRequirements = {}
	
	-- Add agility level requirement.
	levelRequirements['Agility'] = Skills.getRecipeLevel('Agility', obstacle)

	-- Add other level requirements.
	if type(obstacle.skillRequirements) == 'table' then
		for i, skillReq in ipairs(obstacle.skillRequirements) do
			local skillName = Constants.getSkillName(skillReq.skillID)
			if skillName ~= nil then
				levelRequirements[skillName] = skillReq.level
			end
		end
	end
	
	return levelRequirements
end

-- Gets all items and gp/sc costs required to build the given obstacle.
function p.getObstacleCosts(obstacle)
	local costs = {}

	if obstacle.gpCost > 0 then
		costs['GP'] = obstacle.gpCost
	end
	if obstacle.scCost > 0 then
		costs['SC'] = obstacle.scCost
	end
	
	for j, itemCost in ipairs(obstacle.itemCosts) do
		local item = Items.getItemByID(itemCost.id)
		costs[item.name] = itemCost.quantity
	end
	
	return costs
end

function p._getObstacleRequirements(obstacle)
	local resultPart = {}
	local requirements = p.getObstacleRequirements(obstacle)
	
	for skill, level in pairs(requirements) do
		table.insert(resultPart, Icons._SkillReq(skill, level))
	end

	return table.concat(resultPart, '<br/>')
end

function p._getObstacleCosts(obstacle)
	local costs = {}
	local obstacleCosts = p.getObstacleCosts(obstacle)
	
	-- Make sure SC and GP appear at the top.
	if obstacleCosts['GP'] then table.insert(costs, Icons.GP(obstacleCosts['GP'])) end
	if obstacleCosts['SC'] then table.insert(costs, Icons.SC(obstacleCosts['SC'])) end
	for item, amount in pairs(obstacleCosts) do
		if item ~= 'GP' and item ~= 'SC' then
			table.insert(costs, Icons.Icon({item, type='item', qty = amount, notext=true}))
		end
	end

	return table.concat(costs, '<br/>')
end

function p.getObstacleCourseTable(frame)
	local result = ''

	result = '{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|- class="headerRow-0"'
	result = result..'\r\n!Slot!!Name!!XP!!GP!!Time!!XP/s!!GP/s!!Bonuses!!Requirements!!Cost'

	local catLog = {}
	local obstacles = p.getObstacles(function(obst) return true end)
	table.sort(obstacles, function(a, b) return a.category < b.category end)

	local catCounts = {}
	for i, obst in ipairs(obstacles) do
		if catCounts[obst.category] == nil then
			catCounts[obst.category] = 1
		else
			catCounts[obst.category] = catCounts[obst.category] + 1
		end
	end

	for i, obst in ipairs(obstacles) do
		result = result..'\r\n|-'
		result = result..'\r\n|'
		if catLog[obst.category] == nil then
			local rowspan = catCounts[obst.category]
			result = result..'rowspan="'..rowspan..'" style="border:1px solid black"|'..(obst.category + 1)..'||'
			catLog[obst.category] = true
		end
		result = result .. 'id="'..string.gsub(obst.name,' ', '')..'"|'.. Icons.getExpansionIcon(obst.id) .. obst.name

		--After the name & category, doing XP, GP, Time, and rates
		local XP = obst.baseExperience
		local GP = obst.gpReward
		local Time = obst.baseInterval / 1000
		result = result..'||'..XP..'||data-sort-value="'..GP..'"|'..Icons.GP(GP)
		result = result..'||data-sort-value="'..Time..'"|'..Shared.timeString(Time, true)
		-- Readded XP/Time and GP/Time (previously commented out)
		result = result..'||'..Shared.round(XP / Time, 2, 2)
		result = result..'||data-sort-value="'..GP/Time..'"|'..Icons.GP(Shared.round(GP/Time, 2, 2))

		local bonuses = {}
		--After that, adding the bonuses
		for bonusName, bonusValue in pairs(obst.modifiers) do
			table.insert(bonuses, Constants._getModifierText(bonusName, bonusValue))
		end
		if Shared.tableIsEmpty(bonuses) then
			table.insert(bonuses, '<span style="color:red">None :(</span>')
		end
		result = result..'||'..table.concat(bonuses, '<br/>')

		--Grabbing requirements to create
		result = result..'|| ' .. p._getObstacleRequirements(obst)

		--Finally, the cost
		result = result..'|| data-sort-value="'..obst.gpCost..'"|'..p._getObstacleCosts(obst)
	end

	result = result..'\r\n|}'

	return result
end

function p.getPassivePillarTable(frame)
	local result = ''

	result = '{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|- class="headerRow-0"'
	result = result..'\r\n!Name!!Bonuses!!Cost'

	local pillars = p.getPillars(function(pillar) return true end)
	for i, pill in ipairs(pillars) do
		result = result..'\r\n|-'
		result = result..'\r\n|' .. 'id="'..string.gsub(pill.name,' ', '')..'"|'..Icons.getExpansionIcon(pill.id) .. pill.name

		--After that, adding the bonuses
		local bonuses = {}
		for bonusName, bonusValue in pairs(pill.modifiers) do
			table.insert(bonuses, Constants._getModifierText(bonusName, bonusValue))
		end
		if Shared.tableIsEmpty(bonuses) then
			table.insert(bonuses, '<span style="color:red">None :(</span>')
		end
		result = result..'||'..table.concat(bonuses, '<br/>')

		--Finally, the cost
		result = result..'|| data-sort-value="'..pill.gpCost..'"|'.. p._getObstacleCosts(pill)
	end

	result = result..'\r\n|}'

	return result
end

function p.getObstaclesForItem(itemID)
	local costFunc =
		function(obst)
			for i, itemCost in ipairs(obst.itemCosts) do
				if itemCost.id == itemID then
					return true
				end
			end
			return false
		end
	local pillars = p.getPillars(costFunc)

	local result = p.getObstacles(costFunc)
	if result == nil or Shared.tableIsEmpty(result) then
		result = pillars
	else
		for i, pillar in ipairs(pillars) do
			table.insert(result, pillar)
		end
	end

	return result
end

return p