Module:Prayer

From Melvor Idle
Revision as of 06:38, 22 June 2024 by Slash (talk | contribs) (Add soul points table)

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')

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 .. "+" .. Shared.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

function p.getPrayerTable(frame)
	return p.getPrayerTableFiltered(frame, function(prayer) return true end)
end

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

function p.getPrayerTableFiltered(frame, prayerPredicate)
	local skillID = 'Prayer'
	local result = '{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|-class=headerRow-0'
	result = result..'\r\n!colspan="2"|Prayer!!Requirements'
	result = result..'!!Effects!!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)
		result = result..'\r\n|-'
		result = result..'\r\n|'..Icons.Icon({prayer.name, type='prayer', notext=true, size='50'})
		result = result..'||' .. Icons.getExpansionIcon(prayer.id) .. Icons.Icon({prayer.name, type='prayer', noicon=true})
		result = result..'||style="text-align:right;" data-sort-value="' .. level .. '"| ' .. reqText
		result = result..'||'..p._getPrayerEffect(prayer)
		result = result..'||'..p.getPrayerCost(prayer)
	end

	result = result..'\r\n|}'
	return result
end

function p.getBonesTable(frame)
	local result = '{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|- class="headerRow-0"'
	result = result..'\r\n!colspan="2"|Bone!!Prayer Points!!Sources'

	local itemArray = Items.getItems(function(item) return item.prayerPoints ~= nil and item.prayerPoints > 0 end)
	table.sort(itemArray, function(a, b) return a.prayerPoints < b.prayerPoints end)
	for i, item in ipairs(itemArray) do
		result = result..'\r\n|-'
		result = result..'\r\n|'..Icons.Icon({item.name, type='item', notext=true, size='50'})
		result = result..'||' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true})
		result = result..'||style="text-align:right;"|'..Shared.formatnum(item.prayerPoints)
		result = result..'||'..ItemSources._getItemSources(item, false, false)
	end

	result = result..'\r\n|}'

	return result
end

function p.getSoulsTable(frame)
	local result = '{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|- class="headerRow-0"'
	result = result..'\r\n!colspan="2"|Soul!!Soul Points!!Sources'

	local itemArray = Items.getItems(function(item) return item.soulPoints ~= nil and item.soulPoints > 0 end)
	table.sort(itemArray, function(a, b) return a.soulPoints < b.soulPoints end)
	for i, item in ipairs(itemArray) do
		result = result..'\r\n|-'
		result = result..'\r\n|'..Icons.Icon({item.name, type='item', notext=true, size='50'})
		result = result..'||' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true})
		result = result..'||style="text-align:right;"|'..Shared.formatnum(item.soulPoints)
		result = result..'||'..ItemSources._getItemSources(item, false, false)
	end

	result = result..'\r\n|}'

	return result
end

return p