Module:CombatAreas: Difference between revisions

Update for v1.3
(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)
(Update for v1.3)
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
--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 p = {}
local AreaData = mw.loadData('Module:CombatAreas/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 Common = require('Module:Common')
local Icons = require('Module:Icons')
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 areaMap = {
local result = Shared.clone(area)
["combat"] = 'combatAreas',
result.id = index - 1
["dungeon"] = 'dungeons',
if result.name == nil then
["slayer"] = 'slayerAreas',
result.name = result.areaName
["depth"] = 'abyssDepths'
end
}
result.type = type
return result
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
--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
for k, areaType in pairs(areaMap) do
if area.name == name then
local area = GameData.getEntityByName(areaType, name)
return processArea(area, i, 'combat')
if area ~= nil then
return area
end
end
end
end
end


for i, area in pairs(AreaData.slayerAreas) do
function p.getAreaByID(id, areaType)
if area.name == name then
for aType, areaKey in pairs(areaMap) do
return processArea(area, i, 'slayer')
if areaType == nil or areaType == aType then
local area = GameData.getEntityByID(areaKey, id)
if area ~= nil then
return area
end
end
end
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
end


function p.getAreaFilterType(type, name)
function p.getAreaFilterType(name, type)
local areaName = nil
local areaType = areaMap[type]
if type == 'dungeon' then areas = AreaData.dungeons
if areaType ~= nil then
elseif type == 'combat' then areas = AreaData.combatAreas
return GameData.getEntityByName(areaType, name)
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
end
return nil
end
end


function p.getAreas(checkFunc)
function p.getAreas(checkFunc)
local resultArray = {}
local resultArray = nil


for i, area in Shared.skpairs(AreaData.combatAreas) do
for i, areaType in pairs(areaMap) do
local temp = processArea(area, i, 'combat')
local areas = GameData.getEntities(areaType, checkFunc)
if checkFunc(temp) then
if resultArray == nil then
table.insert(resultArray, temp)
resultArray = areas
else
for k, area in ipairs(areas) do
table.insert(resultArray, area)
end
end
end
end
end
for i, area in Shared.skpairs(AreaData.slayerAreas) do
if resultArray == nil then
local temp = processArea(area, i, 'slayer')
resultArray = {}
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
end


return resultArray
return resultArray
end
--Returns the expansion icon for the area if it has one
function p.getExpansionIcon(frame)
local areaName = frame.args ~= nil and frame.args[1] or frame
local area = p.getArea(areaName)
if area == nil then
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end
return Icons.getExpansionIcon(area.id)
end
end


function p._getAreaRequirements(area)
function p._getAreaRequirements(area)
local result = ''
local resultArray = {}
local resultArray = {}
local addReqsToArray = function(reqArray, requirements)
if area.entryRequirements ~= nil then
for i, reqDetails in Shared.skpairs(requirements) do
local reqText = Common.getRequirementString(area.entryRequirements)
if reqDetails.type == 'Level' then
if reqText ~= nil then
for j, lvlDetails in Shared.skpairs(reqDetails.levels) do
table.insert(resultArray, reqText)
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
end
if area.entryRequirements ~= nil then
addReqsToArray(resultArray, area.entryRequirements)
end
end


if area.unlockRequirement ~= nil then
if area.unlockRequirement ~= nil then
-- Ensure this requirement isn't already part of the entry requirements
-- Avoid repeating the same requirements twice, can happen for some dungeons e.g. Impending Darkness
local addReq = true
if area.entryRequirements == nil or mw.dumpObject(area.unlockRequirement) ~= mw.dumpObject(area.entryRequirements) then
if area.entryRequirements ~= nil then
local reqText = Common.getRequirementString(area.unlockRequirement)
local unlockReqStr = mw.dumpObject(area.unlockRequirement)
if reqText ~= nil then
for i, reqDetails in ipairs(area.entryRequirements) do
table.insert(resultArray, reqText)
-- 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
end
end
if addReq then
addReqsToArray(resultArray, { area.unlockRequirement })
end
end
end


result = table.concat(resultArray, '<br/>')
return table.concat(resultArray, '<br/>')
return result
end
 
function p.getAreaRequirementsForBox(frame)
--Returns infobox formatting for requirements, or returns nothing if there are none.
local areaName = frame.args ~= nil and frame.args[1] or frame
local area = p.getArea(areaName)
if area == nil then
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end
 
local reqs = p._getAreaRequirements(area)
if reqs ~= '' then
reqs = "|-\r\n|'''Requirements:'''\r\n"..reqs
end
return reqs
end
end


Line 160: Line 115:
return p._getAreaRequirements(area)
return p._getAreaRequirements(area)
elseif statName == 'areaEffectDesc' then
elseif statName == 'areaEffectDesc' then
if area.areaEffect ~= nil and area.areaEffect then
if area.areaEffect ~= nil then
local descText, subIdx = string.gsub(area.areaEffectDescription, '${effectValue}', area.areaEffectValue or 0)
local descText, subIdx = string.gsub(area.areaEffectDescription, '${effectValue}', area.areaEffect.magnitude or 0)
return descText
return descText
else
else
Line 182: Line 137:
local area = p.getArea(areaName)
local area = p.getArea(areaName)
if area == nil then
if area == nil then
return "ERROR: Could not find an area named "..areaName
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end
end


Line 188: Line 143:
end
end


function p.getMonsterAreas(monsterID)
function p._isMonsterInArea(monster, area)
local areaArray = {}
return (
--There are three types of areas but the lists are pretty short so looping all of them isn't a real issue
Shared.contains(area.monsterIDs, monster.id)
for i, area in pairs(AreaData.combatAreas) do
-- Check for Lair of the Spider Queen random spiders
if Shared.contains(area.monsters, monsterID) then
or (
table.insert(areaArray, processArea(area, i, 'combat'))
Shared.contains(area.monsterIDs, 'melvorTotH:RandomSpiderLair')
end
and Shared.contains(GameData.rawData.spiderLairMonsters, monster.id)
end
)
 
)
for i, area in pairs(AreaData.slayerAreas) do
end
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
function p._getMonsterAreas(monster)
-- Special handling for Lair of the Spider Queen, which has a random list of enemies
local randomSpiderCheck = Shared.contains(GameData.rawData.spiderLairMonsters, monster.id)
return p.getAreas(
function(area)
return p._isMonsterInArea(monster, area)
end)
end
end


Line 216: Line 167:
local area = p.getArea(areaName)
local area = p.getArea(areaName)
if area == nil then
if area == nil then
return "ERROR: Could not find an area named "..areaName
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end
end