Module:Pets: Difference between revisions
From Melvor Idle
m (Include script errors category) |
(Update for v1.1) |
||
Line 2: | Line 2: | ||
local p = {} | local p = {} | ||
local Shared = require( "Module:Shared" ) | local Shared = require( "Module:Shared" ) | ||
local Constants = require('Module:Constants') | local Constants = require('Module:Constants') | ||
local GameData = require('Module:GameData') | |||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
local | local Areas = require('Module:CombatAreas') | ||
-- Compute combat pet sources once for use later | |||
local function getCombatPetSources() | |||
local result = {} | |||
local areas = Areas.getAreas(function(area) return area.pet ~= nil end) | |||
for i, area in ipairs(areas) do | |||
result[area.petID] = { id = area.id, name = area.name, type = area.type, weight = area.weight } | |||
end | |||
end | |||
local CombatPetSources = getCombatPetSources() | |||
function p.getPetByID(ID) | function p.getPetByID(ID) | ||
return GameData.getEntityByID('pets', ID) | |||
end | end | ||
function p.getPet(name) | function p.getPet(name) | ||
name = string.gsub(name, "%%27", "'") | name = string.gsub(name, "%%27", "'") | ||
name = string.gsub(name, "'", "'") | name = string.gsub(name, "'", "'") | ||
name = string.gsub(name, "'", "'") | name = string.gsub(name, "'", "'") | ||
return GameData.getEntityByName('pets', name) | |||
end | end | ||
function p.getPets(checkFunc) | function p.getPets(checkFunc) | ||
return GameData.getEntities('pets', checkFunc) | |||
end | |||
function p._getPetSource(pet) | |||
local skillID = p._getPetSkill(pet) | |||
if skillID ~= nil then | |||
local skillName = Constants.getSkillName(skillID) | |||
return { id = skillID, name = skillName, type = 'skill' } | |||
elseif CombatPetSources ~= nil then | |||
return CombatPetSources[pet.id] | |||
end | end | ||
end | end | ||
function p. | function p._getPetSourceText(pet) | ||
local sourceOverrides = { | local sourceOverrides = { | ||
-- | -- useIcon: true if Source has an associated icon, false otherwise | ||
['Ripper the Reindeer'] = { text = '[[Events#Christmas Event 2020|Christmas Event 2020]]', useIcon = false }, | |||
['Festive Chio'] = { text = '[[Holiday Event 2021]]', useIcon = false }, | |||
['Ripper the Reindeer'] = {'[[Events# | ['Festive Cool Rock'] = { text = '[[Holiday Event 2021]]', useIcon = false }, | ||
['Festive Chio'] = {'[[Holiday Event 2021]]'}, | ['Jerry the Giraffe'] = { text = '[[Golbin Raid|Golbin Raid Shop]]', useIcon = false }, | ||
['Festive Cool Rock'] = {'[[Holiday Event 2021]]'}, | ['Preston the Platypus'] = { text = '[[Golbin Raid|Golbin Raid Shop]]', useIcon = false } | ||
['Jerry the Giraffe'] = {'[[Golbin Raid|Golbin Raid Shop]]', false}, | |||
['Preston the Platypus'] = {'[[Golbin Raid|Golbin Raid Shop]]', false | |||
} | } | ||
local | local petSourceText = nil | ||
local iconType = nil | |||
local useIcon = true | local useIcon = true | ||
local override = sourceOverrides[pet.name] | local override = sourceOverrides[pet.name] | ||
if override ~= nil then | if override ~= nil then | ||
petSourceText = override.text | |||
if override.useIcon ~= nil then | |||
useIcon = override.useIcon | |||
end | |||
end | end | ||
if petSourceText == nil then | |||
local petSource = p._getPetSource(pet) | |||
if petSource ~= nil then | |||
iconType = petSource.type | |||
petSourceText = petSource.name | |||
local | else | ||
if | useIcon = false | ||
iconType = | petSourceText = '' | ||
end | end | ||
end | end | ||
if useIcon then | if useIcon then | ||
return Icons.Icon({petSourceText, type=iconType}) | |||
else | |||
return petSourceText | |||
end | end | ||
end | end | ||
function p._getPetEffect(pet) | function p._getPetEffect(pet) | ||
local modKeys = {'modifiers', 'enemyModifiers'} | |||
local effects = {} | |||
for i, key in ipairs(modKeys) do | |||
if pet[key] ~= nil and not Shared.tableIsEmpty(pet[key]) then | |||
for effectName, effectValue in pairs(pet[key]) do | |||
local preText = (key == 'enemyModifiers' and 'All enemies have: ' or '') | |||
table.insert(effects, preText .. Constants._getModifierText(effectName, effectValue, false)) | |||
end | end | ||
end | end | ||
end | |||
if Shared.tableIsEmpty(effects) then | |||
return 'None' | |||
else | |||
return table.concat(effects, '<br/>') | |||
end | end | ||
end | end | ||
function p._getPetChance(pet) | function p._getPetChance(pet) | ||
if | local source = p._getPetSource(pet) | ||
if source ~= nil and source.weight ~= nil then | |||
if | -- Pet is from a dungeon or combat/slayer area | ||
-- Flaky logic for determining if pet is guaranteed or not | |||
return 'Guaranteed after ' .. | if source.weight <= 10 then | ||
return 'Guaranteed after ' .. Shared.formatnum(source.weight) .. ' clears' | |||
else | else | ||
return '1 in ' .. Shared.formatnum(source.weight) .. ' (' .. Shared.round(100 / source.weight, 2, 2) .. '%)' | |||
return '1 in ' .. | |||
end | end | ||
else | else | ||
-- Skill pet or other | -- Skill pet or other | ||
Line 144: | Line 118: | ||
function p._getPetSkill(pet) | function p._getPetSkill(pet) | ||
local skillOverrides = { | local skillOverrides = { | ||
['Ty'] = | ['melvorD:Ty'] = nil, | ||
['Mark'] = | ['melvorF:Mark'] = 'melvorD:Summoning' | ||
} | } | ||
if skillOverrides[pet.id] ~= nil then | |||
if skillOverrides[pet. | return skillOverrides[pet.id] | ||
else | else | ||
return skillID | return pet.skillID | ||
end | end | ||
end | end | ||
function p._getPetTable(pets) | function p._getPetTable(pets) | ||
if pets = | if type(pets) ~= 'table' or Shared.tableIsEmpty(pets) then | ||
return nil | |||
end | |||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable"\r\n!Pet!!Name!!Effect') | table.insert(resultPart, '{| class="wikitable"\r\n!Pet!!Name!!Effect') | ||
for i, pet in | for i, pet in ipairs(pets) do | ||
table.insert(resultPart, '|-') | table.insert(resultPart, '|-') | ||
table.insert(resultPart, '|style="text-align: center;"|' .. Icons.Icon({pet.name, type='pet', size=60, notext=true})) | table.insert(resultPart, '|style="text-align: center;"|' .. Icons.Icon({pet.name, type='pet', size=60, notext=true})) | ||
Line 184: | Line 156: | ||
else | else | ||
local pets = p.getPets(function(pet) return p._getPetSkill(pet) == skillID end) | local pets = p.getPets(function(pet) return p._getPetSkill(pet) == skillID end) | ||
if pets == nil then | if pets == nil or Shared.tableIsEmpty(pets) then | ||
return '' | return '' | ||
else | else | ||
Line 208: | Line 180: | ||
result = result..'style="text-align: center;"|' .. Icons.Icon({name, type='pet', size='250', notext=true}) | result = result..'style="text-align: center;"|' .. 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. | result = result.."\r\n|-\r\n|'''Source:''' "..p._getPetSourceText(pet) | ||
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 | ||
Line 220: | Line 192: | ||
function p.getPetPageTable() | function p.getPetPageTable() | ||
local result = '' | local result = '' | ||
result = '{|class="wikitable sortable lighttable stickyHeader"' | result = '{|class="wikitable sortable lighttable stickyHeader"' | ||
result = result..'\r\n|- class="headerRow-0"\r\n! Name !! Image !! Acquired From !! Effect' | result = result..'\r\n|- class="headerRow-0"\r\n! Name !! Image !! Acquired From !! Effect' | ||
for i, thisPet in ipairs(GameData.rawData.pets) do | |||
for i, thisPet in | |||
result = result..'\r\n|-\r\n|'..Icons.Icon({thisPet.name, type='pet', noicon=true}) | result = result..'\r\n|-\r\n|'..Icons.Icon({thisPet.name, type='pet', noicon=true}) | ||
result = result..'||style="text-align: center;"|'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true}) | result = result..'||style="text-align: center;"|'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true}) | ||
result = result..'||'..p. | result = result..'||'..p._getPetSourceText(thisPet) | ||
result = result..'||'..p._getPetEffect(thisPet) | result = result..'||'..p._getPetEffect(thisPet) | ||
end | end | ||
Line 242: | Line 209: | ||
function p.getDungeonBoxPetText(frame) | function p.getDungeonBoxPetText(frame) | ||
local dungeonName = frame.args ~= nil and frame.args[1] or frame | local dungeonName = frame.args ~= nil and frame.args[1] or frame | ||
local dung = | local dung = Areas.getArea(dungeonName) | ||
if dung == nil then | if dung == nil then | ||
return 'ERROR: Invalid dungeon name '..dungeonName..'[[Category:Pages with script errors]]' | return 'ERROR: Invalid dungeon name '..dungeonName..'[[Category:Pages with script errors]]' | ||
end | end | ||
if dung.pet ~= nil then | |||
local pet = p.getPetByID(dung.pet.petID) | |||
if pet ~= nil then | |||
local result = "\r\n|-\r\n|'''[[Pets#Boss Pets|Pet]]:'''<br/>" | |||
result = result..Icons.Icon({pet.name, type='pet'}) | |||
result = result.."\r\n|-\r\n|'''Pet Drop Chance:'''<br/>"..p._getPetChance(pet) | |||
return result | |||
end | |||
end | end | ||
end | end | ||
-- TODO Move to Module:Navboxes | |||
function p.getPetNavbox() | function p.getPetNavbox() | ||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; text-align:center; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n|-\r\n!colspan="2"|[[Pets]]') | |||
local petList = { | |||
["skill"] = {}, | |||
["boss"] = {}, | |||
["other"] = {} | |||
} | |||
local skillPetList = {} | local skillPetList = {} | ||
local bossPetList = {} | local bossPetList = {} | ||
local otherPetList = {} | local otherPetList = {} | ||
for i, petData in | for i, petData in ipairs(GameData.rawData.pets) do | ||
local source = p._getPetSource(petData) | |||
local listCat = 'other' | |||
if type(source) == 'table' and source.type ~= nil then | |||
table.insert( | if source.type == 'skill' then | ||
listCat = 'skill' | |||
table.insert( | elseif source.type == 'dungeon' or source.type == 'slayerArea' then | ||
listCat = 'boss' | |||
else | |||
listCat = 'other' | |||
end | |||
end | |||
table.insert(petList[listCat], petData.name) | |||
end | |||
local getIconList = | |||
function(pets) | |||
local result = {} | |||
for i, pet in ipairs(pets) do | |||
table.insert(result, Icons.Icon({pet, type='pet'})) | |||
end | end | ||
return table.concat(result, ' • ') | |||
end | |||
for cat, catData in pairs(petList) do | |||
table.sort(catData, function(a, b) return a < b end) | |||
table.insert(resultPart, '\r\n|-\r\n!' .. Shared.titleCase(cat) .. ' Pets\r\n|' .. getIconList(catData)) | |||
end | end | ||
table. | table.insert(resultPart, '\r\n|}') | ||
return table.concat(resultPart) | |||
end | end | ||
return p | return p |
Revision as of 15:51, 22 October 2022
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 Shared = require( "Module:Shared" )
local Constants = require('Module:Constants')
local GameData = require('Module:GameData')
local Icons = require('Module:Icons')
local Areas = require('Module:CombatAreas')
-- Compute combat pet sources once for use later
local function getCombatPetSources()
local result = {}
local areas = Areas.getAreas(function(area) return area.pet ~= nil end)
for i, area in ipairs(areas) do
result[area.petID] = { id = area.id, name = area.name, type = area.type, weight = area.weight }
end
end
local CombatPetSources = getCombatPetSources()
function p.getPetByID(ID)
return GameData.getEntityByID('pets', ID)
end
function p.getPet(name)
name = string.gsub(name, "%%27", "'")
name = string.gsub(name, "'", "'")
name = string.gsub(name, "'", "'")
return GameData.getEntityByName('pets', name)
end
function p.getPets(checkFunc)
return GameData.getEntities('pets', checkFunc)
end
function p._getPetSource(pet)
local skillID = p._getPetSkill(pet)
if skillID ~= nil then
local skillName = Constants.getSkillName(skillID)
return { id = skillID, name = skillName, type = 'skill' }
elseif CombatPetSources ~= nil then
return CombatPetSources[pet.id]
end
end
function p._getPetSourceText(pet)
local sourceOverrides = {
-- useIcon: true if Source has an associated icon, false otherwise
['Ripper the Reindeer'] = { text = '[[Events#Christmas Event 2020|Christmas Event 2020]]', useIcon = false },
['Festive Chio'] = { text = '[[Holiday Event 2021]]', useIcon = false },
['Festive Cool Rock'] = { text = '[[Holiday Event 2021]]', useIcon = false },
['Jerry the Giraffe'] = { text = '[[Golbin Raid|Golbin Raid Shop]]', useIcon = false },
['Preston the Platypus'] = { text = '[[Golbin Raid|Golbin Raid Shop]]', useIcon = false }
}
local petSourceText = nil
local iconType = nil
local useIcon = true
local override = sourceOverrides[pet.name]
if override ~= nil then
petSourceText = override.text
if override.useIcon ~= nil then
useIcon = override.useIcon
end
end
if petSourceText == nil then
local petSource = p._getPetSource(pet)
if petSource ~= nil then
iconType = petSource.type
petSourceText = petSource.name
else
useIcon = false
petSourceText = ''
end
end
if useIcon then
return Icons.Icon({petSourceText, type=iconType})
else
return petSourceText
end
end
function p._getPetEffect(pet)
local modKeys = {'modifiers', 'enemyModifiers'}
local effects = {}
for i, key in ipairs(modKeys) do
if pet[key] ~= nil and not Shared.tableIsEmpty(pet[key]) then
for effectName, effectValue in pairs(pet[key]) do
local preText = (key == 'enemyModifiers' and 'All enemies have: ' or '')
table.insert(effects, preText .. Constants._getModifierText(effectName, effectValue, false))
end
end
end
if Shared.tableIsEmpty(effects) then
return 'None'
else
return table.concat(effects, '<br/>')
end
end
function p._getPetChance(pet)
local source = p._getPetSource(pet)
if source ~= nil and source.weight ~= nil then
-- Pet is from a dungeon or combat/slayer area
-- Flaky logic for determining if pet is guaranteed or not
if source.weight <= 10 then
return 'Guaranteed after ' .. Shared.formatnum(source.weight) .. ' clears'
else
return '1 in ' .. Shared.formatnum(source.weight) .. ' (' .. Shared.round(100 / source.weight, 2, 2) .. '%)'
end
else
-- Skill pet or other
return 'See: [[Pets#Acquiring Pets|Acquiring Pets]]'
end
end
function p._getPetSkill(pet)
local skillOverrides = {
['melvorD:Ty'] = nil,
['melvorF:Mark'] = 'melvorD:Summoning'
}
if skillOverrides[pet.id] ~= nil then
return skillOverrides[pet.id]
else
return pet.skillID
end
end
function p._getPetTable(pets)
if type(pets) ~= 'table' or Shared.tableIsEmpty(pets) then
return nil
end
local resultPart = {}
table.insert(resultPart, '{| class="wikitable"\r\n!Pet!!Name!!Effect')
for i, pet in ipairs(pets) do
table.insert(resultPart, '|-')
table.insert(resultPart, '|style="text-align: center;"|' .. Icons.Icon({pet.name, type='pet', size=60, notext=true}))
table.insert(resultPart, '|' .. Icons.Icon({pet.name, type='pet', noicon=true}))
table.insert(resultPart, '| ' .. p._getPetEffect(pet))
end
table.insert(resultPart, '|}')
return table.concat(resultPart, '\r\n')
end
function p.getPetTableBySkill(frame)
local skillName = frame.args ~= nil and frame.args[1] or frame
local skillID = Constants.getSkillID(skillName)
if skillID == nil then
return ''
else
local pets = p.getPets(function(pet) return p._getPetSkill(pet) == skillID end)
if pets == nil or Shared.tableIsEmpty(pets) then
return ''
else
return p._getPetTable(pets)
end
end
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)
if pet == nil then
return 'ERROR: Could not find pet with name ' .. (name or 'Unknown') .. '[[Category:Pages with script errros]]'
end
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 = p._getPetChance(pet)
result = '{| class="wikitable infobox" style="float:right; clear:right;"\r\n|-\r\n'
result = result..'! '..name..'\r\n|-\r\n| '
result = result..'style="text-align: center;"|' .. 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._getPetSourceText(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 = ''
result = '{|class="wikitable sortable lighttable stickyHeader"'
result = result..'\r\n|- class="headerRow-0"\r\n! Name !! Image !! Acquired From !! Effect'
for i, thisPet in ipairs(GameData.rawData.pets) do
result = result..'\r\n|-\r\n|'..Icons.Icon({thisPet.name, type='pet', noicon=true})
result = result..'||style="text-align: center;"|'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true})
result = result..'||'..p._getPetSourceText(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 = Areas.getArea(dungeonName)
if dung == nil then
return 'ERROR: Invalid dungeon name '..dungeonName..'[[Category:Pages with script errors]]'
end
if dung.pet ~= nil then
local pet = p.getPetByID(dung.pet.petID)
if pet ~= nil then
local result = "\r\n|-\r\n|'''[[Pets#Boss Pets|Pet]]:'''<br/>"
result = result..Icons.Icon({pet.name, type='pet'})
result = result.."\r\n|-\r\n|'''Pet Drop Chance:'''<br/>"..p._getPetChance(pet)
return result
end
end
end
-- TODO Move to Module:Navboxes
function p.getPetNavbox()
local resultPart = {}
table.insert(resultPart, '{| class="wikitable" style="margin:auto; text-align:center; clear:both; width: 100%"')
table.insert(resultPart, '\r\n|-\r\n!colspan="2"|[[Pets]]')
local petList = {
["skill"] = {},
["boss"] = {},
["other"] = {}
}
local skillPetList = {}
local bossPetList = {}
local otherPetList = {}
for i, petData in ipairs(GameData.rawData.pets) do
local source = p._getPetSource(petData)
local listCat = 'other'
if type(source) == 'table' and source.type ~= nil then
if source.type == 'skill' then
listCat = 'skill'
elseif source.type == 'dungeon' or source.type == 'slayerArea' then
listCat = 'boss'
else
listCat = 'other'
end
end
table.insert(petList[listCat], petData.name)
end
local getIconList =
function(pets)
local result = {}
for i, pet in ipairs(pets) do
table.insert(result, Icons.Icon({pet, type='pet'}))
end
return table.concat(result, ' • ')
end
for cat, catData in pairs(petList) do
table.sort(catData, function(a, b) return a < b end)
table.insert(resultPart, '\r\n|-\r\n!' .. Shared.titleCase(cat) .. ' Pets\r\n|' .. getIconList(catData))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
return p