Module:Item/Variants

local table = require("Module:Table") local string = require("Module:String") local checkType = require('Module:LibraryUtil').checkType local MCColors = require("Module:Color/Data").MCColors

-- -- TABLE OF CONTENTS -- 01: More aliases support: Conversion tables -- 02: Main function for the aliases processing -- 03: Main table for lists of item variants -- 04: Individual procedures to generate lists of item variants -- -- Notes: -- 1. More aliases -- Add the *singular forms* of additional aliases to the singularFormConversions table -- 2. Plurals -- Use $s to set plural positions, for example: 'Crab Hat$s of Celebration' (default: the end of string) -- Add $u *at the end of the string* to disable plural, for example: 'Clay$u', 'Stairs$u' -- Add irregular plurals to the pluralOverrides table --

local p = {}

local function _getAliases -- 01: More aliases support: Conversion tables -- -- Other names to copy from the original name -- -- On the left side, $? formatting doesn't matter (e.g. 'Crab Hat$s of' Cel = 'Crab Hat of Cel') -- -- On the right side, $? formatting should be used to set plurals if needed. local singularFormConversions = { -- [' '] = ' '		-- [' '] = {' ', ...}		['Crab Hat of Celebration'] = 'Crab Hat', }	-- Irregular plurals (i.e. not 's', 'es', 'ies', 'ves') must be substituted here, -- -- including new aliases from singularFormConversions (if their plurals are irregular) -- -- Only the single word on plural positions (default is the end of string) needs to be added, -- -- unless you want to be specific so as to not affect other items -- local pluralOverrides = { -- irregular: [' '] = ' ' }	local aliases = {} local function gsubFn(...) -- Function for one or more gsub + trim -- function: gsubFn(<...>) | parameters must be in pairs of, , and in order local args = { ... }		if #args % 2 == 1 then error("gsubFn: Patterns and replacements not in pairs") end return function(n) for i = 1,#args,2 do				n = n:gsub(args[i], args[i+1]) end return string.trim(n) end end -- 02: Main function for the aliases processing -- -- function: createMultiAliases(name: str, items: table, customPrefixSingular: str/table, customPrefixPlural?: str/table) -- -- Additional prefixes for singular form (other than 'Any'/'Match') (if any) can be passed into 3rd param or items.CPS -- -- Additional prefixes for plural form (other than 'All') (if any) can be passed into 4th param or items.CPP -- local function createMultiAliases(name, items, customPrefixSingular, customPrefixPlural) local normalize = gsubFn('%$.', '') customPrefixSingular, customPrefixPlural = customPrefixSingular or items.customPrefixSingular or items.CPS, customPrefixPlural or items.customPrefixPlural or items.CPP local function search(name) for k,v in pairs(singularFormConversions) do				if normalize(k) == normalize(name) then return v				end end return {} end local allSingularAliases = table.map(table.merge({}, name, search(name)), function(sing)			return gsubFn('[]', '')(sing)		end) local allPluralAliases = table.map(allSingularAliases, function(sing)			-- get plural			if sing:match('%$u$') then return gsubFn('%$u$','')(sing) end			local a,b = sing:find('%$s')			for k,v in pairs(pluralOverrides) do				if (a and sing:match(k..'%$s') or sing:match(k..'$')) then					return (a and gsubFn(k..'%$s', v)(sing) or gsubFn(k..'$', v)(sing))				end			end			if a then				if a < 2 then error('Wrong plural placement of item '..sing) end				return gsubFn('(sh?)%$s','%1es','(x)%$s','%1es','(ch)%$s','%1es','y%$s','ies','fe?%$s','ves','%$s','s')(sing)			else				return gsubFn('(sh?)$','%1es','(x)$','%1es','(ch)$','%1es','y$','ies','([^s])$','%1s')(sing)			end		end) items, allSingularAliases, allPluralAliases = table.map(items, normalize), table.map(allSingularAliases, normalize), table.map(allPluralAliases, normalize) table.each(allSingularAliases, function(n) -- Don't use .eachNamed: we don't want named indexes			table.each(table.merge({'Any','Matching'}, customPrefixSingular or {}), function(p) aliases[p .. ' ' .. n] = items end)		end) table.each(allPluralAliases, function(n) -- Don't use .eachNamed: we don't want named indexes			table.each(table.merge({'All'}, customPrefixPlural or {}), function(p) aliases[p .. ' ' .. n] = items end)		end) end -- 03: Main table for lists of item variants -- -- Mainly for adding items with lesser iteration -- -- Use keys CPS (for singular) and CPP (for plural) to add additional custom prefixes -- local itemVariants = { -- ['Item group'] = { 'Item1', <'Item2'>, <...>, ,  } -- SACKS -- ['Agronomy Sack'] = { 'Small Agronomy Sack', 'Medium Agronomy Sack', 'Large Agronomy Sack' }, ['Combat Sack'] = { 'Small Combat Sack', 'Medium Combat Sack', 'Large Combat Sack' }, ['Husbandry Sack'] = { 'Small Husbandry Sack', 'Medium Husbandry Sack', 'Large Husbandry Sack' }, ['Foraging Sack'] = { 'Small Foraging Sack', 'Medium Foraging Sack', 'Large Foraging Sack' }, ['Fishing Sack'] = { 'Small Fishing Sack', 'Medium Fishing Sack', 'Large Fishing Sack' }, ['Mining Sack'] = { 'Small Mining Sack', 'Medium Mining Sack', 'Large Mining Sack' }, ['Slayer Sack'] = { 'Small Slayer Sack', 'Medium Slayer Sack', 'Large Slayer Sack' }, -- MISC -- ['Null Head'] = { 'Steve Head', 'Alex Head' }, ['Coin'] = { 'Iron Coin', 'Gold Coin', 'Diamond Coin',  'Diamond Coin 2',  'Emerald Coin',  'Lapis Coin',  'Redstone Coin',  'Emerald Coin 2' }, ['Travel Scroll'] = { 'Travel Scroll to Blazing Fortress', 'Travel Scroll to Deep Caverns',  'Travel Scroll to Dwarven Mines',  'Travel Scroll to the Gold Mine',  'Travel Scroll to Mushroom Island',  'Travel Scroll to Spider\'s Den',  'Travel Scroll to the Barn',  'Travel Scroll to the End',  'Travel Scroll to The Park',  'Travel Scroll to Hub Castle',  'Travel Scroll to Dark Auction',  'Travel Scroll to Hub Crypts',  'Travel Scroll to Spider\'s Den Top of Nest',  'Travel Scroll to Magma Fields',  'Travel Scroll to Dragon\'s Nest',  'Travel Scroll to Jungle Island',  'Travel Scroll to Howling Cave', }, ['Fishing Bait$u'] = { 'Minnow Bait', 'Fish Bait', 'Light Bait', 'Dark Bait', 'Spiked Bait', 'Spooky Bait', 'Carrot Bait', 'Blessed Bait', 'Whale Bait', 'Ice Bait', 'Shark Bait' }, ['Brew'] = { 'Cheap Coffee', 'Tepid Green Tea', 'Pulpous Orange Juice', 'Bitter Ice Tea', 'KnockOff Cola', 'Decent Coffee', 'Viking\'s Tear', 'Tutti-Frutti Flavored Poison', 'Dctr. Paper', 'Slayer Energy Drink' }, ['Dragon Fragment'] = { 'Protector Dragon Fragment', 'Old Dragon Fragment', 'Unstable Dragon Fragment', 'Holy Dragon Fragment', 'Wise Dragon Fragment', 'Young Dragon Fragment', 'Strong Dragon Fragment', 'Superior Dragon Fragment' }, ['Power Orb'] = { 'Radiant Power Orb', 'Mana Flux Power Orb', 'Overflux Power Orb', 'Plasmaflux Power Orb' }, ['Gift'] = { 'White Gift', 'Green Gift', 'Red Gift', }, ['Candy$u'] = { 'Green Candy', 'Purple Candy' }, ['Crab Hat$s of Celebration'] = { 'Red Crab Hat of Celebration', 'Orange Crab Hat of Celebration', 'Yellow Crab Hat of Celebration', 'Lime Crab Hat of Celebration', 'Green Crab Hat of Celebration', 'Aqua Crab Hat of Celebration', 'Purple Crab Hat of Celebration', 'Pink Crab Hat of Celebration', 'Black Crab Hat of Celebration' }, ['Century Cake'] = { 'Crab-Colored Century Cake', 'Pet Rock Century Cake', 'aPunch Century Cake', 'Potato-Style Century Cake', 'Barry Century Cake', 'Sea Emperor Century Cake', 'Century Cake of the Next Dungeon Floor', 'Latest Update Century Cake', 'Streamer\'s Century Cake' }, ['Repelling Candle'] = { 'Red Repelling Candle', 'Orange Repelling Candle', 'Yellow Repelling Candle', 'Green Repelling Candle', 'Blue Repelling Candle', 'Purple Repelling Candle', 'Black Repelling Candle', 'Pink Repelling Candle', 'Lilac Repelling Candle', 'Aqua Repelling Candle', 'Cyan Repelling Candle', 'Brown Repelling Candle', 'Gray Repelling Candle', 'White Repelling Candle',  }, ['Flower'] = { 'Oxeye Daisy', 'Red Tulip', 'Orange Tulip', 'White Tulip', 'Pink Tulip', 'Azure Bluet', 'Allium', 'Blue Orchid', 'Poppy', 'Dandelion' }, ['Horse Armor$u'] = { 'Iron Horse Armor', 'Gold Horse Armor', 'Diamond Horse Armor' }, ['Mushroom'] = { 'Red Mushroom', 'Brown Mushroom' }, ['Quartz Block'] = { 'Block of Quartz', 'Chiseled Quartz Block', 'Quartz Pillar' }, ['Red Sandstone'] = { 'Red Sandstone', 'Chiseled Red Sandstone', 'Smooth Red Sandstone' }, ['Sandstone'] = { 'Sandstone', 'Chiseled Sandstone', 'Smooth Sandstone' }, ['Stone Bricks$u'] = { 'Stone Bricks', 'Mossy Stone Bricks', 'Cracked Stone Bricks', 'Chiseled Stone Bricks' }, ['Stone Slab'] = { 'Sandstone Slab', 'Cobblestone Slab', 'Brick Slab', 'Stone Brick Slab', 'Nether Brick Slab', 'Quartz Slab' }, ['Stone'] = { 'Stone', 'Andesite', 'Granite', 'Diorite', 'Polished Andesite', 'Polished Granite', 'Polished Diorite' }, ['Tulip'] = { 'Red Tulip', 'Orange Tulip', 'White Tulip', 'Pink Tulip' }, }	for n,v in pairs(itemVariants) do		createMultiAliases(n, v)	end -- Below this line: 04: Individual procedures to generate lists of item variants -- -- Colored dye (in Color Alphabetical Order) -- coloredDyes = { 'Ink Sack', 'Lapis Lazuli', 'Cocoa Beans', 'Cyan Dye', 'Cactus Green', 'Gray Dye', 'Light Blue Dye', 'Light Gray Dye', 'Lime Dye', 'Magenta Dye', 'Orange Dye', 'Pink Dye', 'Purple Dye', 'Rose Red', --White is Here at Pos 15 'Dandelion Yellow', }	createMultiAliases('Colored Dye', coloredDyes) table.insert(coloredDyes, 15, 'Bone Meal') createMultiAliases('Dye', coloredDyes) -- Colored items -- local destain = gsubFn('^Dyed ',,'^Stained ',) -- General items that use the sixteen colors -- local coloredItems = { {'Carpet', 'Dyed Carpet'}, {'Wool', 'Dyed Wool'}, {'Glass', 'Stained Glass'}, {'Glass Pane', 'Stained Glass Pane'}, {'Clay$u', 'Stained Clay$u'}, }	for _,item in ipairs(coloredItems) do		local itemAny, listAny, itemColored, listColored local cps, cpp = item.CPS, item.CPP if type(coloredItems) == "table" then itemAny, listAny = item[1], {} itemColored, listColored = item[2], {} else itemAny, listAny = item, {} end table.eachNamed(MCColors, function(color)			table.push(listAny, itemAny:match('%$1') and gsubFn('%$1', color)(destain(itemAny)) or color..' '..destain(itemAny))			if color:lower ~= "white" and not not itemColored then				table.push(listColored, itemColored:match('%$1') and gsubFn('%$1', color)(destain(itemColored)) or color..' '..destain(itemColored))			end		end) createMultiAliases(gsubFn('%$1%s*', '')(itemAny), listAny, cps, cpp) if itemColored then createMultiAliases(gsubFn('%$1%s*', '')(itemColored), listColored, cps, cpp) end end -- Backpacks -- local backpackItems = { {'Jumbo Backpack$s ($1)', 'Dyed Jumbo Backpack$s ($1)'}, {'Greater Backpack$s ($1)', 'Dyed Greater Backpack$s ($1)'}, {'Large Backpack$s ($1)', 'Dyed Large Backpack$s ($1)'}, {'Medium Backpack$s ($1)', 'Dyed Medium Backpack$s ($1)'}, {'Small Backpack$s ($1)', 'Dyed Small Backpack$s ($1)'}, }	for _,item in ipairs(backpackItems) do		local itemAny, listAny, itemColored, listColored itemAny, listAny = item[1], {} itemColored, listColored = item[2], {} table.eachNamed(MCColors, function(color)			table.push(listAny, itemAny:match('%$1') and gsubFn('%$1',color)(destain(itemAny)) or color..' '..destain(itemAny))			table.push(listColored, itemColored:match('%$1') and gsubFn('%$1',color)(destain(itemColored)) or color..' '..destain(itemColored))		end) table.push(listAny, gsubFn(' %(%$1%)', '')(itemAny)) createMultiAliases(gsubFn('%$1%s*', '')(itemAny), listAny) if itemColored then createMultiAliases(gsubFn('%$1%s*', '')(itemColored), listColored) end end -- Item groups -- -- Dragon armors -- local dragonArmors = { 'Protector', 'Old', 'Unstable', 'Holy', 'Wise', 'Young', 'Strong', 'Superior' } for _, piece in ipairs{ 'Helmet', 'Chestplate', 'Leggings$u', 'Boots$u', 'Fragment' } do		local dragonRelatedAliases = table.map(table.deepCopy(dragonArmors), function(v) 			return v .. ' Dragon ' .. piece		end) createMultiAliases(piece, dragonRelatedAliases) end -- Wood -- local woods = { 'Oak', 'Spruce', 'Birch', 'Dark Oak', 'Acacia', 'Jungle' }	local woodItems = { 'Wood', 'Wood Plank', -- Skyblock specific 'Wood Slab', 'Wood Stairs$u', 'Fence', 'Fence Gate', 'Sapling', 'Leaves$u', }	for _, item in ipairs(woodItems) do		local itemName = '' local woodAliases = {} for _, wood in ipairs(woods) do			if item:find('wood') then itemName = item:gsub('wood', wood) elseif item:find('%$1') then itemName = item:gsub('%$1', wood) else itemName = wood .. ' ' .. item end table.insert(woodAliases, itemName) end item = item:gsub('%$1 ', '') createMultiAliases(item, woodAliases) end

-- Mushrooms createMultiAliases('Mushroom', { 'Red Mushroom', 'Brown Mushroom' }) createMultiAliases('Enchanted Mushroom', { 'Enchanted Red Mushroom', 'Enchanted Brown Mushroom' }) return aliases end

function p.getAliases return _getAliases end

p.getVariants = p.getAliases

return p