Module:Prayer: Difference between revisions

From Melvor Idle
(Substitute links with Icons.Icon() where possible to benefit from ambiguous link handling)
(Removed functions in favour of manual tables)
 
(26 intermediate revisions by 4 users not shown)
Line 1: Line 1:
local p = {}
local p = {}
local SkillData = mw.loadData('Module:Skills/data')


local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Modifiers = require('Module:Modifiers')
local Skills = require('Module:Skills')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Constants = require('Module:Constants')
local Items = require('Module:Items')
local Items = require('Module:Items')
local ItemSources = require('Module:Items/SourceTables')
local ItemSources = require('Module:Items/SourceTables')
local Num = require('Module:Number')


function p.getPrayerByID(id)
function p.getPrayerByID(id)
  local result = Shared.clone(SkillData.Prayer[id + 1])
return GameData.getEntityByID('prayers', id)
  if result ~= nil and result.id == nil then result.id = id end
  return result
end
end


function p.getPrayer(name)
function p.getPrayer(name)
  local result = nil
return GameData.getEntityByName('prayers', name)
  for i, prayer in pairs(SkillData.Prayer) do
end
    local prayName = prayer.name
 
    if prayName == name then
function p.getPrayers(checkFunc)
      result = Shared.clone(prayer)
return GameData.getEntities('prayers', checkFunc)
      result.id = i - 1
      break
    end
  end
  return result
end
end


function p.getPrayerCost(prayer)
--Returns the expansion icon for the prayer if it has one
  local costLines = {}
function p.getExpansionIcon(frame)
  if prayer.pointsPerPlayer > 0 then
local prayerName = frame.args ~= nil and frame.args[1] or frame
    local pluralString = prayer.pointsPerPlayer > 1 and 's' or ''
local prayer = p.getPrayer(prayerName)
    table.insert(costLines, prayer.pointsPerPlayer..' Prayer Point'..pluralString..' per player attack')
if prayer == nil then
  end
return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
  if prayer.pointsPerEnemy > 0 then
end
    local pluralString = prayer.pointsPerEnemy > 1 and 's' or ''
    table.insert(costLines, prayer.pointsPerEnemy..' Prayer Point'..pluralString..' per enemy attack')
return Icons.getExpansionIcon(prayer.id)
  end
  if prayer.pointsPerRegen > 0 then
    local pluralString = prayer.pointsPerRegen > 1 and 's' or ''
    table.insert(costLines, prayer.pointsPerRegen..' Prayer Point'..pluralString..' when health regenerates')
  end
  return table.concat(costLines, '<br/>')
end
end


function p.formatEffectLine(var, val)
function p.getPrayerCost(prayer)
  if var == 'prayerBonusDefence' then
local costLines = {}
    return '+'..val..'% [[Combat#Melee Evasion Rating|Melee Evasion Rating]]'
if prayer.pointsPerPlayer > 0 then
  elseif var == 'prayerBonusStrength' then
local pluralString = prayer.pointsPerPlayer > 1 and 's' or ''
    return '+'..val..'% [[Combat#Melee Max Hit|Melee Strength]]'
table.insert(costLines, prayer.pointsPerPlayer..' Prayer Point'..pluralString..' per player attack')
  elseif var == 'prayerBonusAttack' then
end
    return '+'..val..'% [[Combat#Melee Accuracy Rating|Melee Accuracy Rating]]'
if prayer.pointsPerEnemy > 0 then
  elseif var == 'prayerBonusDefenceRanged' then
local pluralString = prayer.pointsPerEnemy > 1 and 's' or ''
    return '+'..val..'% [[Combat#Ranged Evasion Rating|Ranged Evasion Rating]]'
table.insert(costLines, prayer.pointsPerEnemy..' Prayer Point'..pluralString..' per enemy attack')
  elseif var == 'prayerBonusAttackRanged' then
end
    return '+'..val..'% [[Combat#Ranged Accuracy Rating|Ranged Accuracy Rating]]'
if prayer.pointsPerRegen > 0 then
  elseif var == 'prayerBonusStrengthRanged' then
local pluralString = prayer.pointsPerRegen > 1 and 's' or ''
    return '+'..val..'% [[Combat#Ranged Max Hit|Ranged Strength]]'
table.insert(costLines, prayer.pointsPerRegen..' Prayer Point'..pluralString..' when health regenerates')
  elseif var == 'prayerBonusDefenceMagic' then
end
    return '+'..val..'% [[Combat#Magic Evasion Rating|Ranged Evasion Rating]]'
return table.concat(costLines, '<br/>')
  elseif var == 'prayerBonusAttackMagic' then
    return '+'..val..'% [[Combat#Magic Accuracy Rating|Magic Accuracy Rating]]'
  elseif var == 'prayerBonusDamageMagic' then
    return '+'..val..'% [[Combat#Magic Max Hit|Magic Damage]]'
  elseif var == 'prayerBonusHitpoints' then
    return val..'x Restore Rate for [[Hitpoints]]'
  elseif var == 'prayerBonusProtectItem' then
    return 'Prevents losing an item upon [[Death]]'
  elseif var == 'prayerBonusProtectFromMelee' then
    return '85% chance to dodge Melee attacks'
  elseif var == 'prayerBonusProtectFromRanged' then
    return '85% chance to dodge Ranged attacks'
  elseif var == 'prayerBonusProtectFromMagic' then
    return '85% chance to dodge Magic attacks'
  elseif var == 'prayerBonusHitpointHeal' then
    return 'Heal +'..val..'% HP when HP falls below 10%'
  elseif var == 'prayerBonusDamageReduction' then
    return '+'..val..'% [[Damage Reduction]]'
  else
    return '+'..val..' of unknown bonus '..var..'[[Category:Unknown Prayer Bonus]]'
  end
end
end


function p._getPrayerEffect(prayer, asList)
function p._getPrayerEffect(prayer, asList)
  if asList == nil then asList = false end
if asList == nil then asList = false end
  local chr = asList and '* ' or ''
 
  local bonusLines = {}
local lineSep = (asList and '\n' or '<br>')
local chr = (asList and '* ' or '')
local bonusLines = {}
if prayer.isUnholy then
table.insert(bonusLines, "For each Unholy Mark stack on the enemy:")
end
if type(prayer.modifiers) == 'table' then
local formatLine = function(text) return chr .. text end


  for bonusKey, bonusVal in Shared.skpairs(prayer.modifiers) do
table.insert(bonusLines, Modifiers.getModifiersText(prayer.modifiers, false, false, 10, formatLine, lineSep))
    table.insert(bonusLines, chr..Constants._getModifierText(bonusKey, bonusVal, false))
end
  end


  --If there are no actual effects, just use the prayer's description 
if type(prayer.enemyModifiers) == 'table' then
  if Shared.tableCount(prayer.modifiers) == 0 then
local formatLine = function(text) return chr .. 'Gives the enemy: ' .. text end
    table.insert(bonusLines, chr..prayer.description)
  end
table.insert(bonusLines, Modifiers.getModifiersText(prayer.enemyModifiers, false, false, 10, formatLine, lineSep))
end


  if prayer.pointsPerPlayer > 0 then
if prayer.pointsPerPlayer > 0 then
    local val = 0.1 * prayer.pointsPerPlayer
-- Prayer XP ratio is 1/3 in game but is divided by 10 here as HP/damage values
    table.insert(bonusLines, chr.."+"..Shared.round(val, 1, 1).." Prayer XP per damage done")
-- displayed to the player are multiplied by 10 in the standard game mode
  end
local xpRatio = 1 / 30
  if asList then
local val = xpRatio * prayer.pointsPerPlayer
    return table.concat(bonusLines, '\r\n')
table.insert(bonusLines, chr .. "+" .. Num.round(val, 3, 3) .. " Prayer XP per damage done")
  else
end
    return table.concat(bonusLines, '<br/>')
return table.concat(bonusLines, lineSep)
  end
end
end


function p.getPrayerEffect(frame)
function p.getPrayerEffect(frame)
  local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
  local asListTxt = frame.args ~= nil and frame.args[2] or frame[2]
local asListTxt = frame.args ~= nil and frame.args[2] or frame[2]
  local asList = asListTxt ~= nil and asListTxt ~= 'false' and asListTxt ~= 'no'
local asList = asListTxt ~= nil and asListTxt ~= 'false' and asListTxt ~= 'no'
  local prayer = p.getPrayer(prayerName)
local prayer = p.getPrayer(prayerName)
  if prayer == nil then
if prayer == nil then
    return "ERROR: Could not find a prayer named "..prayerName
return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
  end
end


  return p._getPrayerEffect(prayer, asList)
return p._getPrayerEffect(prayer, asList)
end
end


function p._getPrayerStat(prayer, statName)
function p._getPrayerStat(prayer, statName)
  if statName == "prayerCost" then
if statName == "prayerCost" then
    return p.getPrayerCost(prayer)
return p.getPrayerCost(prayer)
  elseif statName == "prayerEffect" then
elseif statName == "prayerEffect" then
    return p._getPrayerEffect(prayer)
return p._getPrayerEffect(prayer)
  elseif statName == "prayerEffectList" then
elseif statName == "prayerEffectList" then
    return p.getPrayerEffect(prayer, true)
return p.getPrayerEffect(prayer)
  elseif statName == 'prayerLevel' then
elseif statName == 'prayerLevel' then
    return Icons._SkillReq('Prayer', prayer['prayerLevel'])
return Skills.getRecipeRequirementText('Prayer', prayer)
  else
else
    return prayer[statName]
return prayer[statName]
  end
end
end
end


function p.getPrayerStat(frame)
function p.getPrayerStat(frame)
  local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
  local statName = frame.args ~= nil and frame.args[2] or frame[2]
local statName = frame.args ~= nil and frame.args[2] or frame[2]
  local prayer = p.getPrayer(prayerName)
local prayer = p.getPrayer(prayerName)
  if prayer == nil then
if prayer == nil then
    return "ERROR: Could not find a prayer named "..prayerName
return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
  end
end


  return p._getPrayerStat(prayer, statName)
return p._getPrayerStat(prayer, statName)
end
end


function p._getPrayerCategories(prayer)
function p._getPrayerCategories(prayer)
  return '[[Category:Prayers]]'
return '[[Category:Prayers]]'
end
end


function p.getPrayerCategories(frame)
function p.getPrayerCategories(frame)
  local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
  local prayer = p.getPrayer(prayerName)
local prayer = p.getPrayer(prayerName)
  if prayer == nil then
if prayer == nil then
    return "ERROR: Could not find a prayer named "..prayerName
return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
  end
end


  return p._getPrayerCategories(prayer)
return p._getPrayerCategories(prayer)
end
end


-- Returns only the regular prayers.
function p.getPrayerTable(frame)
function p.getPrayerTable(frame)
  local result = '{| class="wikitable sortable stickyHeader"'
local func = function(prayer)
  result = result..'\r\n|-class=headerRow-0'
return not prayer.isUnholy and not prayer.isAbyssal
  result = result..'\r\n!colspan="2"|Prayer!!'..Icons.Icon({"Prayer", type="skill", notext=true})..' Lvl'
end
  result = result..'!!Effects!!Point Cost'
return p.getPrayerTableFiltered(frame, func)
end


  for i, prayer in Shared.skpairs(SkillData.Prayer) do
function p.getUnholyPrayerTable(frame)
    result = result..'\r\n|-'
return p.getPrayerTableFiltered(frame, function(prayer) return prayer.isUnholy end)
    result = result..'\r\n|'..Icons.Icon({prayer.name, type='prayer', notext=true, size='50'})
end
    result = result..'||'..Icons.Icon({prayer.name, type='prayer', noicon=true})..'||'..prayer.prayerLevel
    result = result..'||'..p._getPrayerEffect(prayer)
    result = result..'||'..p.getPrayerCost(prayer)
  end


  result = result..'\r\n|}'
function p.getAbyssalPrayerTable(frame)
  return result
return p.getPrayerTableFiltered(frame, function(prayer) return prayer.isAbyssal end, 'Abyssal Realm')
end
end


function p.getBonesTable(frame)
-- Realm is defined "manually" here to define custom styling
  local result = '{| class="wikitable sortable stickyHeader"'
function p.getPrayerTableFiltered(frame, prayerPredicate, realm)
  result = result..'\r\n|- class="headerRow-0"'
local skillID = 'Prayer'
  result = result..'\r\n!colspan="2"|Bone!!Prayer Points!!Sources'
local realm = realm or 'Melvor Realm'
 
  local itemArray = Items.getItems(function(item) return item.prayerPoints ~= nil and item.prayerPoints > 0 end)
local html = mw.html.create('table')
:addClass('wikitable sortable stickyHeader')


  table.sort(itemArray, function(a, b) return a.prayerPoints < b.prayerPoints end)
html:tag('tr'):addClass('headerRow-0')
:tag('th'):attr('colspan', 2)
  :wikitext('Prayer')
:tag('th'):wikitext('DLC')
:tag('th'):wikitext(Icons.Icon({'Prayer', type='skill', notext=true}) .. '<br>Level')
:tag('th'):wikitext('Effects')
:tag('th'):wikitext('Point Cost')


  for i, item in Shared.skpairs(itemArray) do
local prayerList = p.getPrayers(prayerPredicate)
    result = result..'\r\n|-'
table.sort(prayerList, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end)
    result = result..'\r\n|'..Icons.Icon({item.name, type='item', notext=true, size='50'})
    result = result..'||'..Icons.Icon({item.name, type='item', noicon=true})
    result = result..'||style="text-align:right;"|'..item.prayerPoints
    result = result..'||'..ItemSources._getItemSources(item, false, false)
  end


  result = result..'\r\n|}'
for i, prayer in ipairs(prayerList) do
local level = Skills.getRecipeLevel(skillID, prayer)
local reqText = Skills.getRecipeRequirementText(skillID, prayer)
html:tag('tr')
:tag('td'):wikitext(Icons.Icon({prayer.name, type='prayer', notext=true}))
:tag('td'):wikitext('[[' .. prayer.name .. ']]')
:tag('td'):wikitext(Icons.getDLCColumnIcon(prayer.id))
  :css('text-align', 'center')
  :attr('data-sort-value', Icons.getExpansionID(prayer.id))
:tag('td'):wikitext(level)
  :css('text-align', 'center')
:tag('td'):wikitext(p._getPrayerEffect(prayer))
:tag('td'):wikitext(p.getPrayerCost(prayer))
end


  return result
return tostring(html)
end
end


return p
return p

Latest revision as of 13:02, 8 July 2024

Documentation for this module may be created at Module:Prayer/doc

local p = {}

local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Modifiers = require('Module:Modifiers')
local Skills = require('Module:Skills')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local ItemSources = require('Module:Items/SourceTables')
local Num = require('Module:Number')

function p.getPrayerByID(id)
	return GameData.getEntityByID('prayers', id)
end

function p.getPrayer(name)
	return GameData.getEntityByName('prayers', name)
end

function p.getPrayers(checkFunc)
	return GameData.getEntities('prayers', checkFunc)
end

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

function p.getPrayerCost(prayer)
	local costLines = {}
	if prayer.pointsPerPlayer > 0 then
		local pluralString = prayer.pointsPerPlayer > 1 and 's' or ''
		table.insert(costLines, prayer.pointsPerPlayer..' Prayer Point'..pluralString..' per player attack')
	end
	if prayer.pointsPerEnemy > 0 then
		local pluralString = prayer.pointsPerEnemy > 1 and 's' or ''
		table.insert(costLines, prayer.pointsPerEnemy..' Prayer Point'..pluralString..' per enemy attack')
	end
	if prayer.pointsPerRegen > 0 then
		local pluralString = prayer.pointsPerRegen > 1 and 's' or ''
		table.insert(costLines, prayer.pointsPerRegen..' Prayer Point'..pluralString..' when health regenerates')
	end
	return table.concat(costLines, '<br/>')
end

function p._getPrayerEffect(prayer, asList)
	if asList == nil then asList = false end

	local lineSep = (asList and '\n' or '<br>')
	local chr = (asList and '* ' or '')
	local bonusLines = {}
	
	if prayer.isUnholy then
		table.insert(bonusLines, "For each Unholy Mark stack on the enemy:")
	end
	
	if type(prayer.modifiers) == 'table' then
		local formatLine = function(text) return chr .. text	end

		table.insert(bonusLines, Modifiers.getModifiersText(prayer.modifiers, false, false, 10, formatLine, lineSep))
	end

	if type(prayer.enemyModifiers) == 'table' then
		local formatLine = function(text) return chr .. 'Gives the enemy: ' .. text	end
		
		table.insert(bonusLines, Modifiers.getModifiersText(prayer.enemyModifiers, false, false, 10, formatLine, lineSep))
	end

	if prayer.pointsPerPlayer > 0 then
		-- Prayer XP ratio is 1/3 in game but is divided by 10 here as HP/damage values
		-- displayed to the player are multiplied by 10 in the standard game mode
		local xpRatio = 1 / 30
		local val = xpRatio * prayer.pointsPerPlayer
		table.insert(bonusLines, chr .. "+" .. Num.round(val, 3, 3) .. " Prayer XP per damage done")
	end
	return table.concat(bonusLines, lineSep)
end

function p.getPrayerEffect(frame)
	local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
	local asListTxt = frame.args ~= nil and frame.args[2] or frame[2]
	local asList = asListTxt ~= nil and asListTxt ~= 'false' and asListTxt ~= 'no'
	local prayer = p.getPrayer(prayerName)
	if prayer == nil then
		return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
	end

	return p._getPrayerEffect(prayer, asList)
end

function p._getPrayerStat(prayer, statName)
	if statName == "prayerCost" then
		return p.getPrayerCost(prayer)
	elseif statName == "prayerEffect" then
		return p._getPrayerEffect(prayer)
	elseif statName == "prayerEffectList" then
		return p.getPrayerEffect(prayer)
	elseif statName == 'prayerLevel' then
		return Skills.getRecipeRequirementText('Prayer', prayer)
	else
		return prayer[statName]
	end
end

function p.getPrayerStat(frame)
	local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
	local statName = frame.args ~= nil and frame.args[2] or frame[2]
	local prayer = p.getPrayer(prayerName)
	if prayer == nil then
		return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
	end

	return p._getPrayerStat(prayer, statName)
end

function p._getPrayerCategories(prayer)
	return '[[Category:Prayers]]'
end

function p.getPrayerCategories(frame)
	local prayerName = frame.args ~= nil and frame.args[1] or frame[1]
	local prayer = p.getPrayer(prayerName)
	if prayer == nil then
		return Shared.printError('No prayer named "' .. prayerName .. '" exists in the data module')
	end

	return p._getPrayerCategories(prayer)
end

-- Returns only the regular prayers.
function p.getPrayerTable(frame)
	local func = function(prayer)
		return not prayer.isUnholy and not prayer.isAbyssal
	end
	
	return p.getPrayerTableFiltered(frame, func)
end

function p.getUnholyPrayerTable(frame)
	return p.getPrayerTableFiltered(frame, function(prayer) return prayer.isUnholy end)
end

function p.getAbyssalPrayerTable(frame)
	return p.getPrayerTableFiltered(frame, function(prayer) return prayer.isAbyssal end, 'Abyssal Realm')
end

-- Realm is defined "manually" here to define custom styling
function p.getPrayerTableFiltered(frame, prayerPredicate, realm)
	local skillID = 'Prayer'
	local realm = realm or 'Melvor Realm'
	
	local html = mw.html.create('table')
		:addClass('wikitable sortable stickyHeader')

	html:tag('tr'):addClass('headerRow-0')
			:tag('th'):attr('colspan', 2)
					  :wikitext('Prayer')
			:tag('th'):wikitext('DLC')
			:tag('th'):wikitext(Icons.Icon({'Prayer', type='skill', notext=true}) .. '<br>Level')
			:tag('th'):wikitext('Effects')
			:tag('th'):wikitext('Point Cost')

	local prayerList = p.getPrayers(prayerPredicate)
	table.sort(prayerList, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end)

	for i, prayer in ipairs(prayerList) do
		local level = Skills.getRecipeLevel(skillID, prayer)
		local reqText = Skills.getRecipeRequirementText(skillID, prayer)
		
		html:tag('tr')
				:tag('td'):wikitext(Icons.Icon({prayer.name, type='prayer', notext=true}))
				:tag('td'):wikitext('[[' .. prayer.name .. ']]')
				:tag('td'):wikitext(Icons.getDLCColumnIcon(prayer.id))
						  :css('text-align', 'center')
						  :attr('data-sort-value', Icons.getExpansionID(prayer.id))
				:tag('td'):wikitext(level)
						  :css('text-align', 'center')
				:tag('td'):wikitext(p._getPrayerEffect(prayer))
				:tag('td'):wikitext(p.getPrayerCost(prayer))
	end

	return tostring(html)
end

return p