Module:Pets: Difference between revisions

From Melvor Idle
(Added drop odds to boss pet sidebar)
(Added new getPets function for use in the new ModifierTables module that's in progress)
(12 intermediate revisions by 2 users not shown)
Line 4: Line 4:


local PetData = mw.loadData('Module:Pets/data')
local PetData = mw.loadData('Module:Pets/data')
local Constants = mw.loadData('Module:Constants/data')


local Shared = require( "Module:Shared" )
local Shared = require( "Module:Shared" )
local Constants = require('Module:Constants')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Skills = require('Module:Skills')
local Skills = require('Module:Skills')
local Zones = require('Module:CombatAreas')
local CombatAreas = require('Module:CombatAreas')




Line 41: Line 41:
   local skillID = Skills.getSkillID(skillName)
   local skillID = Skills.getSkillID(skillName)
   for i, pet in pairs(PetData.Pets) do
   for i, pet in pairs(PetData.Pets) do
     if(skillID == pet.skill) then
    --Deliberately excluding Ty. He knows what he did.
     if(skillID == pet.skill and pet.name ~= 'Ty') then
       result = Shared.clone(pet)
       result = Shared.clone(pet)
       --Make sure every pet has an id, and account for Lua being 1-index
       --Make sure every pet has an id, and account for Lua being 1-index
Line 49: Line 50:
   end
   end
   return result
   return result
end
function p.getPets(checkFunc)
  local result = {}
  for i, pet in Shared.skpairs(PetData.Pets) do
    if checkFunc(pet) then
      local newPet = Shared.clone(pet)
      newPet.id = i - 1
      table.insert(result, newPet)
    end
  end
  return result
end
function p._getPetSource(pet)
  local sourceOverrides = {
    -- Format: ['PetName'] = {'Source', UseIcon}
    -- UseIcon = true if Source has an associated icon, false otherwise
    ['Asura'] = {'Slayer', true},
    ['Ripper the Reindeer'] = {'[[Events#Christmas_Event_2020|Christmas Event 2020]]', false},
    ['Jerry the Giraffe'] = {'[[Golbin Raid|Golbin Raid Shop]]', false},
    ['Preston the Platypus'] = {'[[Golbin Raid|Golbin Raid Shop]]', false}
  }
  local petSource = ''
  local useIcon = true
  local override = sourceOverrides[pet.name]
  if override ~= nil then
    petSource = override[1] ~= nil and override[1] or pet.acquiredBy
    useIcon = override[2]
  elseif pet.acquiredBy ~= nil then
    petSource = pet.acquiredBy
  end
  -- Determine icon type (if any)
  local iconType = nil
  if Skills.getSkillID(petSource) ~= nil then
    iconType = 'skill'
  else
    local combatArea = CombatAreas.getArea(petSource)
    if combatArea ~= nil then
      iconType = combatArea.type
    end
  end
 
  if useIcon then
    petSource = Icons.Icon({petSource, type=iconType})
  end
  return petSource
end
function p._getPetEffect(pet)
  local effectOverrides = {
    ['Ripper the Reindeer'] = 'None',
  }
  if effectOverrides[pet.name] ~= nil then
    return effectOverrides[pet.name]
  elseif pet.modifiers ~= nil then
    local effects = {}
    for effectName, effectValue in pairs(pet.modifiers) do
      table.insert(effects, Constants._getModifierText(effectName, effectValue, false))
    end
    return table.concat(effects, '<br/>')
  else
    return pet.description
  end
end
end


Line 57: Line 123:
   result = result..'!Pet!!Name!!Effect'
   result = result..'!Pet!!Name!!Effect'
   result = result..'\r\n|-\r\n|'..Icons.Icon({pet.name, type='pet', size='60', notext=true})
   result = result..'\r\n|-\r\n|'..Icons.Icon({pet.name, type='pet', size='60', notext=true})
   result = result..'||[['..pet.name..']]||'..pet.description
   result = result..'||[['..pet.name..']]||'..p._getPetEffect(pet)
   result = result..'\r\n|}'
   result = result..'\r\n|}'
   return result
   return result
Line 74: Line 140:
   local name = (args.name ~= nil and args.name ~= '') and args.name or args[1]
   local name = (args.name ~= nil and args.name ~= '') and args.name or args[1]
   local pet = p.getPet(name)
   local pet = p.getPet(name)
   local effect = (args.effect ~= nil and args.effect ~= '') and args.effect or pet.description
   local effect = (args.effect ~= nil and args.effect ~= '') and args.effect or p._getPetEffect(pet)
 
   local completionReq = (pet.ignoreCompletion ~= nil and pet.ignoreCompletion) and 'No' or 'Yes'
   local source = nil
  if (args.skill ~= nil and args.skill ~= '') then
    source = args.skill
  elseif pet.skill ~= nil and pet.skill >= 0 then
    source = Icons.Icon({Skills.getSkillName(pet.skill), type='skill'})
  else
    local combatArea = Zones.getArea(pet.acquiredBy)
    if combatArea ~= nil then
      source = Icons.Icon({combatArea.name, type=combatArea.type})
    end
  end


   local dropChance = nil
   local dropChance = nil
Line 93: Line 148:
     dropChance = '1 in '..odds..' ('..Shared.round(100 / odds, 2, 2)..'%)'
     dropChance = '1 in '..odds..' ('..Shared.round(100 / odds, 2, 2)..'%)'
   end
   end
    
    
   result = '{| class="wikitable" style="float:right; clear:right;"\r\n|-\r\n'
   result = '{| class="wikitable" style="float:right; clear:right;"\r\n|-\r\n'
   result = result..'! '..name..'\r\n|-\r\n| '
   result = result..'! '..name..'\r\n|-\r\n| '
   result = result..Icons.Icon({name, type='pet', size='250', notext=true})
   result = result..Icons.Icon({name, type='pet', size='250', notext=true})
   result = result..'\r\n|-\r\n| Pet ID: '..pet.id
   result = result.."\r\n|-\r\n|'''Pet ID:''' "..pet.id
 
   result = result.."\r\n|-\r\n|'''Source:''' "..p._getPetSource(pet)
   result = result..'\r\n|-\r\n| Source: '..source
   if dropChance ~= nil then
   if dropChance ~= nil then
     result = result..'\r\n|-\r\n| Drop Chance: '..dropChance
     result = result.."\r\n|-\r\n|'''Drop Chance:''' "..dropChance
   end
   end
 
   result = result.."\r\n|-\r\n| style =\"width: 250px;\"|'''Effect:''' "..effect
   result = result..'\r\n|-\r\n| style ="width: 250px;"|Effect: '..effect..'\r\n|}'
  result = result .. "\r\n|-\r\n|'''Part of 100% Completion:''' " .. completionReq .. "\r\n|}"


   return result
   return result
Line 112: Line 165:
function p.getPetPageTable()
function p.getPetPageTable()
   local result = ''
   local result = ''
  local petList = Shared.clone(PetData.Pets)


  local petList = {}
   result = '{|class="wikitable lighttable"'
  local acquiredOverrides = {
    ['Ripper the Reindeer'] = '[[Events#Christmas_Event_2020|Christmas Event 2020]]',
  }
  local effectOverrides = {
    ['Ripper the Reindeer'] = 'None',
  }
  local acquired = nil
  local temp = nil
  for i, pet in pairs(PetData.Pets) do
    temp = Shared.clone(pet)
 
    if(effectOverrides[temp.name] ~= nil) then
      temp.description = effectOverrides[temp.name]
    end
    if(temp.name == 'Asura') then temp.acquiredBy = 'Slayer' end
 
    acquired = ''
    if(Skills.getSkillID(temp.acquiredBy) ~= nil) then
      acquired = 'skill'
    elseif Zones.getAreaFilterType('slayer', temp.acquiredBy) ~= nil then
      acquired = 'slayer'
    elseif Zones.getAreaFilterType('dungeon', temp.acquiredBy) ~= nil then
      acquired = 'dungeon'
    end
    temp.type = acquired
 
    table.insert(petList, temp)
  end
 
   result = result..'{|class="wikitable lighttable"'
   result = result..'\r\n|-\r\n! Name !! Image !! Acquired From !! Effect'
   result = result..'\r\n|-\r\n! Name !! Image !! Acquired From !! Effect'


Line 153: Line 177:
     result = result..'\r\n|-\r\n|[['..thisPet.name..']]'
     result = result..'\r\n|-\r\n|[['..thisPet.name..']]'
     result = result..'||'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true})
     result = result..'||'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true})
    result = result..'||'..p._getPetSource(thisPet)
    result = result..'||'..p._getPetEffect(thisPet)
  end
  result = result..'\r\n|}'


    if acquiredOverrides[thisPet.name] ~= nil then
  return result
      result = result..'||'..acquiredOverrides[thisPet.name]
end
 
function p.getDungeonBoxPetText(frame)
  local dungeonName = frame.args ~= nil and frame.args[1] or frame
  local dung = CombatAreas.getArea(dungeonName)
  if dung == nil then
    return 'ERROR: Invalid dungeon name '..dungeonName..'[[Category:Pages with script errors]]'
  end
 
  local result = ''
  local pet = p.getPetByID(dung.petID)
  if pet ~= nil then
    result = "\r\n|-\r\n|'''[[Pets#Boss Pets|Pet]]:'''<br/>"
    result = result..Icons.Icon({pet.name, type='pet'})
 
    local dropChance = ''
    if dung.name == 'Into the Mist' then
      dropChance = 'Guaranteed after 5 clears'
     else
     else
       result = result..'||'..Icons.Icon({thisPet.acquiredBy, type=thisPet.type})
       local odds = pet.obtained.dungeonCompletion[1][2]
      dropChance = '1 in '..odds..' ('..Shared.round(100 / odds, 2, 2)..'%)'
     end
     end
     result = result..'||'..thisPet.description
     result = result.."\r\n|-\r\n|'''Pet Drop Chance:'''<br/>"..dropChance
   end
   end
  result = result..'\r\n|}'


   return result
   return result

Revision as of 22:20, 22 April 2021

Data for this page is stored in Module:GameData/data


--This module contains all sorts of functions for getting data on pets

local p = {}

local PetData = mw.loadData('Module:Pets/data')

local Shared = require( "Module:Shared" )
local Constants = require('Module:Constants')
local Icons = require('Module:Icons')
local Skills = require('Module:Skills')
local CombatAreas = require('Module:CombatAreas')


function p.getPetByID(ID)
  local result = Shared.clone(PetData.Pets[ID + 1])
  if result ~= nil then
    result.id = ID
  end
  return result
end

function p.getPet(name)
  local result = nil
  name = string.gsub(name, "%%27", "&apos;")
  name = string.gsub(name, "'", "&apos;")
  name = string.gsub(name, "&#39;", "&apos;")
  for i, pet in pairs(PetData.Pets) do
    local PetName = string.gsub(pet.name, '#', '')
    if(name == PetName) then
      result = Shared.clone(pet)
      --Make sure every pet has an id, and account for Lua being 1-index
      result.id = i - 1
      break
    end
  end
  return result
end

function p.getPetBySkill(skillName)
  local result = nil
  local skillID = Skills.getSkillID(skillName)
  for i, pet in pairs(PetData.Pets) do
    --Deliberately excluding Ty. He knows what he did.
    if(skillID == pet.skill and pet.name ~= 'Ty') then
      result = Shared.clone(pet)
      --Make sure every pet has an id, and account for Lua being 1-index
      result.id = i - 1
      break
    end
  end
  return result
end

function p.getPets(checkFunc)
  local result = {}
  for i, pet in Shared.skpairs(PetData.Pets) do
    if checkFunc(pet) then
      local newPet = Shared.clone(pet)
      newPet.id = i - 1
      table.insert(result, newPet)
    end
  end
  return result
end

function p._getPetSource(pet)
  local sourceOverrides = {
    -- Format: ['PetName'] = {'Source', UseIcon}
    -- UseIcon = true if Source has an associated icon, false otherwise
    ['Asura'] = {'Slayer', true},
    ['Ripper the Reindeer'] = {'[[Events#Christmas_Event_2020|Christmas Event 2020]]', false},
    ['Jerry the Giraffe'] = {'[[Golbin Raid|Golbin Raid Shop]]', false},
    ['Preston the Platypus'] = {'[[Golbin Raid|Golbin Raid Shop]]', false}
  }
  local petSource = ''
  local useIcon = true
  local override = sourceOverrides[pet.name]
  if override ~= nil then
    petSource = override[1] ~= nil and override[1] or pet.acquiredBy
    useIcon = override[2]
  elseif pet.acquiredBy ~= nil then
    petSource = pet.acquiredBy
  end

  -- Determine icon type (if any)
  local iconType = nil
  if Skills.getSkillID(petSource) ~= nil then
    iconType = 'skill'
  else
    local combatArea = CombatAreas.getArea(petSource)
    if combatArea ~= nil then
      iconType = combatArea.type
    end
  end
  
  if useIcon then
    petSource = Icons.Icon({petSource, type=iconType})
  end
  return petSource
end

function p._getPetEffect(pet)
  local effectOverrides = {
    ['Ripper the Reindeer'] = 'None',
  }
  if effectOverrides[pet.name] ~= nil then
    return effectOverrides[pet.name]
  elseif pet.modifiers ~= nil then
    local effects = {}
    for effectName, effectValue in pairs(pet.modifiers) do
      table.insert(effects, Constants._getModifierText(effectName, effectValue, false))
    end
    return table.concat(effects, '<br/>')
  else
    return pet.description
  end
end

function p.getPetTable(frame)
  local petName = frame.args ~= nil and frame.args[1] or frame
  local pet = p.getPet(petName)
  local result = '{| class="wikitable"\r\n'
  result = result..'!Pet!!Name!!Effect'
  result = result..'\r\n|-\r\n|'..Icons.Icon({pet.name, type='pet', size='60', notext=true})
  result = result..'||[['..pet.name..']]||'..p._getPetEffect(pet)
  result = result..'\r\n|}'
  return result
end

function p.getPetTableBySkill(frame)
  local result = nil
  local skillName = frame.args ~= nil and frame.args[1] or frame

  return p.getPetTable(p.getPetBySkill(skillName).name)
end

function p.getPetSidebar(frame)
  local args = frame.args ~= nil and frame.args or frame
  local result = nil
  local name = (args.name ~= nil and args.name ~= '') and args.name or args[1]
  local pet = p.getPet(name)
  local effect = (args.effect ~= nil and args.effect ~= '') and args.effect or p._getPetEffect(pet)
  local completionReq = (pet.ignoreCompletion ~= nil and pet.ignoreCompletion) and 'No' or 'Yes'

  local dropChance = nil
  if pet.obtained ~= nil and pet.obtained.dungeonCompletion ~= nil then
    local odds = pet.obtained.dungeonCompletion[1][2]
    dropChance = '1 in '..odds..' ('..Shared.round(100 / odds, 2, 2)..'%)'
  end
  
  result = '{| class="wikitable" style="float:right; clear:right;"\r\n|-\r\n'
  result = result..'! '..name..'\r\n|-\r\n| '
  result = result..Icons.Icon({name, type='pet', size='250', notext=true})
  result = result.."\r\n|-\r\n|'''Pet ID:''' "..pet.id
  result = result.."\r\n|-\r\n|'''Source:''' "..p._getPetSource(pet)
  if dropChance ~= nil then
    result = result.."\r\n|-\r\n|'''Drop Chance:''' "..dropChance
  end
  result = result.."\r\n|-\r\n| style =\"width: 250px;\"|'''Effect:''' "..effect
  result = result .. "\r\n|-\r\n|'''Part of 100% Completion:''' " .. completionReq .. "\r\n|}"

  return result
end

function p.getPetPageTable()
  local result = ''
  local petList = Shared.clone(PetData.Pets)

  result = '{|class="wikitable lighttable"'
  result = result..'\r\n|-\r\n! Name !! Image !! Acquired From !! Effect'

  table.sort(petList, function(a, b)
                         return p.getPet(a.name).id < p.getPet(b.name).id
                       end)

  for i, thisPet in pairs(petList) do
    result = result..'\r\n|-\r\n|[['..thisPet.name..']]'
    result = result..'||'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true})
    result = result..'||'..p._getPetSource(thisPet)
    result = result..'||'..p._getPetEffect(thisPet)
  end
  result = result..'\r\n|}'

  return result
end

function p.getDungeonBoxPetText(frame)
  local dungeonName = frame.args ~= nil and frame.args[1] or frame
  local dung = CombatAreas.getArea(dungeonName)
  if dung == nil then
    return 'ERROR: Invalid dungeon name '..dungeonName..'[[Category:Pages with script errors]]'
  end

  local result = ''
  local pet = p.getPetByID(dung.petID)
  if pet ~= nil then
    result = "\r\n|-\r\n|'''[[Pets#Boss Pets|Pet]]:'''<br/>"
    result = result..Icons.Icon({pet.name, type='pet'})

    local dropChance = ''
    if dung.name == 'Into the Mist' then
      dropChance = 'Guaranteed after 5 clears'
    else
      local odds = pet.obtained.dungeonCompletion[1][2]
      dropChance = '1 in '..odds..' ('..Shared.round(100 / odds, 2, 2)..'%)'
    end
    result = result.."\r\n|-\r\n|'''Pet Drop Chance:'''<br/>"..dropChance
  end

  return result
end

function p.getPetNavbox(frame)
  --•
  local result = '{| class="wikitable" style="margin:auto; text-align:center; clear:both; width: 100%"'
  result = result..'\r\n|-\r\n!colspan="2"|[[Pets]]'

  local skillPetList = {}
  local bossPetList = {}
  local otherPetList = {}
  for i, petData in Shared.skpairs(PetData.Pets) do
    if petData.skill ~= nil and petData.skill >= 0 and petData.name ~= "Ty" then
      table.insert(skillPetList, Icons.Icon({petData.name, type='pet'}))
    elseif petData.obtained ~= nil and petData.obtained.dungeonCompletion ~= nil then
      table.insert(bossPetList, Icons.Icon({petData.name, type='pet'}))
    else
      table.insert(otherPetList, Icons.Icon({petData.name, type='pet'}))
    end
  end
  table.sort(skillPetList, function(a, b) return a < b end)
  table.sort(bossPetList, function(a, b) return a < b end)
  table.sort(otherPetList, function(a, b) return a < b end)
  result = result..'\r\n|-\r\n!Skill Pets\r\n|'..table.concat(skillPetList, ' • ')
  result = result..'\r\n|-\r\n!Boss Pets\r\n|'..table.concat(bossPetList, ' • ')
  result = result..'\r\n|-\r\n!Other Pets\r\n|'..table.concat(otherPetList, ' • ')
  result = result..'\r\n|}'
  return result
end

return p