Module:Icons

From Melvor Idle
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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

local Shared = require("Module:Shared")
local GameData = require("Module:GameData")

-- Locally index some functions for performance
local sgsub, fixPagename, formatnum, tostring, type = string.gsub, Shared.fixPagename, Shared.formatnum, tostring, type

local p = {}
--Extension overrides for items that have non-png images
--Name level overrides take precedence over type level overrides
local extOverrides = {
	["type"] = {
		["skill"] = "svg",
		["spellType"] = "svg",
		["spell"] = "svg",
		["curse"] = "svg", -- Some exceptions included by name below
		["aurora"] = "svg",
		["combatArea"] = "svg",
		["dungeon"] = "svg",
		["prayer"] = "svg",
		["upgrade"] = "svg", -- Some exceptions included by name below
		["tree"] = "svg",
		["rock"] = "svg", -- Some exceptions included by name below
		["thieving"] = "svg",
		["constellation"] = "svg",
		["building"] = "svg",
		["resource"] = "svg",
		["township"] = "svg"
	},
	["name"] = {
		-- General
		["Combat"] = "svg",
		["Guides"] = "svg",
		["Mastery"] = "svg",
		["Coins"] = "svg",
		["Slayer Coins"] = "svg",
		["Raid Coins"] = "svg",
		["Shop"] = "svg",
		["Easter"] = "svg",
		["Melvor Logo"] = "svg",
		["Question"] = "svg",
		["Timer"] = "svg",
		["Hardcore"] = "svg",
		["Chaos"] = "svg",
		["Internal Suffering Speedrun"] = "svg",
		["Hardcore Adventure Speedrun"] = "svg",
		["Mastery Tokens"] = "gif",
		["Prat, the Serpent of Fire"] = "svg",
		-- Items
		["Amulet of Fishing"] = "svg",
		["Lemon"] = "jpg",
		["Lemons"] = "jpg",
		["Lemonade"] = "jpg",
		["Ancient Crossbow"] = "svg",
		["Air Shard"] = "svg",
		["Water Shard"] = "svg",
		["Earth Shard"] = "svg",
		["Fire Shard"] = "svg",
		["Confetti Crossbow"] = "svg",
		["Cloudburst Staff"] = "gif",
		["Shockwave"] = "svg",
		["Event Clue 1"] = "svg",
		["Event Clue 2"] = "svg",
		["Event Clue 3"] = "svg",
		["Event Clue 4"] = "svg",
		-- Pets
		["Cris"] = "svg",
		["Cool Rock"] = "svg",
		["Puff, the Baby Dragon"] = "svg",
		["Bruce"] = "svg",
		["Lil Ron"] = "svg",
		["Leonardo"] = "svg",
		["Golden Golbin"] = "svg",
		["Ty"] = "svg",
		["Ripper the Reindeer"] = "svg",
		["Chick"] = "svg",
		["Zarrah"] = "svg",
		["Chio"] = "svg",
		["Bouncing Bob"] = "svg",
		["Rosey"] = "svg",
		["Ayyden"] = "svg",
		["Arctic Yeti"] = "svg",
		["Mac"] = "svg",
		["Jerry the Giraffe"] = "svg",
		["Preston the Platypus"] = "svg",
		["Quill"] = "svg",
		["Gunter"] = "svg",
		["Salem"] = "svg",
		["Peri"] = "svg",
		["Otto"] = "svg",
		["Jelly Jim"] = "svg",
		["Harley"] = "svg",
		["Singe"] = "svg",
		["Aquarias"] = "svg",
		["Norman"] = "svg",
		["Erran"] = "svg",
		["Ren"] = "svg",
		["Pablo"] = "svg",
		["Sam"] = "svg",
		["Tim the Wolf"] = "svg",
		["Mark"] = "svg",
		["Astro"] = "svg",
		-- Curses, included to override the type level override above
		["Madness"] = "png",
		["Torment"] = "png",
		["Despair"] = "png",
		-- Alt. Magic
		["Rags to Riches III"] = "png",
		-- Upgrades, included to override the type level override above
		["Golbin Crate"] = "png",
		["Corundum Axe"] = "png",
		["Augite Axe"] = "png",
		["Meteorite Axe"] = "png",
		["Divine Axe"] = "png",
		["Spruce Cooking Fire"] = "png",
		["Elderwood Cooking Fire"] = "png",
		["Carrion Cooking Fire"] = "png",
		["Iridium Pot"] = "png",
		["Palladium Pot"] = "png",
		["Divine Pot"] = "png",
		["Corundum Furnace"] = "png",
		["Augite Furnace"] = "png",
		["Divine Furnace"] = "png",
		["Sign of the Stars"] = "png",
		["Summoner's Altar"] = "png",
		["Golden Shard"] = "png",
		["Labyrinth Solution"] = "png",
		["Linden Boat"] = "png",
		["Golden Compass"] = "png",
		-- Rocks (Mining), included to override the type level override above
		["Rune Essence"] = "png",
		["Pure Essence"] = "png",
		["Onyx"] = "png",
		["Oricha"] = "png",
		["Cerulean"] = "png",
		-- Marks (Summoning), included to override the type level override above
		["Eagle"] = "png",
		["Owl"] = "png",
		["Beaver"] = "png",
		["Fox"] = "png",
		["Lightning Spirit"] = "png",
		["Siren"] = "png",
		["Spider"] = "png",
		["Spectre"] = "png"
	}
}

--Some overrides only apply for a specific type
local typeExtOverrides = {
	-- Example: ["item"] = { ["Chicken"] = "png" }
	["item"] = {
		-- These familiars also exist as type mark, where the image is of PNG format
		["Golbin Thief"] = "svg",
		["Occultist"] = "svg",
		["Wolf"] = "svg",
		["Ent"] = "svg",
		["Mole"] = "svg",
		["Octopus"] = "svg",
		["Minotaur"] = "svg",
		["Centaur"] = "svg",
		["Witch"] = "svg",
		["Pig"] = "svg",
		["Crow"] = "svg",
		["Leprechaun"] = "svg",
		["Cyclops"] = "svg",
		["Yak"] = "svg",
		["Unicorn"] = "svg",
		["Dragon"] = "svg",
		["Monkey"] = "svg",
		["Salamander"] = "svg",
		["Bear"] = "svg",
		["Devil"] = "svg"
	}
}

--When calling for an icon of type Key, instead use type Value
local typeOverrides = {
	['combat'] = 'combatArea',
	['slayer'] = 'combatArea',
}
--When calling for an icon for Key, replace with image Value, and optionally override type also
local imgOverrides = {
	['Alt Magic'] = 'Magic',
	['Alt. Magic'] = 'Magic',
	['Alternative Magic'] = 'Magic',
	['Melee'] = {'Attack', 'skill'},
	['Spider (lv. 51)'] = 'Spider',
	['Spider (lv. 52)'] = 'Brown Spider',
	['Bane, Instrument of Fear'] = 'Bane',
	['Mastery Token Astrology'] = 'Mastery Token (Astrology)',
	['Event Token - Holiday 2021'] = 'Christmas Present (Yellow)',
	["I Can't See Helmet"] = {'Golbin', 'monster'},
	-- Shop purchases
	['Basic Resupply'] = {'Lobster', 'item'},
	['Standard Resupply'] = {'Crab', 'item'},
	['Generous Resupply'] = {'Shark', 'item'},
	['Plentiful Resupply'] = {'Magma Fish', 'item'},
	['Bountiful Resupply'] = {'Static Jellyfish', 'item'},
	['Cooking Upgrade 1'] = {'Cooking', 'skill'},
	['Cooking Upgrade 2'] = {'Cooking', 'skill'},
	['Loot Container Stacking'] = {'Amulet of Looting', 'item'},
	['Access to Throne of the Herald'] = {'Golden Key', 'item'},
	["Max Skillcape"] = 'Maximum Skillcape',
	-- Alt.Magic spells using item icons
	['Item Alchemy'] = {'Item Alchemy III', 'spell'},
	['Superheat'] = {'Superheat IV', 'spell'},
	["Holy Invocation I"] = {'Small Urn', 'item'},
	["Holy Invocation II"] = {'Medium Urn', 'item'},
	["Nullification"] = {'Rune Essence', 'item'},
	["Transmutation"] = {'Oricha', 'item'},
	["Purification"] = {'Pure Essence', 'item'},
	["Fragmentation"] = {'Summoning Shard (Black)', 'item'},
	["Holy Invocation III"] = {'Large Urn', 'item'},
	["Embellish"] = {'Lava Fish (Perfect)', 'item'},
	-- Overrides that allow generic potion pages to be linked to easily
	['Melee Accuracy Potion'] = {'Melee Accuracy Potion I', 'item'},
	['Melee Evasion Potion'] = {'Melee Evasion Potion I', 'item'},
	['Ranged Assistance Potion'] = {'Ranged Assistance Potion I', 'item'},
	['Hinder Potion'] = {'Hinder Potion I', 'item'},
	['Magic Assistance Potion'] = {'Magic Assistance Potion I', 'item'},
	['Regeneration Potion'] = {'Regeneration Potion I', 'item'},
	['Famished Potion'] = {'Famished Potion I', 'item'},
	['Ranged Strength Potion'] = {'Ranged Strength Potion I', 'item'},
	['Lucky Herb Potion'] = {'Lucky Herb Potion I', 'item'},
	['Divine Potion'] = {'Divine Potion I', 'item'},
	['Melee Strength Potion'] = {'Melee Strength Potion I', 'item'},
	['Magic Damage Potion'] = {'Magic Damage Potion I', 'item'},
	['Lethal Toxins Potion'] = {'Lethal Toxins Potion I', 'item'},
	['Diamond Luck Potion'] = {'Diamond Luck Potion I', 'item'},
	['Damage Reduction Potion'] = {'Damage Reduction Potion I', 'item'},
	['Area Control Potion'] = {'Area Control Potion I', 'item'},
	['Adaptive Defence Potion'] = {'Adaptive Defence Potion I', 'item'},
	['Slayer Bounty Potion'] = {'Slayer Bounty Potion I', 'item'},
	['Holy Bulwark Potion'] = {'Holy Bulwark Potion I', 'item'},
	['Adaptive Accuracy'] = {'Adaptive Accuracy Potion I', 'item'},
	['Reaper Potion'] = {'Reaper Potion I', 'item'},
	['Penetration Potion'] = {'Penetration Potion I', 'item'},
	['Critical Strike Potion'] = {'Critical Strike Potion I', 'item'},
	['Bird Nest Potion'] = {'Bird Nest Potion I', 'item'},
	['Controlled Heat Potion'] = {'Controlled Heat Potion I', 'item'},
	['Generous Cook Potion'] = {'Generous Cook Potion I', 'item'},
	['Seeing Gold Potion'] = {'Seeing Gold Potion I', 'item'},
	['Fishermans Potion'] = {'Fishermans Potion I', 'item'},
	['Skilled Fletching Potion'] = {'Skilled Fletching Potion I', 'item'},
	['Gentle Hands Potion'] = {'Gentle Hands Potion I', 'item'},
	['Secret Stardust Potion'] = {'Secret Stardust Potion I', 'item'},
	['Crafting Potion'] = {'Crafting Potion I', 'item'},
	['Perfect Swing Potion'] = {'Perfect Swing Potion I', 'item'},
	['Necromancer Potion'] = {'Necromancer Potion I', 'item'},
	['Performance Enhancing Potion'] = {'Performance Enhancing Potion I', 'item'},
	['Elemental Potion'] = {'Elemental Potion I', 'item'},
	['Herblore Potion'] = {'Herblore Potion I', 'item'},
	['Generous Harvest Potion'] = {'Generous Harvest Potion I', 'item'},
	['Alchemic Practice Potion'] = {'Alchemic Practice Potion I', 'item'},
	['Gem Detector Potion'] = {'Gem Detector Potion I', 'item'},
	['Multicooker Potion'] = {'Multicooker Potion I', 'item'},
	['Star Seeker Potion'] = {'Star Seeker Potion I', 'item'},
	['Traps Potion'] = {'Traps Potion I', 'item'},
	['Enkindled Yields Potion'] = {'Enkindled Yields Potion I', 'item'},
	['Alt Magic Potion'] = {'Alt Magic Potion I', 'item'},
	-- Township resources
	['GP'] = {'Coins', ''},
	['Food'] = {'Raw Beef', 'item'},
	['Ore'] = {'Iron', 'rock'},
	['Bar'] = {'Iron Bar', 'item'},
	['Herbs'] = {'Garum Herb', 'item'},
	['Clothing'] = {'Leather Body', 'item'},
	-- Township generic statue building
	['Statue of Worship'] = 'Statue of Nothing',
	-- Easter egg stuff
	["Lemonade (Empty)"] = "Lemonade",
	["Lemonade (Very empty)"] = "Lemonade",
	["Lemonade (Still very empty)"] = "Lemonade",
	["Lemonade (Not as empty as before)"] = "Lemonade",
	["Lemonade (Not much)"] = "Lemonade",
	["Lemonade (Has a bit now)"] = "Lemonade",
	["Lemonade (A little bit more now)"] = "Lemonade",
	["Lemonade (Half full)"] = "Lemonade",
	["Lemonade (Just over half full)"] = "Lemonade",
	["Lemonade (Maybe this is half full?)"] = "Lemonade",
	["Lemonade (Nope this is half full now)"] = "Lemonade",
	["Lemonade (Wow this is slow)"] = "Lemonade",
	["Lemonade (Just fill it up already)"] = "Lemonade",
	["Lemonade (Still not full)"] = "Lemonade",
	["Lemonade (Again, still not full)"] = "Lemonade",
	["Lemonade (Less than before because you drank some)"] = "Lemonade",
	["Lemonade (Back to where we were before)"] = "Lemonade",
	["Lemonade (Almost full)"] = "Lemonade",
	["Lemonade (Still almost full)"] = "Lemonade",
	["Lemonade (How full is it supposed to be?)"] = "Lemonade",
	["Lemonade (Wait this might be half full now)"] = "Lemonade",
	["Lemonade (Haha just joking, hurry up)"] = "Lemonade",
	["Lemonade (Okay this looks pretty full now)"] = "Lemonade",
	["Lemonade (Now?)"] = "Lemonade",
	["Lemonade (What about now?)"] = "Lemonade",
	["Lemonade (YAY ITS FINALLY FULL!)"] = "Lemonade",
	["Lemonade (Oh... still not full)"] = "Lemonade",
	["Lemonade (Wait for it)"] = "Lemonade",
	["Lemonade (Wait for it!)"] = "Lemonade",
	["Lemonade (Full)"] = "Lemonade"
}
--When calling for an icon for Key + Type, replace with image Value, and optionally override type also
local typeImgOverrides = {
	['resource'] = {
		['Rune Essence'] = {'Rune Essence', 'item'},
		['Leather'] = {'Leather', 'item'},
	}
}
--When calling for an icon for Key, the link goes to Value
local linkOverrides = {
	['Alt Magic'] = 'Alternative Magic',
	['Alt. Magic'] = 'Alternative Magic',
	['Spider2'] = 'Brown Spider'
}
--When calling for an icon for Key + Type, the link goes to Value
local typeLinkOverrides = {
	['resource'] = {
		-- Township resources
		['Food'] = '',
		['Wood'] = '',
		['Planks'] = '',
		['Stone'] = '',
		['Bar'] = '',
		['Ore'] = '',
		['Coal'] = '',
		['Rune Essence'] = '',
		['Herbs'] = '',
		['Potions'] = '',
		['Leather'] = '',
		['Clothing'] = ''
	},
	['township'] = {
		['Workers'] = '',
		['Statistics'] = '',
		['Town'] = ''
	}
}

--If no other text override was specified for the given link, use these
local txtOverrides = {
	['Spider2'] = 'Brown Spider'
}
--Ambiguous overrides section
local ambiguousOverrides = {
	['Golbin'] = true,
	['Chick'] = true,
	['Chicken'] = true,
	['Cyclops'] = true,
	['Wizard'] = true,
	['Spider'] = true,
	['Necromancer'] = true,
	['Dark Knight'] = true,
	['Vampire'] = true,
	['Phantom'] = true,
	['Spectre'] = true,
	['Siren'] = true,
	['Lightning Spirit'] = true,
}
--When calling for an icon for Key, add a css class
local imgClassOverrides = {
	-- Township Stat Icons are licensed from Font Awesome Free 5.14.0 under CC BY 4.0 (https://github.com/FortAwesome/Font-Awesome/tree/5.14.0)
	['Population'] = 'township-colortoggle',
	['Workers'] = 'township-colortoggle',
	['Storage'] = 'township-colortoggle',
}

function p.Icon(frame)
	local args = frame.args ~= nil and frame.args or frame
	local link = args[1]
	local text = args[2]
	local iconType = args.type
	local ext = args.ext ~= nil and args.ext ~= '' and args.ext or 'png'
	local notext = args.notext ~= nil and args.notext ~= ''
	local nolink = args.nolink ~= nil and args.nolink ~= ''
	local noicon = args.noicon ~= nil and args.noicon ~= ''
	local menu = args.menu ~= nil and args.menu ~= ''
	local imgSize = args.size ~= nil and args.size or 25
	local qty = args.qty
	local img = args.img ~= nil and args.img ~= '' and args.img or link
	local class = args.class ~= nil and args.class ~= '' and args.class or ''
	local altText = args.alt ~= nil and args.alt or (notext and (text or link)) or ''
	local nospan = args.nospan ~= nil and args.nospan

	link = fixPagename(link)
	img = fixPagename(img)

	img = sgsub(img, '#', '')
	img = sgsub(img, '/Training', '')
	img = sgsub(img, '/Guide', '')
	link = sgsub(link, '#', '')

	--MANUAL OVERRIDES
	local ovrImg = imgOverrides[link]
	local ovrTypeImg = typeImgOverrides[iconType]
	if ovrTypeImg ~= nil then
		ovrImg = ovrTypeImg ~= nil and ovrTypeImg[img] or ovrImg
	end
	local ovrTxt = txtOverrides[link]
	local ovrLink = linkOverrides[link]
	local ovrTypeLink = typeLinkOverrides[iconType]
	if ovrTypeLink ~= nil and ovrTypeLink[img] ~= nil then
		if ovrTypeLink[img] == '' then
			nolink = true
		else
			ovrLink = ovrTypeLink[img]
		end
	end
	local hasText = (text ~= nil and text ~= '')
	if ovrImg ~= nil and img == link then
		if type(ovrImg) == 'string' then
			img = ovrImg
		elseif type(ovrImg) == 'table' then
			img = ovrImg[1]
			if ovrImg[2] ~= nil then iconType = ovrImg[2] end
		end
	end
	local ovrClass = imgClassOverrides[link]
	-- Type & extension overrides must be after adjustments have been made
	-- for any image overrides
	local ovrTypeExt = typeExtOverrides[iconType]
	if ovrTypeExt ~= nil then
		ovrTypeExt = ovrTypeExt[img]
	end
	local ovrType = typeOverrides[iconType]
	local ovrExt = extOverrides.name[img]
	if ovrExt == nil then
		ovrExt = extOverrides.type[ovrType or iconType]
	end
	if not hasText and ovrTxt ~= nil then
		text = ovrTxt
		hasText = true
	end
	if ovrLink ~= nil then
		if not hasText then
			text = link
			hasText = true
		end
		link = ovrLink
	end
	if ovrTypeExt ~= nil then
		ext = ovrTypeExt
	elseif ovrExt ~= nil then
		ext = ovrExt
	end
	if ovrType ~= nil then
		iconType = ovrType
	end
	if ovrClass ~= nil then
		class = ovrClass
	end
	-- There are a couple specific double overrides to be included that don't fit in the above lists
	if ambiguousOverrides[link] then
		if not hasText then
			text = link
			hasText = true
		end
		link = link..' ('..(iconType == 'mark' and 'item' or iconType)..')'
	end

	local resultText = ''
	if not noicon then
		-- Image size
		local txtSize = tostring(imgSize)
		-- Extension and type if one is set
		local txtImg = (iconType ~= nil and iconType ~= '' and img .. '_(' .. iconType .. ')' or img) .. '.' .. ext
		-- Include a link unless no link -and- no text was requested
		local txtLink = '|link=' .. (nolink and '' or link)
		resultText = '[[File:' .. txtImg .. '|' .. txtSize .. 'x' .. txtSize .. 'px|alt=' .. altText .. txtLink .. ']]'
		if class ~= nil and class ~= '' then
			resultText = '<span class="'..class..'">'..resultText..'</span>'
		end
	end

	if not notext then
		if nolink then
			resultText = resultText .. (noicon and '' or ' ') .. (hasText and text or link)
		else
			resultText = resultText .. (noicon and '' or ' ') .. '[[' .. link .. (hasText and text ~= link and '|' .. text or '') .. ']]'
		end
	end

	-- Add Quantity to the front if requested
	--local resultQty = (qty ~= nil and qty ~= '' and formatnum(qty) .. ' ' or '')
	if qty ~= nil and qty ~= '' then
		resultText = formatnum(qty) .. ' ' .. resultText
	end

	if menu then
		return '{| class="articletable" style="display:inline-block;vertical-align:middle;"\r\n|-\r\n|' .. resultText .. '\r\n|}'
	elseif not noicon and not nospan then
		return '<span style="display:inline-block">' .. resultText .. '</span>'
	else
		return resultText
	end
end

-- Wrapper for p.Icon(), uses the same parameters but forces noicon = true
function p.Link(frame)
	local args = frame.args ~= nil and frame.args or frame
	args.noicon = true
	return p.Icon({['args'] = args})
end

function p._SkillReq(skill, level, showText)
	local altText = (showText and '') or skill
	local result = p.Icon({skill, type='skill', notext=(showText and '' or true), nospan=true, alt=altText})
	if level == nil then level = 'Unknown [[Category:Pages with script errors]]' end
	result = result.." Level "..level

	result = '<span style="display:inline-block">'..result..'</span>'
	return result
end

function p.SkillReq(frame)
	local args = frame.args ~= nil and frame.args or frame
	local skill = args[1]
	local level = tonumber(args[2])
	local showText = args.showText ~= nil and args.showText ~= '' and args.showText ~= 'false'
	return p._SkillReq(skill, level, showText)
end

function p._MasteryReq(itemName, level, showText)
	local iconname = itemName
	local linkname = itemName
	--First, go with the lowest tier of potions if a potion is mentioned
	local s, e = string.find(itemName, 'Potion')
	if e ~= nil then
		linkname = string.sub(itemName, 1, e)
		iconname = linkname..' I'
	end
	local altTextItem = (showText and '') or linkname
	local altTextMastery = (showText and '') or '&nbsp;Mastery'

	local result = 'Level '..level..' '
	result = result..p.Icon({linkname, img=iconname, type='item', notext=true, nospan=true, alt=altTextItem})..p.Icon({'Mastery', notext=true, nospan=true, alt=altTextMastery})
	if showText then result = result..'[['..linkname..']] [[Mastery]]' end
	result = '<span style="display:inline-block">'..result..'</span>'
	return result
end

function p.MasteryReq(frame)
	local args = frame.args ~= nil and frame.args or frame
	local itemName = args[1]
	local level = tonumber(args[2])
	local showText = args.showText ~= nil and args.showText ~= '' and args.showText ~= 'false'
	return p._MasteryReq(itemName, level, showText)
end

function p._Currency(fileName, link, altText, amt, maxAmt)
	local amtText = formatnum(amt)
	if maxAmt ~= nil and maxAmt >= amt then
		amtText = amtText .. ' - ' .. formatnum(maxAmt)
	end

	local fileText = ''
	if fileName ~= nil then
		fileText = '[[File:' .. fileName .. '|25px'
		if link ~= nil then
			fileText = fileText .. '|link=' .. link
		end
		fileText = fileText .. '|alt=' .. ((altText == nil and '') or altText) .. ']]&nbsp;'
	end

	return '<span style="display:inline-block">' .. fileText .. amtText .. '</span>'
end

function p.GP(amt, maxamt)
	return p._Currency('Coins.svg', 'Coins', 'GP', amt, maxamt)
end

function p.SC(amt, maxamt)
	return p._Currency('Slayer Coins.svg', 'Currency#Slayer Coins', 'SC', amt, maxamt)
end

function p.RC(amt, maxamt)
	return p._Currency('Raid_Coins.svg', 'Currency#Raid Coins', 'RC', amt, maxamt)
end

--Adding a shortcut function for this
function p.TotH()
	return p.Icon({'Throne of the Herald Expansion', ext='svg', notext=true, img='TotH'})
end

function p.getExpansionIcon(id)
	local ns, _ = GameData.getLocalID(id)
	if ns == 'melvorTotH' then
		return p.TotH()..' '
	else
		return ''
	end
end

return p