Module:Pets: Difference between revisions

From Melvor Idle
mNo edit summary
m (Add Superior Tier only note to stronghold pet drops)
 
(54 intermediate revisions by 4 users not shown)
Line 2: Line 2:


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


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 Modifiers = require('Module:Modifiers')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Skills = require('Module:Skills')
local Num = require('Module:Number')
local Zones = require('Module:CombatAreas')


local areaDataKeys = { 'combatAreas', 'slayerAreas', 'dungeons', 'strongholds', 'abyssDepths' }
-- Compute combat pet sources once for use later
local function getCombatPetSources()
local result = {}
for _, key in ipairs(areaDataKeys) do
local areas = GameData.getEntities(key,
function(area)
-- Lazy exclusion of event namespaces
local areaNS, areaLocalID = Shared.getLocalID(area.id)
if areaNS == 'melvorBirthday2023' or areaNS == 'melvorAprilFools2024' then
return false
end
return area.pet ~= nil
end
)
for i, area in ipairs(areas) do
result[area.pet.petID] = {
id = area.id,
name = area.name,
type = area.type,
isCombat = true,
weight = area.pet.weight,
fixedChance = (area.fixedPetClears ~= nil and area.fixedPetClears) or area.pet.weight == 1
}
end
end
return result
end
local CombatPetSources = getCombatPetSources()


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


function p.getPet(name)
function p.getPet(name)
  local result = nil
return GameData.getEntityByName('pets', Shared.fixPagename(name))
  name = string.gsub(name, "%%27", "'")
  name = string.gsub(name, "'", "'")
  name = string.gsub(name, "'", "'")
  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
end


function p.getPetBySkill(skillName)
function p.getPets(checkFunc)
  local result = nil
return GameData.getEntities('pets', checkFunc)
  local skillID = Skills.getSkillID(skillName)
  for i, pet in pairs(PetData.Pets) do
    if(skillID == pet.skill) 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
end


function p._getPetEffect(pet)
--Returns the expansion icon for the pet if it has one
  if pet.modifiers ~= nil then
function p.getExpansionIcon(frame)
    local effects = {}
local petName = frame.args ~= nil and frame.args[1] or frame
    for effectName, effectValue in pairs(pet.modifiers) do
local pet = p.getPet(petName)
      table.insert(effects, Constants.getModifierText(effectName, effectValue, false))
if pet == nil then
    end
return Shared.printError('No pet named "' .. petName .. '" exists in the data module')
    return table.concat(effects, '\r\n')
end
  else
    return pet.description
return Icons.getExpansionIcon(pet.id)
  end
end
end


function p.getPetTable(frame)
function p._getPetSource(pet)
  local petName = frame.args ~= nil and frame.args[1] or frame
if CombatPetSources ~= nil and CombatPetSources[pet.id] ~= nil then
  local pet = p.getPet(petName)
return CombatPetSources[pet.id]
  local result = '{| class="wikitable"\r\n'
else
  result = result..'!Pet!!Name!!Effect'
local skillID = p._getPetSkill(pet)
  result = result..'\r\n|-\r\n|'..Icons.Icon({pet.name, type='pet', size='60', notext=true})
if skillID ~= nil then
  result = result..'||[['..pet.name..']]||'..pet.description
local skillName = Constants.getSkillName(skillID)
  result = result..'\r\n|}'
return { id = skillID, name = skillName, type = 'skill', isCombat = false }
  return result
end
end
end
end


function p.getPetTableBySkill(frame)
function p._getPetSourceText(pet)
  local result = nil
local sourceOverrides = {
  local skillName = frame.args ~= nil and frame.args[1] or frame
-- 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 },
['Ty'] = { text = 'Mastery', useIcon = true },
['Golden Golbin'] = { text = Icons.Icon({'Golbin', type='monster'}) .. ' kills', useIcon = false},
['Saki'] = { text = 'Mastery', useIcon = true }
}
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
if petSource.isCombat then
iconType = (petSource.type == 'dungeon' and 'dungeon') or 'combatArea'
else
iconType = petSource.type
end
petSourceText = petSource.name
else
useIcon = false
petSourceText = ''
end
end


  return p.getPetTable(p.getPetBySkill(skillName).name)
if useIcon then
return Icons.Icon({petSourceText, type=iconType})
else
return petSourceText
end
end
end


function p.getPetSidebar(frame)
function p._getPetEffect(pet)
  local args = frame.args ~= nil and frame.args or frame
local modKeys = {'modifiers', 'enemyModifiers'}
  local result = nil
local effects = {}
  local name = (args.name ~= nil and args.name ~= '') and args.name or args[1]
for i, key in ipairs(modKeys) do
  local pet = p.getPet(name)
if pet[key] ~= nil and not Shared.tableIsEmpty(pet[key]) then
  local effect = (args.effect ~= nil and args.effect ~= '') and args.effect or p._getPetEffect(pet)
local preText = (key == 'enemyModifiers' and 'All enemies have: ' or '')
table.insert(effects, preText .. Modifiers.getModifiersText(pet[key], false))
end
end
if Shared.tableIsEmpty(effects) then
return 'None'
else
return table.concat(effects, '<br/>')
end
end


  local source = nil
function p._getPetChance(pet)
  if (args.skill ~= nil and args.skill ~= '') then
local source = p._getPetSource(pet)
    source = args.skill
if source ~= nil and source.weight ~= nil then
  elseif pet.skill ~= nil and pet.skill >= 0 then
-- Pet is from a dungeon or combat/slayer area
    source = Icons.Icon({Skills.getSkillName(pet.skill), type='skill'})
if source.fixedChance then
  else
return 'Guaranteed after ' .. Num.formatnum(source.weight) .. (source.weight == 1 and ' clear' or ' clears')
    local combatArea = Zones.getArea(pet.acquiredBy)
else
    if combatArea ~= nil then
return '1 in ' .. Num.formatnum(source.weight) .. ' (' .. Num.round(100 / source.weight, 2, 2) .. '%)'
      source = Icons.Icon({combatArea.name, type=combatArea.type})
end
    end
else
  end
-- Skill pet or other
return 'See: [[Pets#Acquiring Pets|Acquiring Pets]]'
end
end


  local dropChance = nil
function p._getPetSkill(pet)
  if pet.obtained ~= nil and pet.obtained.dungeonCompletion ~= nil then
local skillOverrides = {
    local odds = pet.obtained.dungeonCompletion[1][2]
['melvorD:Ty'] = nil,
    dropChance = '1 in '..odds..' ('..Shared.round(100 / odds, 2, 2)..'%)'
['melvorF:Mark'] = 'melvorD:Summoning'
  end
}


 
if skillOverrides[pet.id] ~= nil then
  result = '{| class="wikitable" style="float:right; clear:right;"\r\n|-\r\n'
return skillOverrides[pet.id]
  result = result..'! '..name..'\r\n|-\r\n| '
else
  result = result..Icons.Icon({name, type='pet', size='250', notext=true})
return pet.skillID
  result = result..'\r\n|-\r\n| Pet ID: '..pet.id
end
end


  result = result..'\r\n|-\r\n| Source: '..source
function p._getPetTable(pets)
  if dropChance ~= nil then
if type(pets) ~= 'table' or Shared.tableIsEmpty(pets) then
    result = result..'\r\n|-\r\n| Drop Chance: '..dropChance
return nil
  end
end


  result = result..'\r\n|-\r\n| style ="width: 250px;"|Effect: '..effect..'\r\n|}'
local html = mw.html.create('table')
:addClass('wikitable')
html:tag('tr')
:tag('th'):wikitext('Pet')
:tag('th'):wikitext('Name')
:tag('th'):wikitext('[[DLC]]')
:tag('th'):wikitext('Effect')


  return result
for i, pet in ipairs(pets) do
html:tag('tr')
:tag('td'):wikitext(Icons.Icon({pet.name, type='pet', notext=true}))
  :css('text-align', 'center')
:tag('td'):wikitext('[[' .. pet.name .. ']]')
:tag('td'):wikitext(Icons.getDLCColumnIcon(pet.id))
  :css('text-align', 'center')
:tag('td'):wikitext(p._getPetEffect(pet))
end
return tostring(html)
end
end


function p.getPetPageTable()
function p.getPetTableBySkill(frame)
  local result = ''
local skillName = frame.args ~= nil and frame.args[1] or frame
local skillID = Constants.getSkillID(skillName)


  local petList = {}
if skillID == nil then
  local acquiredOverrides = {
error("SkillID not found for skill: " .. skillName)
    ['Ripper the Reindeer'] = '[[Events#Christmas_Event_2020|Christmas Event 2020]]',
else
    ['Jerry the Giraffe'] = '[[Golbin Raid|Golbin Raid Shop]]',
local pets = p.getPets(function(pet) return p._getPetSkill(pet) == skillID end)
    ['Preston the Platypus'] = '[[Golbin Raid|Golbin Raid Shop]]',
if pets == nil or Shared.tableIsEmpty(pets) then
  }
return ''
  local effectOverrides = {
else
    ['Ripper the Reindeer'] = 'None',
return p._getPetTable(pets)
  }
end
  local acquired = nil
end
  local temp = nil
end
  for i, pet in pairs(PetData.Pets) do
    temp = Shared.clone(pet)


    if(effectOverrides[temp.name] ~= nil) then
function p.getPetSidebar(frame)
      temp.description = effectOverrides[temp.name]
local args = frame.args ~= nil and frame.args or frame
    end
local result = nil
    if(temp.name == 'Asura') then temp.acquiredBy = 'Slayer' end
local name = (args.name ~= nil and args.name ~= '') and args.name or args[1]
local pet = p.getPet(name)
if pet == nil then
return Shared.printError('No pet named "' .. (name or 'Unknown') .. '" exists in the data module')
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)


    acquired = ''
result = '{| class="wikitable infobox"\r\n|-\r\n'
    if(Skills.getSkillID(temp.acquiredBy) ~= nil) then
result = result..'! ' .. Icons.getExpansionIcon(pet.id) .. name .. '\r\n|-\r\n| '
      acquired = 'skill'
result = result..'style="text-align: center;"|' .. Icons.Icon({name, type='pet', size='250', notext=true})
    elseif Zones.getAreaFilterType('slayer', temp.acquiredBy) ~= nil then
result = result.."\r\n|-\r\n|'''Pet ID:''' "..pet.id
      acquired = 'slayer'
result = result.."\r\n|-\r\n|'''Source:''' "..p._getPetSourceText(pet)
    elseif Zones.getAreaFilterType('dungeon', temp.acquiredBy) ~= nil then
if dropChance ~= nil then
      acquired = 'dungeon'
result = result.."\r\n|-\r\n|'''Drop Chance:''' "..dropChance
    end
end
    temp.type = acquired
result = result.."\r\n|-\r\n| style =\"width: 250px;\"|'''Effect:''' "..effect
result = result .. "\r\n|-\r\n|'''Part of 100% Completion:''' " .. completionReq .. "\r\n|}"


    table.insert(petList, temp)
return result
  end
end


  result = result..'{|class="wikitable lighttable"'
function p.getPetPageTable()
  result = result..'\r\n|-\r\n! Name !! Image !! Acquired From !! Effect'
    local html = mw.html.create('table')
        :addClass('wikitable sortable lighttable stickyHeader')


  table.sort(petList, function(a, b)
    html:tag('tr'):addClass('headerRow-0')
                        return p.getPet(a.name).id < p.getPet(b.name).id
        :tag('th'):attr('colspan', '2')
                      end)
          :wikitext('Pet')
       
        :tag('th'):wikitext('[[DLC]]')
        :tag('th'):wikitext('Acquired From')
        :tag('th'):wikitext('Effect')


  for i, thisPet in pairs(petList) do
    for i, thisPet in ipairs(GameData.rawData.pets) do
    result = result..'\r\n|-\r\n|[['..thisPet.name..']]'
        html:tag('tr')
    result = result..'||'..Icons.Icon({thisPet.name, size='60', type='pet', notext=true})
            :tag('td'):addClass('table-img')
 
                  :attr('data-sort-value', thisPet.name)
    if acquiredOverrides[thisPet.name] ~= nil then
                      :wikitext(Icons.Icon({thisPet.name, type='pet', notext=true}))
      result = result..'||'..acquiredOverrides[thisPet.name]
                      :css('text-align', 'center')
    else
            :tag('td'):wikitext('[[' .. thisPet.name .. ']]')
      result = result..'||'..Icons.Icon({thisPet.acquiredBy, type=thisPet.type})
            :tag('td'):wikitext(Icons.getDLCColumnIcon(thisPet.id))
              :css('text-align', 'center')
              :attr('data-sort-value', Icons.getExpansionID(thisPet.id))
            :tag('td'):wikitext(p._getPetSourceText(thisPet))
            :tag('td'):wikitext(p._getPetEffect(thisPet))
     end
     end
    result = result..'||'..p._getPetEffect(thisPet)
  end
  result = result..'\r\n|}'


  return result
    return tostring(html)
end
end


function p.getPetNavbox(frame)
function p.getDungeonBoxPetText(frame)
  --•
local dungeonName = frame.args ~= nil and frame.args[1] or frame
  local result = '{| class="wikitable" style="margin:auto; text-align:center; clear:both; width: 100%"'
local dung = nil
  result = result..'\r\n|-\r\n!colspan="2"|[[Pets]]'
for i, key in ipairs(areaDataKeys) do
dung = GameData.getEntityByName(key, dungeonName)
if dung ~= nil then
break
end
end
if dung == nil then
return Shared.printError('No dungeon named "' .. dungeonName .. '" exists in the data module')
end


  local skillPetList = {}
if dung.pet ~= nil then
  local bossPetList = {}
local pet = p.getPetByID(dung.pet.petID)
  local otherPetList = {}
if pet ~= nil then
  for i, petData in Shared.skpairs(PetData.Pets) do
local result = "\r\n|-\r\n|'''[[Pets#Boss Pets|Pet]]:'''<br/>"
    if petData.skill ~= nil and petData.skill >= 0 and petData.name ~= "Ty" then
result = result..Icons.Icon({pet.name, type='pet'})
      table.insert(skillPetList, Icons.Icon({petData.name, type='pet'}))
result = result.."\r\n|-\r\n|'''Pet Drop Chance:'''<br/>"..p._getPetChance(pet)
    elseif petData.obtained ~= nil and petData.obtained.dungeonCompletion ~= nil then
if dung.type == 'stronghold' then
      table.insert(bossPetList, Icons.Icon({petData.name, type='pet'}))
result = result..' - Superior Tier only'
    else
end
      table.insert(otherPetList, Icons.Icon({petData.name, type='pet'}))
return result
    end
end
  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
end


return p
return p

Latest revision as of 22:43, 7 August 2024

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 Modifiers = require('Module:Modifiers')
local Icons = require('Module:Icons')
local Num = require('Module:Number')

local areaDataKeys = { 'combatAreas', 'slayerAreas', 'dungeons', 'strongholds', 'abyssDepths' }
-- Compute combat pet sources once for use later
local function getCombatPetSources()
	local result = {}
	for _, key in ipairs(areaDataKeys) do
		local areas = GameData.getEntities(key,
			function(area)
				-- Lazy exclusion of event namespaces
				local areaNS, areaLocalID = Shared.getLocalID(area.id)
				if areaNS == 'melvorBirthday2023' or areaNS == 'melvorAprilFools2024' then
					return false
				end
				return area.pet ~= nil
			end
		)
		for i, area in ipairs(areas) do
			result[area.pet.petID] = {
				id = area.id,
				name = area.name,
				type = area.type,
				isCombat = true,
				weight = area.pet.weight,
				fixedChance = (area.fixedPetClears ~= nil and area.fixedPetClears) or area.pet.weight == 1
			}
		end
	end
	return result
end
local CombatPetSources = getCombatPetSources()

function p.getPetByID(ID)
	return GameData.getEntityByID('pets', ID)
end

function p.getPet(name)
	return GameData.getEntityByName('pets', Shared.fixPagename(name))
end

function p.getPets(checkFunc)
	return GameData.getEntities('pets', checkFunc)
end

--Returns the expansion icon for the pet if it has one
function p.getExpansionIcon(frame)
	local petName = frame.args ~= nil and frame.args[1] or frame
	local pet = p.getPet(petName)
	if pet == nil then
		return Shared.printError('No pet named "' .. petName .. '" exists in the data module')
	end
	
	return Icons.getExpansionIcon(pet.id)
end

function p._getPetSource(pet)
	if CombatPetSources ~= nil and CombatPetSources[pet.id] ~= nil then
		return CombatPetSources[pet.id]
	else
		local skillID = p._getPetSkill(pet)
		if skillID ~= nil then
			local skillName = Constants.getSkillName(skillID)
			return { id = skillID, name = skillName, type = 'skill', isCombat = false }
		end
	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 },
		['Ty'] = { text = 'Mastery', useIcon = true },
		['Golden Golbin'] = { text = Icons.Icon({'Golbin', type='monster'}) .. ' kills', useIcon = false},
		['Saki'] = { text = 'Mastery', useIcon = true }
	}
	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
			if petSource.isCombat then
				iconType = (petSource.type == 'dungeon' and 'dungeon') or 'combatArea'
			else
				iconType = petSource.type
			end
			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
			local preText = (key == 'enemyModifiers' and 'All enemies have: ' or '')
			table.insert(effects, preText .. Modifiers.getModifiersText(pet[key], false))
		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
		if source.fixedChance then
			return 'Guaranteed after ' .. Num.formatnum(source.weight) .. (source.weight == 1 and ' clear' or ' clears')
		else
			return '1 in ' .. Num.formatnum(source.weight) .. ' (' .. Num.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 html = mw.html.create('table')
		:addClass('wikitable')
		
	html:tag('tr')
			:tag('th'):wikitext('Pet')
			:tag('th'):wikitext('Name')
			:tag('th'):wikitext('[[DLC]]')
			:tag('th'):wikitext('Effect')

	for i, pet in ipairs(pets) do
		html:tag('tr')
				:tag('td'):wikitext(Icons.Icon({pet.name, type='pet', notext=true}))
						  :css('text-align', 'center')
				:tag('td'):wikitext('[[' .. pet.name .. ']]')
				:tag('td'):wikitext(Icons.getDLCColumnIcon(pet.id))
						  :css('text-align', 'center')
				:tag('td'):wikitext(p._getPetEffect(pet))
	end
	
	return tostring(html)
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
		error("SkillID not found for skill: " .. skillName)
	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 Shared.printError('No pet named "' .. (name or 'Unknown') .. '" exists in the data module')
	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"\r\n|-\r\n'
	result = result..'! ' .. Icons.getExpansionIcon(pet.id) .. 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 html = mw.html.create('table')
        :addClass('wikitable sortable lighttable stickyHeader')

    html:tag('tr'):addClass('headerRow-0')
        	:tag('th'):attr('colspan', '2')
        			  :wikitext('Pet')
        	
        	:tag('th'):wikitext('[[DLC]]')
        	:tag('th'):wikitext('Acquired From')
        	:tag('th'):wikitext('Effect')

    for i, thisPet in ipairs(GameData.rawData.pets) do
        html:tag('tr')
            	:tag('td'):addClass('table-img')
                		  :attr('data-sort-value', thisPet.name)
                	      :wikitext(Icons.Icon({thisPet.name, type='pet', notext=true}))
                	      :css('text-align', 'center')
            	:tag('td'):wikitext('[[' .. thisPet.name .. ']]')
            	:tag('td'):wikitext(Icons.getDLCColumnIcon(thisPet.id))
            			  :css('text-align', 'center')
            			  :attr('data-sort-value', Icons.getExpansionID(thisPet.id))
            	:tag('td'):wikitext(p._getPetSourceText(thisPet))
            	:tag('td'):wikitext(p._getPetEffect(thisPet))
    end

    return tostring(html)
end

function p.getDungeonBoxPetText(frame)
	local dungeonName = frame.args ~= nil and frame.args[1] or frame
	local dung = nil
	for i, key in ipairs(areaDataKeys) do
		dung = GameData.getEntityByName(key, dungeonName)
		if dung ~= nil then
			break
		end
	end
	if dung == nil then
		return Shared.printError('No dungeon named "' .. dungeonName .. '" exists in the data module')
	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)
			if dung.type == 'stronghold' then
				result = result..' - Superior Tier only'
			end
			return result
		end
	end
end

return p