Module:Magic

From Melvor Idle
Revision as of 22:01, 23 January 2021 by Falterfire (talk | contribs) (Added p.getCurseTable, p.getAuroraTable, and p.getAncientTable)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Data pulled from Module:GameData/data


local p = {}

local MagicData = mw.loadData('Module:Magic/data')

local Areas = require('Module:CombatAreas')
local Shared = require('Module:Shared')
local Icons = require('Module:Icons')
local Items = require('Module:Items')

function processSpell(section, index)
  local result = Shared.clone(MagicData[section][index])
  result.id = index - 1
  result.type = section
  return result
end

function p.getSpell(name, type)
  local section = type
  if type == 'Spell' or type == 'Standard' then
    section = 'Spells'
  elseif type == 'Curse' then
    section = 'Curses'
  elseif type == 'Aurora' then
    section = 'Auroras'
  elseif type == 'Alt Magic' or type == 'Alternative Magic' then
    section='AltMagic'
  end
  
  if section == nil then
    for i, section in Shared.skpairs(MagicData) do
      for j, spell in Shared.skpairs(section) do
        if spell.name == name then
          return processSpell(i, j)
        end
      end
    end
  elseif section ~= nil and MagicData[section] ~= nil then
    for i, spell in Shared.skpairs(MagicData[section]) do
      if spell.name == name then
        return processSpell(section, i)
      end
    end
  else
    return nil
  end
end

function p.getSpellByID(type, id)
  local section = type
  if type == nil or type == 'Spell' or type == 'Standard' then
    section = 'Spells'
  elseif type == 'Curse' then
    section = 'Curses'
  elseif type == 'Aurora' then
    section = 'Auroras'
  elseif type == 'Alt Magic' or type == 'Alternative Magic' then
    section='AltMagic'
  end
  
  if MagicData[section] ~= nil then
    return processSpell(section, id + 1)
  else
    return nil
  end
end

function p.getTypeString(type)
  if type == 'Auroras' then
    return 'Aurora'
  elseif type == 'Curses' then
    return 'Curse'
  elseif type == 'AltMagic' then
    return 'Alt. Magic'
  elseif type == 'Spells' then
    return "Combat Spell"
  elseif type == 'Ancient' then
     return 'Ancient Magick'
  end
end

function p._getSpellIcon(spell, size)
  if size == nil then size = 50 end
  if spell.type == 'Auroras' then
    return Icons.Icon({spell.name, type='aurora', notext=true, size=size})
  elseif spell.type == 'Curses' then
    return Icons.Icon({spell.name, type='curse', notext=true, size=size})
  else
    return Icons.Icon({spell.name, type='spell', notext=true, size=size})
  end
end

function p._getSpellRequirements(spell)
  local result = ''
  result = result..Icons._SkillReq('Magic', spell.magicLevelRequired)
  if spell.requiredItem ~= nil and spell.requiredItem >= 0 then
    local reqItem = Items.getItemByID(spell.requiredItem)
    result = result..'<br/>'..Icons.Icon({reqItem.name, type='item', notext=true})..' equipped'
  end
  if spell.requiredDungeonCompletion ~= nil then
    local dung = Areas.getAreaByID('dungeon', spell.requiredDungeonCompletion[1])
    result = result..'<br/>'..Icons.Icon({dung.name, type='dungeon', notext=true, qty=spell.requiredDungeonCompletion[2]})..' Clears'
  end
  return result
end

function p._getSpellRunes(spell)
  local result = ''
  for i, req in Shared.skpairs(spell.runesRequired) do
    local rune = Items.getItemByID(req.id)
    if i > 1 then result = result..', ' end
    result = result..Icons.Icon({rune.name, type='item', notext=true, qty=req.qty})
  end
  if spell.runesRequiredAlt ~= nil and not Shared.tablesEqual(spell.runesRequired, spell.runesRequiredAlt) then
    result = result.."<br/>'''OR'''<br/>"
    for i, req in pairs(spell.runesRequiredAlt) do
      local rune = Items.getItemByID(req.id)
      if i > 1 then result = result..', ' end
      result = result..Icons.Icon({rune.name, type='item', notext=true, qty=req.qty})
    end
  end
  return result
end

function p.getSpellRunes(frame)
  local spellName = frame.args ~= nil and frame.args[1] or frame
  local spell = p.getSpell(spellName)
  if spell == nil then
    return "ERROR: No spell named "..spellName.." exists in the data module"
  end
  return p._getSpellRunes(spell)
end

function p._getSpellStat(spell, stat)
  if stat == 'bigIcon' then
    return p._getSpellIcon(spell, 250)
  elseif stat == 'icon' then
    return p._getSpellIcon(spell)
  elseif stat == 'requirements' then
    return p._getSpellRequirements(spell)
  elseif stat == 'runes' then
    return p._getSpellRunes(spell)
  elseif stat == 'type' then
    return p.getTypeString(spell.type)
  end
  return spell[stat]
end

function p.getSpellStat(frame)
  local spellName = frame.args ~= nil and frame.args[1] or frame[1]
  local statName = frame.args ~= nil and frame.args[2] or frame[2]
  local spell = p.getSpell(spellName)
  if spell == nil then
    return "ERROR: No spell named "..spellName.." found"
  end
  return p._getSpellStat(spell, statName)
end

function p.getOtherSpellBoxText(frame)
  local spellName = frame.args ~= nil and frame.args[1] or frame
  local spell = p.getSpell(spellName)
  if spell == nil then
    return "ERROR: No spell named "..spellName.." found"
  end

  local result = ''
  if spell.type == 'Spells' then
    result = result.."|-\r\n|'''Max Hit:''' "..(spell.maxHit * 10)
  end
  if spell.description ~= nil then
    result = result.."\r\n|-\r\n|'''Description:'''<br/>"..spell.description
  end

  return result
end

function p._getSpellCategories(spell)
  local result = '[[Category:Spells]]'
  result = result..'[[Category:'..p.getTypeString(spell.type)..']]'
  return result
end

function p.getSpellCategories(frame)
  local spellName = frame.args ~= nil and frame.args[1] or frame
  local spell = p.getSpell(spellName)
  if spell == nil then
    return "ERROR: No spell named "..spellName.." found"
  end
  return p._getSpellCategories(spell)
end

function p.getSpellsForRune(runeID)
  local spellList = {}
  for secName, secArray in Shared.skpairs(MagicData) do
    for i, spell in pairs(secArray) do
      local foundSpell = false
      for j, req in pairs(spell.runesRequired) do
        if req.id == runeID then
          table.insert(spellList, processSpell(secName, i))
          foundSpell = true
          break
        end
      end
      if spell.runesRequiredAlt ~= nil and not foundSpell then
        for j, req in pairs(spell.runesRequiredAlt) do
          if req.id == runeID then
            table.insert(spellList, processSpell(secName, i))
            break
          end
        end
      end
    end
  end
  table.sort(spellList, function(a, b) 
               if a.type ~= b.type then
                 return p.getSpellTypeIndex(a.type) < p.getSpellTypeIndex(b.type)
               else
                 return a.magicLevelRequired < b.magicLevelRequired
               end
             end)
  return spellList
end

function p.getSpellTypeIndex(type)
  if type == 'Spells' then
    return 0
  elseif type == 'Curses' then
    return 1
  elseif type == 'Auroras' then
    return 2
  elseif type == 'Ancient' then
    return 3
  elseif type == 'AltMagic' then
    return 4
  end
  return -1
end

function p.getSpellTypeLink(type)
  if type == 'Spells' then
    return Icons.Icon({'Magic', 'Standard', img='Standard', type='spellType'})
  elseif type == 'Curses' then
    return Icons.Icon({'Curses', 'Curse', img='Curse', type='spellType'})
  elseif type == 'Auroras' then
    return Icons.Icon({'Auroras', 'Aurora', img='Aurora', type='spellType'})
  elseif type == 'Ancient' then
    return Icons.Icon({'Ancient Magicks', 'Ancient', img='Ancient', type='spellType'})
  elseif type == 'AltMagic' then
    return Icons.Icon({'Alt. Magic', type='skill'})
  end
  return ''
end

function p._getSpellRow(spell, includeTypeColumn)
  local rowTxt = '\r\n|-\r\n|data-sort-value="'..spell.name..'"|'
  if spell.type == 'Auroras' then
    rowTxt = rowTxt..Icons.Icon({spell.name, type='aurora', notext=true, size=50})
  elseif spell.type == 'Curses' then
    rowTxt = rowTxt..Icons.Icon({spell.name, type='curse', notext=true, size=50})
  else
    rowTxt = rowTxt..Icons.Icon({spell.name, type='spell', notext=true, size=50})
  end
  rowTxt = rowTxt..'||[['..spell.name..']]'
  rowTxt = rowTxt..'||data-sort-value="'..spell.magicLevelRequired..'"|'..Icons._SkillReq('Magic', spell.magicLevelRequired)
  --Handle required items/dungeon clears
  if spell.requiredItem ~= nil and spell.requiredItem >= 0 then
    local reqItem = Items.getItemByID(spell.requiredItem)
    rowTxt = rowTxt..'<br/>'..Icons.Icon({reqItem.name, type='item', notext=true})..' equipped'
  end
  if spell.requiredDungeonCompletion ~= nil then
    local dung = Areas.getAreaByID('dungeon', spell.requiredDungeonCompletion[1])
    rowTxt = rowTxt..'<br/>'..Icons.Icon({dung.name, type='dungeon', notext=true, qty=spell.requiredDungeonCompletion[2]})..' Clears'
  end

  if includeTypeColumn then
    rowTxt = rowTxt..'||data-sort-value="'..p.getSpellTypeIndex(spell.type)..'"|'
    rowTxt = rowTxt..p.getSpellTypeLink(spell.type)
  end
  if spell.type == 'Spells' then
    rowTxt = rowTxt..'||Combat spell with a max hit of '..(spell.maxHit * 10)
  else
    rowTxt = rowTxt..'||'..spell.description
  end
  rowTxt = rowTxt..'||style="text-align:center"|'
  rowTxt = rowTxt..p._getSpellRunes(spell)
  return rowTxt
end


function p.getCurseTable(frame)
  local result = '{|class="wikitable sortable"\r\n!colspan="2"|Spell'
  result = result..'!!Requirements'
  result = result..'!!style="width:275px"|Description'
  result = result..'!!Runes'
  for i, spell in pairs(MagicData.Curses) do
    local rowTxt = p._getSpellRow(processSpell('Curses', i), false)
    result = result..rowTxt
  end
  result = result..'\r\n|}'
  return result
end

function p.getAuroraTable(frame)
  local result = '{|class="wikitable sortable"\r\n!colspan="2"|Spell'
  result = result..'!!Requirements'
  result = result..'!!style="width:275px"|Description'
  result = result..'!!Runes'
  for i, spell in pairs(MagicData.Auroras) do
    local rowTxt = p._getSpellRow(processSpell('Auroras', i), false)
    result = result..rowTxt
  end
  result = result..'\r\n|}'
  return result
end

function p.getAncientTable(frame)
  local result = '{|class="wikitable sortable"\r\n!colspan="2"|Spell'
  result = result..'!!Requirements'
  result = result..'!!style="width:275px"|Description'
  result = result..'!!Runes'
  for i, spell in pairs(MagicData.Ancient) do
    local rowTxt = p._getSpellRow(processSpell('Ancient', i), false)
    result = result..rowTxt
  end
  result = result..'\r\n|}'
  return result
end

return p