Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

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

local getArgs = require('Module:Arguments').getArgs
local getRarity = function(name)
	return require('Module:CosmeticInfo').getRarity({name=name})
end
local getType = function(name)
	return require('Module:CosmeticInfo').getType({name=name})
end

local machineData = mw.loadData('Module:CosmeticMachine/Data')

local function round(n)
	local frac = math.abs(n) % 1
	if frac == 0 then return n end
	local zeros = tostring(frac):match("%.(0*)") or ""
	local places = #zeros + 2
	local factor = 10 ^ places
	local sign = n < 0 and -1 or 1
	return math.floor(n * factor + 0.5) / factor
end

local p = {}

function p.getTotalUniqueCosmetics()
	local unique = {}
	for _, pullData in pairs(machineData) do
		for _, name in ipairs(pullData.cosmetics) do
			unique[name] = true
		end
	end
	local count = 0
	for _ in pairs(unique) do
		count = count + 1
	end
	return count
end

function p.getNoOfCosmeticsInPull(frame)
	local args = getArgs(frame)
	local cosmetics = machineData[args.pullType .. " Pull"].cosmetics
	
	local count = 0
	for _ in pairs(cosmetics) do
		count = count + 1
	end
	return count
end

function p.getPullChance(frame)
	local args = getArgs(frame)
	local cosmeticName = args.cosmeticName
	local pullType = args.pullType .. " Pull"
	
	local rarity = getRarity(cosmeticName)
	local cType = getType(cosmeticName) or "Standard"
	
	local pullData = machineData[pullType]
	if not pullData then return 0 end
	
	if not pullData.rarityChances[rarity] then return 0 end
	local baseRarityChance = (pullData.rarityChances[rarity]) / 100

	local function countEligible(filterFunc)
		local count = 0
		for _, name in ipairs(pullData.cosmetics) do
			if getRarity(name) == rarity and filterFunc(name) then
				count = count + 1
			end
		end
		return count
	end
	
	local chanceShare
	if cType == "Exclusive" then
		local exChance = pullData.exclusiveChance and (pullData.exclusiveChance[rarity] or pullData.exclusiveChance["All"] or 0)
		local exclusiveCount = countEligible(function(name)
			return getRarity(name) == rarity and getType(name) == cType
		end)
		if exclusiveCount == 0 then return 0 end
		
		chanceShare = (baseRarityChance * (exChance / 100)) / exclusiveCount
		
	elseif cType == "Arcane" and rarity == "Mythic" then
		local arcChance = pullData.arcaneChance and pullData.arcaneChance["Mythic"] or 0
		local arcaneCount = countEligible(function(name)
			return getRarity(name) == "Mythic" and getType(name) == "Arcane"
		end)
		if arcaneCount == 0 then return 0 end
		
		chanceShare = (baseRarityChance * (arcChance / 100)) / arcaneCount
		
	else
		local exclusiveCut = pullData.exclusiveChance and (pullData.exclusiveChance[rarity] or pullData.exclusiveChance["All"] or 0)
		local arcaneCut = (rarity == "Mythic" and pullData.arcaneChance and pullData.arcaneChance["Mythic"]) or 0
		local remainingChance = baseRarityChance * (1 - (exclusiveCut + arcaneCut) / 100)
		
		local standardCount = countEligible(function(name)
			return getRarity(name) == rarity and getType(name) == "Standard"
		end)
		if standardCount == 0 then return 0 end
		
		chanceShare = remainingChance / standardCount
		
	end
	return round(chanceShare * 100) .. "%"
end

function p.getCosmeticPulls(frame)
	local args = getArgs(frame)
	local cosmeticName = args.cosmeticName
	local results = {}
	
	for _, pullType in ipairs({"Basic", "Ultimate"}) do
		local chance = p.getPullChance({cosmeticName = cosmeticName, pullType = pullType})
		local color = machineData[pullType .. ' Pull'].color
		
		if chance and (chance ~= 0 and chance ~= "0%") then
			table.insert(results, {pullType = pullType, color = color, chance = chance})
		end
	end
	
	return results
end

function p.makeSentences(frame)
	local args = getArgs(frame)
	local name = args.name
	local mode = args.mode or "auto"
	local pulls = p.getCosmeticPulls{cosmeticName = name}
	if not pulls or #pulls == 0 then return "No pull data found for " .. name end
	
	local function makeSentence(result)
		local article
		if result.pullType:sub(1, 1):lower():match("[aeiou]") then
			article = "an"
		else
			article = "a"
		end
		return string.format(
			"'''%s''' chance when making %s <span style=\"color: %s\">[[File:%s Cosmetic Key.png|20px|link=%s Cosmetic Key]] %s Pull</span> at the [[File:Icon-Cosmetic-Machine.png|20px|link=Cosmetic Machine]] [[Cosmetic Machine]]",
			result.chance, article, result.color, result.pullType, result.pullType, result.pullType
		)
	end
	
	if mode == "inline" then
		local parts = {}
		for _, result in ipairs(pulls) do
			table.insert(parts, makeSentence(result))
		end
		return table.concat(parts, "; ")
		
	elseif mode == "list" then
		local out = {}
		for _, result in ipairs(pulls) do
			table.insert(out, "* " .. makeSentence(result))
		end
		return table.concat(out, "\n")
		
	else -- auto
		if #pulls == 1 then
			return makeSentence(pulls[1])
		else
			local out = {}
			for _, result in ipairs(pulls) do
				table.insert(out, "* " .. makeSentence(result))
			end
			return table.concat(out, "\n")
		end
	end
end

function p.displayPullCosmetics(frame)
	local args = getArgs(frame)
	local pullType = args.pullType
	local pullData = machineData[pullType .. " Pull"]
	if not pullData then return 'No data found for pull type: ' .. pullType end
	
	local out = {'<div class="tradeable-display">'}
	local count = 0
	
	for _, name in ipairs(pullData["cosmetics"]) do
		local chance = p.getPullChance({cosmeticName = name, pullType = pullType})
		local filename = name .. '.png'
		local cell = string.format(
			'<div><center><div class="afix" style="width: 100px">[[File:%s|link=%s]]</div></center><div style="word-wrap:break-word; text-align:center"><small>[[%s]]</small><br /><b>%s</b></div></div>',
			filename, name, name, chance)
		
		table.insert(out, cell)
		count = count + 1
	end
	
	table.insert(out, '</div>')
	return table.concat(out, '\n')
end

return p