core keeper

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

local trim = mw.text.trim
local data = mw.loadData("Module:LootTable/data")
local objectIdFromName = require("Module:ObjectIdFromName")

local currentFrame

local function getArg(key)
	local value = currentFrame.args[key]
	if not value then
		return nil
	end
	value = trim(value)
	if value == '' then
		return nil
	end
	return value
end

-- From https://minecraft.fandom.com/wiki/Module:LootChest
local function getAverageOccurrenceInRolls(minRolls, maxRolls, itemWeight, totalWeight)
	local inverseResult = 0 -- 1 - inverseResult = return value
	local inverseItemWeight = totalWeight - itemWeight

	-- will be used for the division in the for loop to avoid the slightly
	-- less performant math.pow(). The divisor already includes the probability
	-- of picking any specific number of rolls.
	local curDividend = inverseItemWeight
	local curDivisor = totalWeight * (maxRolls - minRolls + 1)

	for i = 1, maxRolls do
		if i >= minRolls then
			inverseResult = inverseResult + curDividend / curDivisor
		end
		curDividend = curDividend * inverseItemWeight -- simulate pow
		curDivisor = curDivisor * totalWeight -- simulate pow
	end

	return 1 - inverseResult
end

local p = {
	getAverageOccurrenceInRolls = getAverageOccurrenceInRolls
}

-- For other modules
function p.getAcquireTable(name)
	return data[name]
end

-- For {{Loot Table}} doc
function p.printIdList(frame)
	local list = mw.html.create("ul")
	
	for key, _ in pairs(data) do
		list:tag("li"):tag("code"):wikitext(key):done():done()	
	end
	
	return tostring(list)
end

-- For the {{Loot table}} template
function p.go(frame)
	currentFrame = frame
    -- local acquireTable = data[getArg(1)]
    local acquireTable = data[tonumber(getArg(1))] or data[objectIdFromName[getArg(1)]]

    if acquireTable then
        local output = mw.html.create("table"):addClass("wikitable sortable")

        -- Header
        local header = output:tag("tr")
        header:tag("th"):wikitext("Item")
        header:tag("th"):wikitext("Amount")
        header:tag("th"):tag("abbr"):attr("title", "Average chance of this item appearing in all rolls"):wikitext("Chance")

		local minRolls = acquireTable.uniqueDrops[1]
		local maxRolls = acquireTable.uniqueDrops[2]

        if minRolls > 1 or minRolls ~= maxRolls then
			local rollsRangeText = (minRolls == maxRolls and minRolls or minRolls .. "-" .. maxRolls) .. " rolls"
			output:tag("tr"):tag("th"):attr("colspan", "4"):wikitext(rollsRangeText)
        end

        local totalWeight = 0
        for _, item in ipairs(acquireTable.items) do
            totalWeight = totalWeight + item.weight
        end

        for _, item in ipairs(acquireTable.items) do
			local minAmount = item.amount[1]
			local maxAmount = item.amount[2]

            local row = output:tag("tr")

            row:tag("td"):wikitext(item.none and "None" or frame:expandTemplate{ title = "Item", args = { item.name } })
            row:tag("td"):attr("align", "center"):wikitext(minAmount == maxAmount and minAmount or minAmount .. "-" .. maxAmount)
			row:tag("td"):attr("align", "center"):wikitext(string.format("%.2f%%", getAverageOccurrenceInRolls(minRolls, maxRolls, item.weight, totalWeight) * 100))
        end

        return output
    end
end

return p