ExetaRes LogoExetaRes

Module:ItemPrices

Click here to update this documentation.

This module is used in Objects and NPCs pages to generate their trade lists. Its data comes from Module:ItemPrices/data.

The module is used by the following templates:

Deprecated


local itemprices = require("Module:ItemPrices/data")

local p = {}
local notes = {}
local npcnotes = {}

local function has_value (tab, val)
    for index, value in ipairs(tab) do
        if value == val then
            return true
        end
    end
    return false
end

function indexOf(array, value)
    for i, v in ipairs(array) do
        if v == value then
            return i
        end
    end
    return nil
end

function notesAsLinks(notesIdx)
	local noten = ""
	if string.len(notesIdx) > 1 then
		local notenarr = {}
		for i in string.gmatch(notesIdx, "%d") do
		   table.insert(notenarr, "[[#notes-" .. i .. "|".. i .. "]]")
		end
		noten = "<sup>" .. table.concat(notenarr, ", ") .. "</sup>"
	elseif string.len(notesIdx) == 1 then
		noten = "<sup>[[#notes-" .. notesIdx .. "|".. notesIdx .. "]]</sup>"
	end
	return noten
end

function p.displayTradesForNPC(frame)
	local targetNPC = frame.args["npc"]
	local transactionType = frame.args["transaction"]
	local notrades = true
	
	local transaction = "Buys"
	if transactionType == "sells" then
		transaction = "Sells"
	end
	
	local output = mw.html.create("div")
		:addClass("trades")
		:attr("id", "npc-trade-" .. transactionType)
		:node(mw.html.create("h4")
				:wikitext(transaction))
	
	-- Check for items
	local itemsn = getItemsForNPC(targetNPC, transactionType)
	if table.getn(itemsn) > 0 then
		notrades = false
		local pricetable, noteslist = createItemsTable(itemsn, transactionType)
		output:node(pricetable)
		
		if table.getn(notes) > 0 then
			local noteslist = mw.html.create("ol")
		
			for k, v in pairs(notes) do
				noteslist:node(mw.html.create("li")
					:attr("id", "notes-" .. k)
					:wikitext(v))	
			end
		
			output:node(mw.html.create("div")
				:addClass("item-notes")
				:wikitext("'''Notes:'''")
				:node(noteslist))
		end
	end
	
	if notrades then
		output:node(mw.html.create("p")
			:addClass("no-results")
			:wikitext("This NPC does not ".. transactionType:sub(1, -2) .. " anything."))
	end
	
	return output
end

-- Retrieves all item selling/buying prices for a given npc
function getItemsForNPC(targetNPC, transactionType)
	--local targetNPC = frame.args["npc"]
	--local transactionType = frame.args["transaction"]
	if not itemprices[targetNPC] then --If the NPC isn't list or doesn't exist we can skip everything else
		return {}
	end
	local items = itemprices[targetNPC][transactionType]
	local notenpc = ""
	local itemsn = {}
	if itemprices[targetNPC]["note"] then
		notenpc = itemprices[targetNPC]["note"]
		table.insert(notes, notenpc)
	end
	for k, v in pairs(items) do
		if not (v["status"] == "itemonly") then
			local noten = ""
			if v["note"] then
				-- Add Item Note
				if not has_value(notes, v["note"]) then
					table.insert(notes, v["note"])
				end
				if itemprices[targetNPC]["note"] then
					noten = "1, " .. indexOf(notes, v["note"])
				else 
					noten = indexOf(notes, v["note"])
				end
			elseif itemprices[targetNPC]["note"] then
				noten = "1"
			end
			table.insert(itemsn, {item = v["item"], price = v["price"], noten = noten, currency = v["currency"], keytype = v["keytype"]})
		end
	end
	if table.getn(itemsn) == 0 then --If the NPC exists but it only buys or sells and we're looking for the opposite, we don't print an empty table
		return {}
	end
	table.sort(itemsn, function(a,b) return a["item"] < b["item"] end)
	return itemsn
end

-- Creates the items table for a npc
function createItemsTable(items, transactionType)
	local pricetable = mw.html.create("table")
		:addClass("wikitable sortable")
		:node(mw.html.create("tr")
			:node(mw.html.create("th")
				:wikitext(""))
			:node(mw.html.create("th")
				:wikitext("Item"))
			:node(mw.html.create("th")
				:attr("data-sort-type", "number")
				:wikitext("Price")))
	
	local eng = mw.language.new("en")
	for k, v in pairs(items) do
		local price = ""
		if tonumber(v["price"]) then
			local currency = "Gold"
			if not (v["currency"] == nil) then
				currency = v["currency"]
			end
			local iconargs = {}
			table.insert(iconargs, currency)
			price = eng:formatNum(v["price"]) .. " ".. mw.getCurrentFrame():expandTemplate{title = "Icon", args = iconargs}
		else
			price = v["price"]
		end
		
		local noten = notesAsLinks(v["noten"])
		
		local imgname = v["item"]
		
		--if string.find(key, "^Key %d%d%d%d$") then --Checks if the item is named as a key, e.g. 'Key 0000'
		if v["keytype"] then
			imgname = v["keytype"] .. " Key"
		end
		
		pricetable:node(mw.html.create("tr")
			:css("text-align", "center")
			:node(mw.html.create("td")
				:wikitext("[[File:" .. imgname .. ".gif|link=".. v["item"] .. "]]"))
			:node(mw.html.create("td")
				:wikitext("[[" .. v["item"] .. "]]" .. noten))
			:node(mw.html.create("td")
				:css("white-space", "nowrap")
				:wikitext(price)))
	end
	return pricetable, noteslist
end

-- Retrieves all selling/buying prices for a given item
function p.displayNPCsForItem(frame)
	local targetItem = frame.args["item"]
	local transactionType = frame.args["transaction"]
	local outformat = frame.args["format"]
	local npcs = {}
	
	for k, v in pairs(itemprices) do
		if not (v["status"] == "npconly") then
			for k2, v2 in pairs(v[transactionType]) do
				if v2["item"] == targetItem then
					if outformat == "csv" then
						table.insert(npcs, k)	
					else
						local notenarr = {}
						if v["note"] then
							-- Add NPC Note
							if not has_value(notes, v["note"]) then
								table.insert(notes, v["note"])
								table.insert(notenarr, table.getn(notes))
							else
								table.insert(notenarr, indexOf(notes, v["note"]))
							end
							
						end
						if v2["note"] then
							-- Add item Note
							if not has_value(notes, v2["note"]) then
								table.insert(notes, v2["note"])
								table.insert(notenarr, table.getn(notes))
							else
								table.insert(notenarr, indexOf(notes, v2["note"]))
							end
							
						end
						local noten = ""
						if notenarr then
							noten = table.concat(notenarr, ", ")
						else 
							noten = ""
						end
						table.insert(npcs, {npc = k, location = v["location"], price = v2["price"], noten = noten, currency = v2["currency"]})
					end
				end
			end
		end
	end
	if outformat == "csv" then
		return table.concat(npcs, ", ")
	else
		if table.getn(npcs) == 0 then
			return p.ItemNoTrade(transactionType, "item")
		end
		table.sort(npcs, function(a,b) return a["npc"] < b["npc"] end)
		return p.createNPCsTable(npcs, transactionType)
	end
end

-- Creates the npcs table
function p.createNPCsTable(npcs, transactionType)
	
	local pricetable = mw.html.create("table")
		:addClass("wikitable sortable")
		:node(mw.html.create("tr")
			:node(mw.html.create("th")
				:wikitext("NPC"))
			:node(mw.html.create("th")
				:wikitext("Location"))
			:node(mw.html.create("th")
				:attr("data-sort-type", "number")
				:wikitext("Price")))
	
	local eng = mw.language.new("en")
	for k, v in pairs(npcs) do
		local price = ""
		if tonumber(v["price"]) then
			local currency = "Gold"
			if not (v["currency"] == nil) then
				currency = v["currency"]
			end
			local iconargs = {}
			table.insert(iconargs, currency)
			price = eng:formatNum(v["price"]) .. " ".. mw.getCurrentFrame():expandTemplate{title = "Icon", args = iconargs}
		else
			price = v["price"]
		end
		
		local noten = notesAsLinks(v["noten"])
		
		pricetable:node(mw.html.create("tr")
			:css("text-align", "center")
			:node(mw.html.create("td")
				:wikitext("[[" .. v["npc"] .. "]]" .. noten))
			:node(mw.html.create("td")
				:wikitext(v["location"]))
			:node(mw.html.create("td")
				:css("white-space", "nowrap")
				:wikitext(price)))
	end
	
	local transaction = "Sell To"
	local transactionid = "sellto"
	if transactionType == "sells" then
		transaction = "Buy From"
		transactionid = "buyfrom"
	end
	local result = mw.html.create("div")
		:addClass("trades")
		:attr("id", "npc-trade-" .. transactionid)
		:node(mw.html.create("h4")
			:wikitext(transaction))
		:node(pricetable)
		
	if table.getn(notes) > 0 then
		local noteslist = mw.html.create("ol")
	
		for k, v in pairs(notes) do
			noteslist:node(mw.html.create("li")
				:attr("id", "notes-" .. k)
				:wikitext(v))	
		end
	
		result:node(mw.html.create("div")
			:addClass("item-notes")
			:wikitext("'''Notes:'''")
			:node(noteslist))
	end
		
    return result
end

-- Output if Item is not bought/sold by NPCs
function p.ItemNoTrade(transaction, product)
	local title = "Sell To"
	local text = "No NPC buys this " .. product .. "."
	if transaction == "sells" then
		title = "Buy From"
		text = "No NPC sells this " .. product .. "."
	end
	local output = mw.html.create("div")
		:addClass("trades")
		:node(mw.html.create("h4")
				:wikitext(title))
		:node(mw.html.create("p")
			:addClass("no-results")
			:wikitext(text))
	return output
end

--Gets the best buy/sell price of an item
function p.getItemPrice(frame)
	local targetItem = frame.args["item"]
	local transactionType = frame.args["transaction"]
	local currency = frame.args["currency"]
	local values = {}
	
	for k, v in pairs(itemprices) do
		if not (v["status"] == "npconly") then
			for k2, v2 in pairs(v[transactionType]) do
				if v2["item"] == targetItem then
					if ((currency == "gold") and (not v2["currency"])) or (currency == v2["currency"]) then
						table.insert(values, v2["price"])
					end
				end
			end
		end
	end
	if table.getn(values) == 0 then
		return 0
	elseif transactionType == "sells" then
		return math.min(unpack(values))
	elseif transactionType == "buys" then
		return math.max(unpack(values))
	else
		return 'Error: invalid transaction'
	end
end

--Maintenance functions
--Count how many NPCs buy/sell a given item
function p.countItemTransactions(frame)
	local output = {}
	for k, v in pairs(itemprices) do
		for k2, v2 in pairs(v["buys"]) do
			local item = v2["item"]
			if (not output[item]) then
				output[item] = {buys = 1, sells = 0}
			else 
				output[item]["buys"] = output[item]["buys"] + 1
			end
		end
		for k2, v2 in pairs(v["sells"]) do
			local item = v2["item"]
			if (not output[item]) then
				output[item] = {buys = 0, sells = 1}
			else 
				output[item]["sells"] = output[item]["sells"] + 1
			end
		end
	end
	
	return p.createTransactionsTable(output)
end
function p.createTransactionsTable(data)
	
	local counttable = mw.html.create("table")
		:addClass("wikitable sortable")
		:node(mw.html.create("tr")
			:node(mw.html.create("th")
				:wikitext("Item"))
			:node(mw.html.create("th")
				:wikitext("NPCs_Buying"))
			:node(mw.html.create("th")
				:wikitext("NPCs_Selling")))
			
	for k, v in pairs(data) do
		counttable:node(mw.html.create("tr")
			:css("text-align", "center")
			:node(mw.html.create("td")
				:wikitext("[[" .. k .. "]]"))
			:node(mw.html.create("td")
				:wikitext(v["buys"]))
			:node(mw.html.create("td")
				:wikitext(v["sells"])))
	end
		
    return counttable
end

return p