Module:SCValue

From Melvor Idle
Revision as of 16:54, 6 May 2024 by Ricewind (talk | contribs)

This module can be used to get information regarding SC Slayer Coins related shop purchases. For instance, it calculates for much effective profit there can be gained or lost by buying specific items with SC and selling them for GP.


local p = {}

local Shared = require('Module:Shared')
local Shop = require('Module:Shop')
local Items = require('Module:Items')
local Common = require('Module:Common')
local Debug = require('Module:Debug')

local function getPurchase(itemName)
	local func = 
		function(purchase, name)
			return name == itemName
		end

	local purchList = Shop.getCategoryPurchases(func, 'Slayer')
	if purchList ~= nil and not Shared.tableIsEmpty(purchList) then
		return purchList[1]
	end
end

local function getPurchaseValue(purchase)
	if purchase == nil or purchase.cost == nil or purchase.contains == nil 
	then return 0 end
	
	local costs = purchase.cost
	local sales = purchase.contains
	
	local function getItemValues(items)
		local gpVal = 0
		if items ~= nil then
			for _, item in pairs(items) do
				gpVal = gpVal + Items.getItemValueByID(item['id']) * item['quantity']
			end
		end	
		return gpVal
	end
	
	-- Get total costs (including gp/item costs)
	local gpCost = 0
	if costs.gp ~= nil then	gpCost = costs.gp['cost'] or 0 end
	gpCost = gpCost + getItemValues(costs.items)

	-- Get gross profit from sale
	local gpProfit = getItemValues(sales.items)

	-- Calculate actual profit
	return gpProfit - gpCost
end

-- Returns all SC items that can be sold for GP, and can be bought in bulk.
local function getSellablePurchases()
	-- We need something to sell!
	-- We also want to buy/sell massive quantities for profit!
	local func = 
		function(purchase, name)
			local items = purchase.contains.items
			return purchase.allowQuantityPurchase and 
				items ~= nil and 
				not Shared.tableIsEmpty(items)
		end
		
	return Shop.getCategoryPurchases(func, 'Slayer')
end

local function getMostProfitablePurchases(amount)
	amount = tonumber(amount) or 1
	amount = math.max(amount, 1)
	
	local data = {}
	-- Gather value data about SC Shop Items
	for _, v in pairs(getSellablePurchases()) do
		local gpValue = getPurchaseValue(v)
		local scCost = (v.cost.slayerCoins or {}).cost or 0
		local gpPersc = (scCost ~= 0) and (gpValue / scCost) or (gpValue == 0 and 0 or 0)
		
		table.insert(data, {
			Purchase = v,
			SCCost = scCost,
			GPValue = gpValue,
			GPPerSC = gpPersc,
		})
	end
	
	-- Sort by most profitable to least profitable
	table.sort(data, function(a, b) return a.GPPerSC > b.GPPerSC end)

	-- Keep most profitable entries only
	local entries = {}
	for i = 1, math.min(#data, amount) do
		table.insert(entries, data[i])
	end
	
	return entries
end

function p.getSCItemProfits(frame)
end

function p._getSCItemProfits(amount)
	local purchases = getMostProfitablePurchases(amount)
	Debug.log(purchases)
end

function p.getSCValue(item)
	local purchase = getPurchase(item)
	if purchase == nil then
		return Shared.printError("No Slayer Shop item exists with the name: " .. item)
	end
	
	return getPurchaseValue(purchase)
end

function p.test()
	p._getSCItemProfits(1)
	Debug.log(getPurchase('Mystic Lantern'))
	--mw.log(p.getSCValue(item))
end

return p