Module:CombatAreas: Difference between revisions

From Melvor Idle
(fixed a typo)
(_getAreaRequirements: Resolve cases where requirement text returned could contain empty lines)
 
(36 intermediate revisions by 3 users not shown)
Line 1: Line 1:
--NOTE: Some tables are in Module:CombatAreas/AreaTables to prevent loop from referencing Monsters
local p = {}
local p = {}


local Constants = mw.loadData('Module:Constants/data')
local Constants = require('Module:Constants')
local AreaData = mw.loadData('Module:CombatAreas/data')
 
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 Monsters = require('Module:Monsters')
 
local areaMap = {
["combat"] = 'combatAreas',
["dungeon"] = 'dungeons',
["slayer"] = 'slayerAreas'
}


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
  mw.log(name)
for k, areaType in pairs(areaMap) do
  --There are three types of areas but the lists are pretty short so looping all of them isn't a real issue
local area = GameData.getEntityByName(areaType, name)
  for i, area in pairs(AreaData.combatAreas) do
if area ~= nil then
    if area.areaName == name then
return area
      result = Shared.clone(area)
end
      result.id = i - 1
end
      return result
end
    end
 
  end
function p.getAreaByID(id, type)
local areaType = areaMap[type]
if areaType ~= nil then
return GameData.getEntityByID(areaType, id)
end
end
 
function p.getAreaFilterType(name, type)
local areaType = areaMap[type]
if areaType ~= nil then
return GameData.getEntityByName(areaType, name)
end
end
 
function p.getAreas(checkFunc)
local resultArray = nil
 
for i, areaType in pairs(areaMap) do
local areas = GameData.getEntities(areaType, checkFunc)
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


  for i, area in pairs(AreaData.slayerAreas) do
return resultArray
    if area.areaName == name then
end
      result = Shared.clone(area)
      result.id = i - 1
      return result
    end
  end


  for i, area in pairs(AreaData.dungeons) do
--Returns the expansion icon for the area if it has one
    if area.name == name then
function p.getExpansionIcon(frame)
      result = Shared.clone(area)
local areaName = frame.args ~= nil and frame.args[1] or frame
      result.type = 'dungeon'
local area = p.getArea(areaName)
      result.id = i - 1
if area == nil then
      return result
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
    end
end
  end
return Icons.getExpansionIcon(area.id)
end


  return nil
function p._getAreaRequirements(area)
local resultArray = {}
if area.entryRequirements ~= nil then
local reqText = Common.getRequirementString(area.entryRequirements)
if reqText ~= nil then
table.insert(resultArray, reqText)
end
end
 
if area.unlockRequirement ~= nil then
-- Avoid repeating the same requirements twice, can happen for some dungeons e.g. Impending Darkness
if area.entryRequirements == nil or mw.dumpObject(area.unlockRequirement) ~= mw.dumpObject(area.entryRequirements) then
local reqText = Common.getRequirementString(area.unlockRequirement)
if reqText ~= nil then
table.insert(resultArray, reqText)
end
end
end
 
return table.concat(resultArray, '<br/>')
end
end


function p.getAreaMonsterTable(frame)
function p.getAreaRequirementsForBox(frame)
  local areaName = frame.args ~= nil and frame.args[1] or frame
--Returns infobox formatting for requirements, or returns nothing if there are none.
  local area = p.getArea(areaName)
local areaName = frame.args ~= nil and frame.args[1] or frame
  if area == nil then
local area = p.getArea(areaName)
    return "ERROR: Could not find an area named "..areaName
if area == nil then
  end
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end


  if area.type == 'dungeon' then
local reqs = p._getAreaRequirements(area)
    return p.getDungeonMonsterTable(frame)
if reqs ~= '' then
  end
reqs = "|-\r\n|'''Requirements:'''\r\n"..reqs
end
return reqs
end


  local tableTxt = '{| class="wikitable sortable"'
function p._getAreaStat(area, statName)
  tableTxt = tableTxt..'\r\n! Name !! Combat Level !! Hitpoints !! Max Hit !! [[Combat Triangle|Combat Style]]'
if statName == 'requirements' then
  for i, monsterID in pairs(area.monsters) do
return p._getAreaRequirements(area)
    local monster = Monsters.getMonsterByID(monsterID)
elseif statName == 'areaEffectDesc' then
    tableTxt = tableTxt..'\r\n|-\r\n|'..Icons.Icon({monster.name, type='monster'})
if area.areaEffect ~= nil then
    tableTxt = tableTxt..'||'..Monsters.getMonsterCombatLevel(monster.name)
local descText, subIdx = string.gsub(area.areaEffectDescription, '${effectValue}', area.areaEffect.magnitude or 0)
    tableTxt = tableTxt..'||'..Shared.formatnum(Monsters.getMonsterHP(monster.name))
return descText
    tableTxt = tableTxt..'||'..Shared.formatnum(Monsters.getMonsterMaxHit(monster.name))
else
    tableTxt = tableTxt..'||'..Monsters.getMonsterStyleIcon({monster.name, nolink='true'})
return 'None'
  end
end
  tableTxt = tableTxt..'\r\n|}'
elseif statName == 'difficulty' then
  return tableTxt
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.getDungeonMonsterTable(frame)
function p.getAreaStat(frame)
  local areaName = frame.args ~= nil and frame.args[1] or frame
local areaName = frame.args ~= nil and frame.args[1] or frame[1]
  local area = p.getArea(areaName)
local statName = frame.args ~= nil and frame.args[2] or frame[2]
  if area == nil then
local area = p.getArea(areaName)
    return "ERROR: Could not find a dungeon named "..areaName
if area == nil then
  end
return Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end
 
return p._getAreaStat(area, statName)
end


  --For Dungeons, go through and count how many of each monster are in the dungeon first
function p.getMonsterAreas(monsterID)
  local monsterCounts = {}
-- Special handling for Lair of the Spider Queen, which has a random list of enemies
  for i, monsterID in pairs(area.monsters) do
local randomSpiderCheck = Shared.contains(GameData.rawData.spiderLairMonsters, monsterID)
    if monsterCounts[monsterID] == nil then
return p.getAreas(
      monsterCounts[monsterID] = 1
function(area)
    else
return Shared.contains(area.monsterIDs, monsterID) or
      monsterCounts[monsterID] = monsterCounts[monsterID] + 1
(randomSpiderCheck and Shared.contains(area.monsterIDs, 'melvorTotH:RandomSpiderLair'))
    end
end)
  end
end


  local usedMonsters = {}
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 Shared.printError('No area named "' .. areaName .. '" exists in the data module')
end


  local tableTxt = '{| class="wikitable sortable"'
local result = p._getAreaStat(area, 'requirements')
  tableTxt = tableTxt..'\r\n! Name !! Combat Level !! Hitpoints !! Max Hit !! [[Combat Triangle|Combat Style]] !! Count'
if result ~= '' then
  for i, monsterID in pairs(area.monsters) do
result = "\r\n|-\r\n|'''Requirements:'''<br/>"..result
    if not Shared.contains(usedMonsters, monsterID) then
end
      local monster = Monsters.getMonsterByID(monsterID)
return result
      local name = monster.name
      if monsterID == 51 then name = 'Spider2' end
      tableTxt = tableTxt..'\r\n|-\r\n|'..Icons.Icon({name, type='monster'})
      tableTxt = tableTxt..'||'..Monsters.getMonsterCombatLevel(name)
      tableTxt = tableTxt..'||'..Shared.formatnum(Monsters.getMonsterHP(name))
      tableTxt = tableTxt..'||'..Shared.formatnum(Monsters.getMonsterMaxHit(name))
      tableTxt = tableTxt..'||'..Monsters.getMonsterStyleIcon({name, nolink='true'})
      tableTxt = tableTxt..'||'..monsterCounts[monsterID]
      table.insert(usedMonsters, monsterID)
    end
  end
  tableTxt = tableTxt..'\r\n|}'
  return tableTxt
end
end


return p
return p

Latest revision as of 21:58, 6 October 2023

Data is pulled from Module:GameData/data


--NOTE: Some tables are in Module:CombatAreas/AreaTables to prevent loop from referencing Monsters
local p = {}

local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Common = require('Module:Common')
local Icons = require('Module:Icons')

local areaMap = {
	["combat"] = 'combatAreas',
	["dungeon"] = 'dungeons',
	["slayer"] = 'slayerAreas'
}

function p.getArea(name)
	--There are three types of areas but the lists are pretty short so looping all of them isn't a real issue
	for k, areaType in pairs(areaMap) do
		local area = GameData.getEntityByName(areaType, name)
		if area ~= nil then
			return area
		end
	end
end

function p.getAreaByID(id, type)
	local areaType = areaMap[type]
	if areaType ~= nil then
		return GameData.getEntityByID(areaType, id)
	end
end

function p.getAreaFilterType(name, type)
	local areaType = areaMap[type]
	if areaType ~= nil then
		return GameData.getEntityByName(areaType, name)
	end
end

function p.getAreas(checkFunc)
	local resultArray = nil

	for i, areaType in pairs(areaMap) do
		local areas = GameData.getEntities(areaType, checkFunc)
		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

	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

function p._getAreaRequirements(area)
	local resultArray = {}
	if area.entryRequirements ~= nil then
		local reqText = Common.getRequirementString(area.entryRequirements)
		if reqText ~= nil then
			table.insert(resultArray, reqText)
		end
	end

	if area.unlockRequirement ~= nil then
		-- Avoid repeating the same requirements twice, can happen for some dungeons e.g. Impending Darkness
		if area.entryRequirements == nil or mw.dumpObject(area.unlockRequirement) ~= mw.dumpObject(area.entryRequirements) then
			local reqText = Common.getRequirementString(area.unlockRequirement)
			if reqText ~= nil then
				table.insert(resultArray, reqText)
			end
		end
	end

	return table.concat(resultArray, '<br/>')
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

function p._getAreaStat(area, statName)
	if statName == 'requirements' then
		return p._getAreaRequirements(area)
	elseif statName == 'areaEffectDesc' then
		if area.areaEffect ~= nil then
			local descText, subIdx = string.gsub(area.areaEffectDescription, '${effectValue}', area.areaEffect.magnitude 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 Shared.printError('No area named "' .. areaName .. '" exists in the data module')
	end

	return p._getAreaStat(area, statName)
end

function p.getMonsterAreas(monsterID)
	-- Special handling for Lair of the Spider Queen, which has a random list of enemies
	local randomSpiderCheck = Shared.contains(GameData.rawData.spiderLairMonsters, monsterID)
	return p.getAreas(
		function(area)
			return Shared.contains(area.monsterIDs, monsterID) or
				(randomSpiderCheck and Shared.contains(area.monsterIDs, 'melvorTotH:RandomSpiderLair'))
		end)
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 Shared.printError('No area named "' .. areaName .. '" exists in the data module')
	end

	local result = p._getAreaStat(area, 'requirements')
	if result ~= '' then
		result = "\r\n|-\r\n|'''Requirements:'''<br/>"..result
	end
	return result
end

return p