Module:CombatAreas: Difference between revisions
From Melvor Idle
(_getAreaRequirements: Crude attempt to prevent the same requirement appearing twice) |
(Use tabs instead of spaces for indentation; getMonsterAreas: Remove check for ID 1/Hill Giants - Game data no longer flags ITM afflicted monsters in this way) |
||
Line 13: | Line 13: | ||
function processArea(area, index, type) | function processArea(area, index, type) | ||
local result = Shared.clone(area) | |||
result.id = index - 1 | |||
if result.name == nil then | |||
result.name = result.areaName | |||
end | |||
result.type = type | |||
return result | |||
end | end | ||
function p.getArea(name) | function p.getArea(name) | ||
local result = nil | |||
--There are three types of areas but the lists are pretty short so looping all of them isn't a real issue | |||
for i, area in pairs(AreaData.combatAreas) do | |||
if area.name == name then | |||
return processArea(area, i, 'combat') | |||
end | |||
end | |||
for i, area in pairs(AreaData.slayerAreas) do | |||
if area.name == name then | |||
return processArea(area, i, 'slayer') | |||
end | |||
end | |||
for i, area in pairs(AreaData.dungeons) do | |||
if area.name == name then | |||
return processArea(area, i, 'dungeon') | |||
end | |||
end | |||
return nil | |||
end | end | ||
function p.getAreaByID(type, id) | function p.getAreaByID(type, id) | ||
if type == 'dungeon' then type = 'dungeons' | |||
elseif type == 'combat' then type = 'combatAreas' | |||
elseif type == 'slayer' then type = 'slayerAreas' end | |||
return processArea(AreaData[type][id + 1], id + 1) | |||
end | end | ||
function p.getAreaFilterType(type, name) | function p.getAreaFilterType(type, name) | ||
local areaName = nil | |||
if type == 'dungeon' then areas = AreaData.dungeons | |||
elseif type == 'combat' then areas = AreaData.combatAreas | |||
elseif type == 'slayer' then areas = AreaData.slayerAreas | |||
else return nil end | |||
for i, area in pairs(areas) do | |||
if type == 'dungeon' then areaName = area.name | |||
else areaName = area.areaName end | |||
if areaName == name then | |||
return processArea(area, i, type) | |||
end | |||
end | |||
return nil | |||
end | end | ||
function p.getAreas(checkFunc) | function p.getAreas(checkFunc) | ||
local resultArray = {} | |||
for i, area in Shared.skpairs(AreaData.combatAreas) do | |||
local temp = processArea(area, i, 'combat') | |||
if checkFunc(temp) then | |||
table.insert(resultArray, temp) | |||
end | |||
end | |||
for i, area in Shared.skpairs(AreaData.slayerAreas) do | |||
local temp = processArea(area, i, 'slayer') | |||
if checkFunc(temp) then | |||
table.insert(resultArray, temp) | |||
end | |||
end | |||
for i, area in Shared.skpairs(AreaData.dungeons) do | |||
local temp = processArea(area, i, 'dungeon') | |||
if checkFunc(temp) then | |||
table.insert(resultArray, temp) | |||
end | |||
end | |||
return resultArray | |||
end | end | ||
Line 157: | Line 157: | ||
function p._getAreaStat(area, statName) | function p._getAreaStat(area, statName) | ||
if statName == 'requirements' then | |||
return p._getAreaRequirements(area) | |||
elseif statName == 'areaEffectDesc' then | |||
if area.areaEffect ~= nil and area.areaEffect then | |||
local descText, subIdx = string.gsub(area.areaEffectDescription, '${effectValue}', area.areaEffectValue or 0) | |||
return descText | |||
else | |||
return 'None' | |||
end | |||
elseif statName == 'difficulty' then | |||
local result = Constants.getDifficultyString(area.difficulty[1]) | |||
if area.difficulty[2] ~= nil then | |||
result = result..' - '..Constants.getDifficultyString(area.difficulty[2]) | |||
end | |||
return result | |||
end | |||
return area[statName] | |||
end | end | ||
function p.getAreaStat(frame) | function p.getAreaStat(frame) | ||
local areaName = frame.args ~= nil and frame.args[1] or frame[1] | |||
local statName = frame.args ~= nil and frame.args[2] or frame[2] | |||
local area = p.getArea(areaName) | |||
if area == nil then | |||
return "ERROR: Could not find an area named "..areaName | |||
end | |||
return p._getAreaStat(area, statName) | |||
end | end | ||
function p.getMonsterAreas(monsterID) | function p.getMonsterAreas(monsterID) | ||
local areaArray = {} | |||
--There are three types of areas but the lists are pretty short so looping all of them isn't a real issue | |||
for i, area in pairs(AreaData.combatAreas) do | |||
if Shared.contains(area.monsters, monsterID) then | |||
table.insert(areaArray, processArea(area, i, 'combat')) | |||
end | |||
end | |||
for i, area in pairs(AreaData.slayerAreas) do | |||
if Shared.contains(area.monsters, monsterID) then | |||
table.insert(areaArray, processArea(area, i, 'slayer')) | |||
end | |||
end | |||
for i, area in pairs(AreaData.dungeons) do | |||
if Shared.contains(area.monsters, monsterID) then | |||
table.insert(areaArray, processArea(area, i, 'dungeon')) | |||
end | |||
end | |||
return areaArray | |||
end | end | ||
function p.getDungeonRequirements(frame) | function p.getDungeonRequirements(frame) | ||
local areaName = frame.args ~= nil and frame.args[1] or frame | |||
local area = p.getArea(areaName) | |||
if area == nil then | |||
return "ERROR: Could not find an area named "..areaName | |||
end | |||
local result = p._getAreaStat(area, 'requirements') | |||
if result ~= '' then | |||
result = "\r\n|-\r\n|'''Requirements:'''<br/>"..result | |||
end | |||
return result | |||
end | end | ||
return p | return p |
Revision as of 23:08, 7 January 2022
Data is pulled from Module:GameData/data
NOTE: Some tables are in Module:CombatAreas/AreaTables to prevent loop from referencing Monsters
--NOTE: Some tables are in Module:CombatAreas/AreaTables to prevent loop from referencing Monsters
local p = {}
local AreaData = mw.loadData('Module:CombatAreas/data')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Shop = require('Module:Shop')
p.eventData = AreaData.event
function processArea(area, index, type)
local result = Shared.clone(area)
result.id = index - 1
if result.name == nil then
result.name = result.areaName
end
result.type = type
return result
end
function p.getArea(name)
local result = nil
--There are three types of areas but the lists are pretty short so looping all of them isn't a real issue
for i, area in pairs(AreaData.combatAreas) do
if area.name == name then
return processArea(area, i, 'combat')
end
end
for i, area in pairs(AreaData.slayerAreas) do
if area.name == name then
return processArea(area, i, 'slayer')
end
end
for i, area in pairs(AreaData.dungeons) do
if area.name == name then
return processArea(area, i, 'dungeon')
end
end
return nil
end
function p.getAreaByID(type, id)
if type == 'dungeon' then type = 'dungeons'
elseif type == 'combat' then type = 'combatAreas'
elseif type == 'slayer' then type = 'slayerAreas' end
return processArea(AreaData[type][id + 1], id + 1)
end
function p.getAreaFilterType(type, name)
local areaName = nil
if type == 'dungeon' then areas = AreaData.dungeons
elseif type == 'combat' then areas = AreaData.combatAreas
elseif type == 'slayer' then areas = AreaData.slayerAreas
else return nil end
for i, area in pairs(areas) do
if type == 'dungeon' then areaName = area.name
else areaName = area.areaName end
if areaName == name then
return processArea(area, i, type)
end
end
return nil
end
function p.getAreas(checkFunc)
local resultArray = {}
for i, area in Shared.skpairs(AreaData.combatAreas) do
local temp = processArea(area, i, 'combat')
if checkFunc(temp) then
table.insert(resultArray, temp)
end
end
for i, area in Shared.skpairs(AreaData.slayerAreas) do
local temp = processArea(area, i, 'slayer')
if checkFunc(temp) then
table.insert(resultArray, temp)
end
end
for i, area in Shared.skpairs(AreaData.dungeons) do
local temp = processArea(area, i, 'dungeon')
if checkFunc(temp) then
table.insert(resultArray, temp)
end
end
return resultArray
end
function p._getAreaRequirements(area)
local result = ''
local resultArray = {}
local addReqsToArray = function(reqArray, requirements)
for i, reqDetails in Shared.skpairs(requirements) do
if reqDetails.type == 'Level' then
for j, lvlDetails in Shared.skpairs(reqDetails.levels) do
local skill = Constants.getSkillName(lvlDetails.skill)
table.insert(reqArray, Icons._SkillReq(skill, lvlDetails.level))
end
elseif reqDetails.type == 'SlayerItem' then
local item = Items.getItemByID(reqDetails.itemID)
table.insert(reqArray, Icons.Icon({item.name, type='item'})..' Equipped')
elseif reqDetails.type == 'Dungeon' then
for j, dungDetails in Shared.skpairs(reqDetails.dungeons) do
local dung = p.getAreaByID('dungeon', dungDetails.dungeonID)
if dungDetails.count > 1 then
table.insert(reqArray, dungDetails.count..'x '..Icons.Icon({dung.name, type='dungeon'})..' Completions')
else
table.insert(reqArray, Icons.Icon({dung.name, type='dungeon'})..' Completed')
end
end
elseif reqDetails.type == 'ShopPurchase' then
local shopPurchase = Shop.processPurchase(reqDetails.category, reqDetails.id)
if shopPurchase ~= nil then
table.insert(reqArray, Shop._getPurchaseIcon({ shopPurchase }) .. ' Purchased')
end
else
table.insert(reqArray, 'ERROR: Unknown requirement type ' .. (reqDetails.type or 'nil') .. '[[Category:Pages with script errors]]')
end
end
end
if area.entryRequirements ~= nil then
addReqsToArray(resultArray, area.entryRequirements)
end
if area.unlockRequirement ~= nil then
-- Ensure this requirement isn't already part of the entry requirements
local addReq = true
if area.entryRequirements ~= nil then
local unlockReqStr = mw.dumpObject(area.unlockRequirement)
for i, reqDetails in ipairs(area.entryRequirements) do
-- Using mw.dumpObject() as a lazy way to compare tables
if area.unlockRequirement.type == reqDetails.type and mw.dumpObject(reqDetails) == unlockReqStr then
addReq = false
break
end
end
end
if addReq then
addReqsToArray(resultArray, { area.unlockRequirement })
end
end
result = table.concat(resultArray, '<br/>')
return result
end
function p._getAreaStat(area, statName)
if statName == 'requirements' then
return p._getAreaRequirements(area)
elseif statName == 'areaEffectDesc' then
if area.areaEffect ~= nil and area.areaEffect then
local descText, subIdx = string.gsub(area.areaEffectDescription, '${effectValue}', area.areaEffectValue or 0)
return descText
else
return 'None'
end
elseif statName == 'difficulty' then
local result = Constants.getDifficultyString(area.difficulty[1])
if area.difficulty[2] ~= nil then
result = result..' - '..Constants.getDifficultyString(area.difficulty[2])
end
return result
end
return area[statName]
end
function p.getAreaStat(frame)
local areaName = frame.args ~= nil and frame.args[1] or frame[1]
local statName = frame.args ~= nil and frame.args[2] or frame[2]
local area = p.getArea(areaName)
if area == nil then
return "ERROR: Could not find an area named "..areaName
end
return p._getAreaStat(area, statName)
end
function p.getMonsterAreas(monsterID)
local areaArray = {}
--There are three types of areas but the lists are pretty short so looping all of them isn't a real issue
for i, area in pairs(AreaData.combatAreas) do
if Shared.contains(area.monsters, monsterID) then
table.insert(areaArray, processArea(area, i, 'combat'))
end
end
for i, area in pairs(AreaData.slayerAreas) do
if Shared.contains(area.monsters, monsterID) then
table.insert(areaArray, processArea(area, i, 'slayer'))
end
end
for i, area in pairs(AreaData.dungeons) do
if Shared.contains(area.monsters, monsterID) then
table.insert(areaArray, processArea(area, i, 'dungeon'))
end
end
return areaArray
end
function p.getDungeonRequirements(frame)
local areaName = frame.args ~= nil and frame.args[1] or frame
local area = p.getArea(areaName)
if area == nil then
return "ERROR: Could not find an area named "..areaName
end
local result = p._getAreaStat(area, 'requirements')
if result ~= '' then
result = "\r\n|-\r\n|'''Requirements:'''<br/>"..result
end
return result
end
return p