Anonymous

Module:CombatAreas: Difference between revisions

From Melvor Idle
getExpansionIcon: Implement
(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)
(getExpansionIcon: Implement)
(3 intermediate revisions by the same user 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 Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Shop = require('Module:Shop')
local Shop = require('Module:Shop')


p.eventData = AreaData.event
local areaMap = {
 
    ["combat"] = 'combatAreas',
function processArea(area, index, type)
    ["dungeon"] = 'dungeons',
local result = Shared.clone(area)
    ["slayer"] = 'slayerAreas'
result.id = index - 1
}
if result.name == nil then
result.name = result.areaName
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
end
            return area
end
        end
 
    end
for i, area in pairs(AreaData.slayerAreas) do
end
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
function p.getAreaByID(id, type)
    local areaType = areaMap[type]
    if areaType ~= nil then
        return GameData.getEntityByID(areaType, id)
    end
end
end


function p.getAreaByID(type, id)
function p.getAreaFilterType(name, type)
if type == 'dungeon' then type = 'dungeons'
    local areaType = areaMap[type]
elseif type == 'combat' then type = 'combatAreas'
    if areaType ~= nil then
elseif type == 'slayer' then type = 'slayerAreas' end
        return GameData.getEntityByName(areaType, name)
return processArea(AreaData[type][id + 1], id + 1)
    end
end
end


function p.getAreaFilterType(type, name)
function p.getAreas(checkFunc)
local areaName = nil
local resultArray = 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
    for i, areaType in pairs(areaMap) do
if type == 'dungeon' then areaName = area.name
        local areas = GameData.getEntities(areaType, checkFunc)
else areaName = area.areaName end
        if resultArray == nil then
            resultArray = areas
        else
            for k, area in ipairs(areas) do
                table.insert(resultArray, area)
            end
        end
    end
    if resultArray == nil then
        resultArray = {}
    end


if areaName == name then
    return resultArray
return processArea(area, i, type)
end
end
 
return nil
end
end


function p.getAreas(checkFunc)
--Returns the expansion icon for the area if it has one
local resultArray = {}
function p.getExpansionIcon(frame)
 
local areaName = frame.args ~= nil and frame.args[1] or frame
for i, area in Shared.skpairs(AreaData.combatAreas) do
local area = p.getArea(areaName)
local temp = processArea(area, i, 'combat')
if area == nil then
if checkFunc(temp) then
return "ERROR: No area named " .. areaName .. " exists in the data module[[Category:Pages with script errors]]"
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
end
 
return resultArray
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)
local addReqsToArray = function(reqArray, requirements)
for i, reqDetails in Shared.skpairs(requirements) do
for i, reqDetails in ipairs(requirements) do
if reqDetails.type == 'Level' then
if reqDetails.type == 'SkillLevel' then
for j, lvlDetails in Shared.skpairs(reqDetails.levels) do
                local skillName = Constants.getSkillName(reqDetails.skillID)
local skill = Constants.getSkillName(lvlDetails.skill)
                if skillName ~= nil then
table.insert(reqArray, Icons._SkillReq(skill, lvlDetails.level))
                    table.insert(reqArray, Icons._SkillReq(skillName, reqDetails.level))
end
                end
elseif reqDetails.type == 'SlayerItem' then
elseif reqDetails.type == 'SlayerItem' then
local item = Items.getItemByID(reqDetails.itemID)
local item = Items.getItemByID(reqDetails.itemID)
table.insert(reqArray, Icons.Icon({item.name, type='item'})..' Equipped')
table.insert(reqArray, Icons.Icon({item.name, type='item'}) .. ' Equipped')
elseif reqDetails.type == 'Dungeon' then
elseif reqDetails.type == 'DungeonCompletion' then
for j, dungDetails in Shared.skpairs(reqDetails.dungeons) do
                local dung = p.getAreaByID(reqDetails.dungeonID, 'dungeon')
local dung = p.getAreaByID('dungeon', dungDetails.dungeonID)
                if dung ~= nil then
if dungDetails.count > 1 then
                    if reqDetails.count > 1 then
table.insert(reqArray, dungDetails.count..'x '..Icons.Icon({dung.name, type='dungeon'})..' Completions')
                        table.insert(reqArray, Shared.formatnum(reqDetails.count) .. 'x ' .. Icons.Icon({dung.name, type='dungeon'}) .. ' Completions')
else
                    else
table.insert(reqArray, Icons.Icon({dung.name, type='dungeon'})..' Completed')
                        table.insert(reqArray, Icons.Icon({dung.name, type='dungeon'}) .. ' Completed')
end
                    end
end
                end
elseif reqDetails.type == 'ShopPurchase' then
elseif reqDetails.type == 'ShopPurchase' then
local shopPurchase = Shop.processPurchase(reqDetails.category, reqDetails.id)
                local shopPurchase = GameData.getEntityByID('shopPurchases', reqDetails.purchaseID)
if shopPurchase ~= nil then
if shopPurchase ~= nil then
table.insert(reqArray, Shop._getPurchaseIcon({ shopPurchase }) .. ' Purchased')
table.insert(reqArray, Shop._getPurchaseIcon({ shopPurchase }) .. ' Purchased')
Line 135: Line 107:


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
        addReqsToArray(resultArray, area.unlockRequirement)
local unlockReqStr = mw.dumpObject(area.unlockRequirement)
        end
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
end


result = table.concat(resultArray, '<br/>')
return table.concat(resultArray, '<br/>')
return result
end
end


Line 160: Line 120:
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 189: Line 149:


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