Module:Common: Difference between revisions

From Melvor Idle
(New module, attempting to avoid module requirement loops when modules which require many modules also have functions which are desired by other modules)
 
(Cleanup migrated functions)
Tag: Manual revert
 
(13 intermediate revisions by 2 users not shown)
Line 29: Line 29:
return skillData.skillID
return skillData.skillID
end
end
end
end
-- getEquipmentSlotPage: Given a valid equipment slot ID, returns the page name for that slot's
-- equipment. If the slot is not recognized, then nil is returned
function p.getEquipmentSlotPage(equipSlot)
if type(equipSlot) == 'string' then
local slotLinkMap = {
["Helmet"] = 'Helmets',
["Platebody"] = 'Platebodies',
["Platelegs"] = 'Platelegs',
["Boots"] = 'Boots',
["Gloves"] = 'Gloves',
["Cape"] = 'Capes',
["Amulet"] = 'Amulets',
["Ring"] = 'Rings',
["Gem"] = 'Gems (Equipment)',
["Weapon"] = 'Weapons',
["Shield"] = 'Shields',
["Quiver"] = 'Ammunition',
["Consumable"] = 'Consumables',
["Passive"] = 'Combat Passive Slot',
["Summon1"] = 'Summoning',
["Summon2"] = 'Summoning'
}
return slotLinkMap[equipSlot]
end
end
-- getEquipmentSlotLink: As with getEquipmentSlotPage(), except returns wikitext to link to the
-- relevant page.
function p.getEquipmentSlotLink(equipSlot)
local pageName = p.getEquipmentSlotPage(equipSlot)
if pageName ~= nil then
return '[[' .. pageName .. '|' .. equipSlot .. ']]'
else
return equipSlot
end
end
end
end
Line 80: Line 117:
local purchaseName = p.getPurchaseName(purchase)
local purchaseName = p.getPurchaseName(purchase)
local purchType = p.getPurchaseType(purchase)
local purchType = p.getPurchaseType(purchase)
local iconType = nil
if purchType == 'Item Bundle' then
local upgBundles = {
'melvorAoD:Summoners_Pack_I',
'melvorAoD:Summoners_Pack_II',
'melvorAoD:Summoners_Pack_III',
'melvorAoD:Combat_Supply_I',
'melvorAoD:Combat_Supply_II',
'melvorAoD:Combat_Supply_III'
}
if Shared.contains(upgBundles, purchase.id) then
iconType = 'upgrade'
else
iconType = 'item'
end
else
iconType = string.lower(purchType)
end
-- Amend iconArgs before passing to Icons.Icon()
-- Amend iconArgs before passing to Icons.Icon()
iconArgs[1] = purchaseName
iconArgs[1] = purchaseName
iconArgs['type'] = (purchType == 'Item Bundle' and 'item') or string.lower(purchType)
iconArgs['type'] = iconType


return Icons.Icon(iconArgs)
return Icons.Icon(iconArgs)
end
-- getCostString: Given item & currency costs for something, returns human readable wikitext
-- for those costs. If there are no costs, returns the value specified by valueIfNone instead.
-- Costs are in the format:
-- { items = { ... }, gp = 0, sc = 0, rc = 0 }
function p.getCostString(costs, valueIfNone)
local costArray = {}
if type(costs.items) == 'table' and not Shared.tableIsEmpty(costs.items) then
for i, itemCost in ipairs(costs.items) do
local item = GameData.getEntityByID('items', itemCost.id)
if item ~= nil then
table.insert(costArray, Icons.Icon({item.name, type='item', qty=itemCost.quantity}))
end
end
end
if costs.gp ~= nil and costs.gp > 0 then
table.insert(costArray, Icons.GP(costs.gp))
end
if costs.sc ~= nil and costs.sc > 0 then
table.insert(costArray, Icons.SC(costs.sc))
end
if costs.rc ~= nil and costs.rc > 0 then
table.insert(costArray, Icons.RC(costs.rc))
end
if Shared.tableIsEmpty(costArray) then
return valueIfNone
else
return table.concat(costArray, '<br/>')
end
end
end


Line 141: Line 226:
end
end
elseif req.type == 'ItemFound' then
elseif req.type == 'ItemFound' then
local item = GameData.getObjectByID('items', req.itemID)
local item = GameData.getEntityByID('items', req.itemID)
if item ~= nil then
if item ~= nil then
table.insert(reqArray, 'Find ' .. Icons.Icon({item.name, type='item'}))
table.insert(reqArray, 'Find ' .. Icons.Icon({item.name, type='item'}))
end
elseif req.type == 'MonsterKilled' then
local monster = GameData.getEntityByID('monsters', req.monsterID)
if monster ~= nil then
table.insert(reqArray, Icons.Icon({monster.name, type='monster', qty=req.count, notext=true}) .. ' Kills')
end
end
elseif req.type == 'ShopPurchase' then
elseif req.type == 'ShopPurchase' then

Latest revision as of 20:05, 1 April 2024

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

-- This module contains common functions which interact with or interpret game data
-- in some form. Functions here may be applicable to various aspects of the game
-- (e.g. monsters, shop, dungeons, pets, items, and so on) and are contained here
-- to avoid loops when requiring modules.

-- Any functions which have no reliance upon, or relevance to game data are better suited
-- for [[Module:Shared]].

-- This module should _never_ require other modules which rely upon [[Module:GameData]]

local p = {}

local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Icons = require('Module:Icons')

-- getSkillName: Given a valid namespaced skill ID, returns that skill's name
function p.getSkillName(skillID)
	local skill = GameData.getSkillData(skillID)
	if skill ~= nil then
		return skill.name
	end
end

-- getSkillID: Given a valid skill name, returns that skill's namespaced ID
function p.getSkillID(skillName)
	for i, skillData in ipairs(GameData.rawData.skillData) do
		if skillData.data.name == skillName then
			return skillData.skillID
		end
	end
end

-- getEquipmentSlotPage: Given a valid equipment slot ID, returns the page name for that slot's
-- equipment. If the slot is not recognized, then nil is returned
function p.getEquipmentSlotPage(equipSlot)
	if type(equipSlot) == 'string' then
		local slotLinkMap = {
			["Helmet"] = 'Helmets',
			["Platebody"] = 'Platebodies',
			["Platelegs"] = 'Platelegs',
			["Boots"] = 'Boots',
			["Gloves"] = 'Gloves',
			["Cape"] = 'Capes',
			["Amulet"] = 'Amulets',
			["Ring"] = 'Rings',
			["Gem"] = 'Gems (Equipment)',
			["Weapon"] = 'Weapons',
			["Shield"] = 'Shields',
			["Quiver"] = 'Ammunition',
			["Consumable"] = 'Consumables',
			["Passive"] = 'Combat Passive Slot',
			["Summon1"] = 'Summoning',
			["Summon2"] = 'Summoning'
		}
		return slotLinkMap[equipSlot]
	end
end

-- getEquipmentSlotLink: As with getEquipmentSlotPage(), except returns wikitext to link to the
-- relevant page.
function p.getEquipmentSlotLink(equipSlot)
	local pageName = p.getEquipmentSlotPage(equipSlot)
	if pageName ~= nil then
		return '[[' .. pageName .. '|' .. equipSlot .. ']]'
	else
		return equipSlot
	end
end

-- getPurchaseName: Given a purchase from shop data, returns the name of that purchase
function p.getPurchaseName(purch)
	if purch.customName ~= nil then
		return purch.customName
	elseif purch.contains ~= nil then
		local item = nil
		if purch.contains.items ~= nil and not Shared.tableIsEmpty(purch.contains.items) then
			item = GameData.getEntityByID('items', purch.contains.items[1].id)
		elseif purch.contains.itemCharges ~= nil and not Shared.tableIsEmpty(purch.contains.itemCharges) then
			item = GameData.getEntityByID('items', purch.contains.itemCharges.id)
		end
		if item ~= nil then
			return item.name
		end
		if purch.contains.petID ~= nil then
			local pet = GameData.getEntityByID('pets', purch.contains.petID)
			if pet ~= nil then
				return pet.name
			end
		end
	end
	return ''
end

-- getPurchaseType: Given a purchase from shop data, returns the type of that purchase (based on
-- the purchase's contents)
function p.getPurchaseType(purchase)
	if purchase.contains == nil then
		return 'Unknown'
	elseif purchase.contains.petID ~= nil then
		return 'Pet'
	elseif purchase.contains.itemCharges ~= nil then
		return 'Item'
	elseif purchase.contains.modifiers ~= nil or purchase.contains.items == nil or Shared.tableCount(purchase.contains.items) == 0 then
		return 'Upgrade'
	elseif purchase.contains.items ~= nil and Shared.tableCount(purchase.contains.items) > 1 then
		return 'Item Bundle'
	else
		return 'Item'
	end
end

-- getPurchaseIcon: Accepts the same arguments as Icons.Icon(), except the first parameter is a
-- shop purchase rather than the icon/linked page name
function p.getPurchaseIcon(iconArgs)
	local purchase = iconArgs[1]
	local purchaseName = p.getPurchaseName(purchase)
	local purchType = p.getPurchaseType(purchase)
	local iconType = nil
	if purchType == 'Item Bundle' then
		local upgBundles = {
			'melvorAoD:Summoners_Pack_I',
			'melvorAoD:Summoners_Pack_II',
			'melvorAoD:Summoners_Pack_III',
			'melvorAoD:Combat_Supply_I',
			'melvorAoD:Combat_Supply_II',
			'melvorAoD:Combat_Supply_III'
		}
		if Shared.contains(upgBundles, purchase.id) then
			iconType = 'upgrade'
		else
			iconType = 'item'
		end
	else
		iconType = string.lower(purchType)
	end
	-- Amend iconArgs before passing to Icons.Icon()
	iconArgs[1] = purchaseName
	iconArgs['type'] = iconType

	return Icons.Icon(iconArgs)
end

-- getCostString: Given item & currency costs for something, returns human readable wikitext
-- for those costs. If there are no costs, returns the value specified by valueIfNone instead.
-- Costs are in the format:
-- { items = { ... }, gp = 0, sc = 0, rc = 0 }
function p.getCostString(costs, valueIfNone)
	local costArray = {}
	if type(costs.items) == 'table' and not Shared.tableIsEmpty(costs.items) then
		for i, itemCost in ipairs(costs.items) do
			local item = GameData.getEntityByID('items', itemCost.id)
			if item ~= nil then
				table.insert(costArray, Icons.Icon({item.name, type='item', qty=itemCost.quantity}))
			end
		end
	end
	if costs.gp ~= nil and costs.gp > 0 then
		table.insert(costArray, Icons.GP(costs.gp))
	end
	if costs.sc ~= nil and costs.sc > 0 then
		table.insert(costArray, Icons.SC(costs.sc))
	end
	if costs.rc ~= nil and costs.rc > 0 then
		table.insert(costArray, Icons.RC(costs.rc))
	end
	if Shared.tableIsEmpty(costArray) then
		return valueIfNone
	else
		return table.concat(costArray, '<br/>')
	end
end

-- getRequirementString: Given requirements from something such as a shop purchase or dungeon,
-- returns human readable wikitext for those requirements. If there are no requirements, returns
-- the value specified by valueIfNone instead
function p.getRequirementString(reqs, valueIfNone)
	if reqs == nil or Shared.tableIsEmpty(reqs) then
		return valueIfNone
	end

	local reqArray = {}
	for i, req in ipairs(reqs) do
		if req.type == 'AllSkillLevels' then
			local reqText = 'Level ' .. req.level .. ' in all skills'
			if req.exceptions ~= nil and not Shared.tableIsEmpty(req.exceptions) then
				local exceptSkills = {}
				for i, skillID in ipairs(req.exceptions) do
					local skillName = p.getSkillName(skillID)
					if skillName ~= nil then
						table.insert(exceptSkills, Icons.Icon({skillName, type='skill'}))
					end
				end
				reqText = reqText .. ' except for ' .. table.concat(exceptSkills, ', ')
			end
			table.insert(reqArray, reqText)
		elseif req.type == 'ArchaeologyItemsDonated' then
			table.insert(reqArray, 'Donate ' .. Shared.formatnum(req.count) .. ' Artefacts to the Museum in ' .. Icons.Icon({'Archaeology', type='skill'}))
		elseif req.type == 'CartographyPOIDiscovery' then
			local map = GameData.getEntityByID(GameData.skillData.Cartography.worldMaps, req.worldMapID)
			if map ~= nil then
				local poiPart = {}
				for j, poiID in ipairs(req.poiIDs) do
					local poi = GameData.getEntityByID(map.pointsOfInterest, poiID)
					if poi ~= nil then
						table.insert(poiPart, Icons.Icon({poi.name, type='poi'}))
					else
						table.insert(poiPart, Shared.printError('Could not find POI with ID ' .. poiID))
					end
				end
				table.insert(reqArray, 'Discover ' .. table.concat(poiPart, ', '))
			end
		elseif req.type == 'Completion' then
			local ns = GameData.getEntityByName('namespaces', req.namespace)
			if ns ~= nil then
				table.insert(reqArray, req.percent .. '% ' .. ns.displayName .. ' Completion')
			end
		elseif req.type == 'DungeonCompletion' then
			local dung = GameData.getEntityByID('dungeons', req.dungeonID)
			if dung ~= nil then
				local dungStr = 'Complete ' .. Icons.Icon({dung.name, type='dungeon'})
				if req.count > 1 then
					dungStr = dungStr .. ' ' .. Shared.formatnum(req.count) .. ' times'
				end
				table.insert(reqArray, dungStr)
			end
		elseif req.type == 'ItemFound' then
			local item = GameData.getEntityByID('items', req.itemID)
			if item ~= nil then
				table.insert(reqArray, 'Find ' .. Icons.Icon({item.name, type='item'}))
			end
		elseif req.type == 'MonsterKilled' then
			local monster = GameData.getEntityByID('monsters', req.monsterID)
			if monster ~= nil then
				table.insert(reqArray, Icons.Icon({monster.name, type='monster', qty=req.count, notext=true}) .. ' Kills')
			end
		elseif req.type == 'ShopPurchase' then
			local shopPurch = GameData.getEntityByID('shopPurchases', req.purchaseID)
			if shopPurch ~= nil then
				table.insert(reqArray, p.getPurchaseIcon({ shopPurch }) .. ' Purchased')
			end
		elseif req.type == 'SkillLevel' then
			local skillName = p.getSkillName(req.skillID)
			if skillName ~= nil then
				table.insert(reqArray, Icons._SkillReq(skillName, req.level))
			end
		elseif req.type == 'SlayerItem' then
			local item = GameData.getEntityByID('items', req.itemID)
			if item ~= nil then
				table.insert(reqArray, Icons.Icon({item.name, type='item'}) .. ' Equipped')
			end
		elseif req.type == 'SlayerTask' then
			table.insert(reqArray, 'Complete ' .. Shared.formatnum(req.count) .. ' ' .. req.tier .. ' Slayer Tasks')
		elseif req.type == 'TownshipBuilding' then
			local tsData = GameData.getSkillData('melvorD:Township')
			if tsData ~= nil and tsData.buildings ~= nil then
				local building = GameData.getEntityByID(tsData.buildings, req.buildingID)
				if building ~= nil then
					table.insert(reqArray, 'Have ' .. Shared.formatnum(req.count) .. ' ' .. building.name .. ' actively built in Township')
				end
			end
		elseif req.type == 'TownshipTask' then
			table.insert(reqArray, 'Complete ' .. Shared.formatnum(req.count) .. ' Township Tasks')
		else
			table.insert(reqArray, Shared.printError('Unknown requirement: ' .. (req.type or 'nil')))
		end
	end

	if Shared.tableIsEmpty(reqArray) then
		return valueIfNone
	else
		return table.concat(reqArray, '<br/>')
	end
end

return p