Market summary

This commit is contained in:
raymoo 2016-02-25 22:07:57 -08:00
parent 72f0a7832a
commit 37a92fd65a
2 changed files with 125 additions and 1 deletions

View File

@ -53,6 +53,32 @@ ON Inbox (Recipient);
CREATE VIEW if not exists distinct_items AS
SELECT DISTINCT Item FROM Orders;
CREATE VIEW if not exists market_summary AS
SELECT
distinct_items.Item,
(
SELECT sum(Orders.Amount) FROM Orders
WHERE Orders.Item = distinct_items.Item
AND Orders.Type = "buy"
),
(
SELECT max(Orders.Rate) FROM Orders
WHERE Orders.Item = distinct_items.Item
AND Orders.Type = "buy"
),
(
SELECT sum(Orders.Amount) FROM Orders
WHERE Orders.Item = distinct_items.Item
AND Orders.Type = "sell"
),
(
SELECT min(Orders.Rate) FROM Orders
WHERE Orders.Item = distinct_items.Item
AND Orders.Type = "sell"
)
FROM distinct_items;
END TRANSACTION;
]=]
@ -192,6 +218,10 @@ DELETE FROM Inbox
WHERE Id = :id;
]=]
local summary_query = [=[
SELECT * FROM market_summary;
]=]
local ex_methods = {}
local ex_meta = { __index = ex_methods }
@ -252,6 +282,7 @@ function exports.open_exchange(path)
get_inbox_stmt = assert(db:prepare(get_inbox_query)),
red_inbox_stmt = assert(db:prepare(red_inbox_query)),
del_inbox_stmt = assert(db:prepare(del_inbox_query)),
summary_stmt = assert(db:prepare(summary_query)),
}
@ -1053,7 +1084,32 @@ function ex_methods.take_inbox(self, id, amount)
return true, math.min(amount, available)
end
-- Returns a list of tables with fields:
-- item_name: Name of the item
-- buy_volume: Number of items sought
-- buy_max: Maximum buy rate
-- sell_volume: Number of items for sale
-- sell_min: Minimum sell rate
function ex_methods.market_summary(self)
local db = self.db
local stmt = self.stmts.summary_stmt
local res = {}
for a in stmt:rows() do
table.insert(res, {
item_name = a[1],
buy_volume = a[2],
buy_max = a[3],
sell_volume = a[4],
sell_min = a[5],
})
end
stmt:reset()
return res
end
function exports.test()

View File

@ -1,6 +1,55 @@
local exchange = ...
local search_cooldown = 2
local summary_interval = 600
local function mk_summary_fs()
local summary = exchange:market_summary()
local res = {}
table.insert(res, "size[8,8]")
table.insert(res, "label[0,0;Updated Periodically]")
table.insert(res, "tablecolumns[text;text;text;text;text;text]")
table.insert(res, "table[0,1;8,6;summary_table;")
table.insert(res, "Item,Description,Buy Vol,Buy Max,Sell Vol,Sell Max")
local all_items = minetest.registered_items
for i, row in ipairs(summary) do
table.insert(res, "," .. row.item_name)
local def = all_items[row.item_name]
if def then
table.insert(res, "," .. def.description)
else
table.insert(res, "," .. "Unknown Item")
end
table.insert(res, "," .. (row.buy_volume or 0))
table.insert(res, "," .. (row.buy_max or "N/A"))
table.insert(res, "," .. (row.sell_volume or 0))
table.insert(res, "," .. (row.sell_min or "N/A"))
end
table.insert(res, "]")
table.insert(res, "button[3,7;2,1;back;Back]")
return table.concat(res)
end
local summary_fs = ""
minetest.after(0, function()
summary_fs = mk_summary_fs()
end)
local elapsed = 0
minetest.register_globalstep(function(dtime)
elapsed = elapsed + dtime
if elapsed >= summary_interval then
summary_fs = mk_summary_fs()
end
end)
local summary_form = "global_exchange:summary"
local function show_summary(p_name)
minetest.show_formspec(p_name, summary_form, summary_fs)
end
local main_state = {}
-- ^ A per-player state for the main form. It contains these values:
@ -101,6 +150,7 @@ local function mk_main_fs(p_name, new_item, err_str, success)
fs = fs .. "label[0.2,0.5;Use an ATM to make your account.]"
end
fs = fs .. "button[4,0;2,1;summary;Market Summary]"
fs = fs .. "button[6,0;2,1;your_orders;Your Orders]"
fs = fs .. "field[0.2,1.5;3,1;item;Item: ;" .. item_def .. "]"
fs = fs .. "field[3.2,1.5;3,1;amount;Amount: ;" .. amount_def .. "]"
@ -396,6 +446,10 @@ local function handle_main(player, formname, fields)
show_main(p_name)
end
if fields["summary"] then
show_summary(p_name)
end
if fields["your_orders"] then
if not own_state[p_name] then
own_state[p_name] = {}
@ -491,9 +545,23 @@ local function handle_own_orders(player, formname, fields)
end
local function handle_summary(player, formname, fields)
if formname ~= summary_form then return end
local p_name = player:get_player_name()
if fields["back"] then
show_main(p_name)
end
return true
end
minetest.register_on_player_receive_fields(handle_main)
minetest.register_on_player_receive_fields(handle_select)
minetest.register_on_player_receive_fields(handle_own_orders)
minetest.register_on_player_receive_fields(handle_summary)
minetest.register_node("global_exchange:exchange", {