diff --git a/atm.lua b/atm.lua index a54f13f..f0b9a5f 100644 --- a/atm.lua +++ b/atm.lua @@ -14,8 +14,7 @@ button[1,1;4,1;transaction_log;Transaction Log] local function logout(x,y) - return "button[" .. x .. "," .. y .. - ";2,1;logout;Log Out]" + return "button[" .. x .. "," .. y .. ";2,1;logout;Log Out]" end @@ -41,58 +40,48 @@ end local function new_account_fs(p_name) - local fs = "size[4,3]" - local act_suc, err = exchange:new_account(p_name) + local fs if not act_suc then - fs = fs .. label(0.5,0.5, "Error: " .. err) + fs = label(0.5,0.5, "Error: " .. err) else - fs = fs .. label(0.5,0.5, "Congratulations on \nyour new account.") + fs = label(0.5,0.5, "Congratulations on \nyour new account.") end - fs = fs .. logout(0.5,2) - - return fs + return "size[4,3]" .. fs .. logout(0.5,2) end local function info_fs(p_name) local balance = exchange:get_balance(p_name) - local fs = "size[4,3]" - + local fs if not balance then - fs = fs .. label(0.5,0.5, "You don't have an account.") + fs = label(0.5,0.5, "You don't have an account.") else - fs = fs .. label(0.5,0.5, "Balance: " .. balance) + fs = label(0.5,0.5, "Balance: " .. balance) end - fs = fs .. logout(0.5,2) - - return fs + return "size[4,3]" .. fs .. logout(0.5,2) end local function wire_fs(p_name) local balance = exchange:get_balance(p_name) - local fs = "size[4,5]" - fs = fs .. logout(0,4) + local fs = "size[4,5]" .. logout(0,4) if not balance then - fs = fs .. label(0.5,0.5, "You don't have an account.") - return fs + return fs .. label(0.5,0.5, "You don't have an account.") end -- To prevent duplicates - fs = fs .. field(-100, -100, 0,0, "trans_id", "", unique()) - fs = fs .. label(0.5,0.5, "Balance: " .. balance) - fs = fs .. field(0.5,1.5, 2,1, "recipient", "Send to:", "") - fs = fs .. field(0.5,2.5, 2,1, "amount", "Amount", "") - fs = fs .. "button[2,4;2,1;send;Send]" - - return fs + return fs .. field(-100, -100, 0,0, "trans_id", "", unique()) .. + label(0.5,0.5, "Balance: " .. balance) .. + field(0.5,1.5, 2,1, "recipient", "Send to:", "") .. + field(0.5,2.5, 2,1, "amount", "Amount", "") .. + "button[2,4;2,1;send;Send]" end @@ -102,41 +91,37 @@ local function send_fs(p_name, receiver, amt_str) local amt = tonumber(amt_str) if not amt or amt <= 0 then - fs = fs .. label(0.5,0.5, "Invalid transfer amount.") - fs = fs .. "button[0.5,2;2,1;wire;Back]" - - return fs + return fs .. label(0.5,0.5, "Invalid transfer amount.") .. + "button[0.5,2;2,1;wire;Back]" end - + local succ, err = exchange:transfer_credits(p_name, receiver, amt) if not succ then - fs = fs .. label(0.5,0.5, "Error: " .. err) - fs = fs .. "button[0.5,2;2,1;wire;Back]" - else - fs = fs.. label(0.5,0.5, "Successfully sent " - .. amt .. " credits to " .. receiver) - fs = fs .. "button[0.5,2;2,1;wire;Back]" + return fs .. label(0.5,0.5, "Error: " .. err) .. + "button[0.5,2;2,1;wire;Back]" end - - return fs + return fs.. label(0.5,0.5, "Successfully sent " .. + amt .. " credits to " .. receiver) .. + "button[0.5,2;2,1;wire;Back]" end local function log_fs(p_name) - local res = { "size[8,8]label[0,0;Transaction Log]button[0,7;2,1;logout;Log Out]", - "tablecolumns[text;text]", - "table[0,1;8,6;log_table;Time,Message", + local res = { + "size[8,8]label[0,0;Transaction Log]button[0,7;2,1;logout;Log Out]", + "tablecolumns[text;text]", + "table[0,1;8,6;log_table;Time,Message", } - local log = exchange:player_log(p_name) - for i, entry in ipairs(log) do - table.insert(res, ",") - table.insert(res, tostring(entry.Time)) - table.insert(res, ",") - table.insert(res, entry.Message) + for i, entry in ipairs(exchange:player_log(p_name)) do + i = i*4 + res[i] = "," + res[i+1] = tostring(entry.Time) + res[i+2] = "," + res[i+3] = entry.Message end - table.insert(res, "]") + res[#res+1] ="]" return table.concat(res) end @@ -145,9 +130,9 @@ end local trans_ids = {} -local function handle_fields(player, formname, fields) +minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= atm_form then return end - if fields["quit"] then return true end + if fields.quit then return true end local p_name = player:get_player_name() @@ -159,36 +144,33 @@ local function handle_fields(player, formname, fields) trans_ids[p_name] = this_id - if fields["logout"] then + if fields.logout then minetest.show_formspec(p_name, atm_form, main_menu) end - if fields["new_account"] then + if fields.new_account then minetest.show_formspec(p_name, atm_form, new_account_fs(p_name)) end - if fields["info"] then + if fields.info then minetest.show_formspec(p_name, atm_form, info_fs(p_name)) end - if fields["wire"] then + if fields.wire then minetest.show_formspec(p_name, atm_form, wire_fs(p_name)) end - if fields["send"] then + if fields.send then minetest.show_formspec(p_name, atm_form, send_fs(p_name, fields.recipient, fields.amount)) end - if fields["transaction_log"] then + if fields.transaction_log then minetest.show_formspec(p_name, atm_form, log_fs(p_name)) end return true -end - - -minetest.register_on_player_receive_fields(handle_fields) +end) minetest.register_node("global_exchange:atm", { @@ -198,10 +180,8 @@ minetest.register_node("global_exchange:atm", { "global_exchange_atm_side.png", }, groups = {cracky=2}, - on_rightclick = function(pos, node, clicker) - local p_name = clicker:get_player_name() - - minetest.show_formspec(p_name, atm_form, main_menu) + on_rightclick = function(pos, _, clicker) + minetest.show_formspec(clicker:get_player_name(), atm_form, main_menu) end, }) diff --git a/digital_mailbox.lua b/digital_mailbox.lua index 0697d78..96107f0 100644 --- a/digital_mailbox.lua +++ b/digital_mailbox.lua @@ -19,37 +19,37 @@ end local function mk_inbox_list(results, x, y, w, h) - local res = {} - table.insert(res, "textlist[") - table.insert(res, tostring(x)) - table.insert(res, ",") - table.insert(res, tostring(y)) - table.insert(res, ";") - table.insert(res, tostring(w)) - table.insert(res, ",") - table.insert(res, tostring(h)) - table.insert(res, ";result_list;") + local res = { + "textlist[", + tostring(x), + ",", + tostring(y), + ";", + tostring(w), + ",", + tostring(h), + ";result_list;" + } for i, row in ipairs(results) do - table.insert(res, row.Amount .. " " .. row.Item) - table.insert(res, ",") + res[i*2+8] = row.Amount .. " " .. row.Item + res[i*2+9] = "," end - table.insert(res, "]") + res[#res+1] = "]" return table.concat(res) end local function mk_mail_fs(p_name, results, err_str) - fs = "size[6,8]" - fs = fs .. "label[0,0;Inbox]" + fs = "size[6,8]" .. + "label[0,0;Inbox]" if err_str then fs = fs .. "label[3,0;Error: " .. err_str .. "]" end - fs = fs .. mk_inbox_list(results, 0, 1, 6, 6) - fs = fs .. "button[0,7;2,1;claim;Claim]" - return fs + return fs .. mk_inbox_list(results, 0, 1, 6, 6) .. + "button[0,7;2,1;claim;Claim]" end @@ -58,14 +58,15 @@ local function show_mail(p_name, results, err_str) end -local function handle_fields(player, formname, fields) +minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= mailbox_form then return end - if fields["quit"] then return true end + if fields.quit then return true end local p_name = player:get_player_name() local idx = selected_index[p_name] - if fields["claim"] and idx then + if fields.claim + and idx then local row = get_mail(p_name)[idx] if row then @@ -77,7 +78,7 @@ local function handle_fields(player, formname, fields) show_mail(p_name, get_mail(p_name), "Not enough room.") return true end - + local succ, res = exchange:take_inbox(row.Id, row.Amount) if not succ then show_mail(p_name, get_mail(p_name), res) @@ -92,8 +93,8 @@ local function handle_fields(player, formname, fields) end end - if fields["result_list"] then - local event = minetest.explode_textlist_event(fields["result_list"]) + if fields.result_list then + local event = minetest.explode_textlist_event(fields.result_list) if event.type == "CHG" then selected_index[p_name] = event.index @@ -101,10 +102,7 @@ local function handle_fields(player, formname, fields) end return true -end - - -minetest.register_on_player_receive_fields(handle_fields) +end) minetest.register_node("global_exchange:mailbox", { @@ -116,7 +114,7 @@ minetest.register_node("global_exchange:mailbox", { groups = {cracky=2}, on_rightclick = function(pos, node, clicker) local p_name = clicker:get_player_name() - local succ, res = exchange:view_inbox(p_name) + local _,res = exchange:view_inbox(p_name) mailbox_contents[p_name] = res minetest.show_formspec(p_name, mailbox_form, mk_mail_fs(p_name, res)) end, diff --git a/exchange.lua b/exchange.lua index 904332d..e23d488 100644 --- a/exchange.lua +++ b/exchange.lua @@ -77,7 +77,7 @@ SELECT AND Orders.Type = "sell" ) FROM distinct_items; - + END TRANSACTION; ]=] @@ -239,7 +239,7 @@ end local function is_integer(num) - return math.floor(num) == num + return num%1 == 0 end @@ -248,7 +248,7 @@ local function exec_stmt(db, stmt, names) local res = stmt:step() stmt:reset() - + if res == sqlite3.BUSY then return false, "Database Busy." elseif res ~= sqlite3.DONE then @@ -292,7 +292,7 @@ function exports.open_exchange(path) transaction_log_stmt = assert(db:prepare(transaction_log_query)), } - + local ret = { db = db, stmts = stmts, } @@ -332,7 +332,7 @@ function ex_methods.log(self, message, recipient) return true end end - + -- Returns success boolean and error. function ex_methods.new_account(self, p_name, amt) @@ -346,7 +346,7 @@ function ex_methods.new_account(self, p_name, amt) end db:exec("BEGIN TRANSACTION;") - + local stmt = self.stmts.new_act_stmt stmt:bind_names({ @@ -385,7 +385,7 @@ function ex_methods.new_account(self, p_name, amt) end db:exec("COMMIT;") - + return true end @@ -394,7 +394,7 @@ end function ex_methods.get_balance(self, p_name) local db = self.db local stmt = self.stmts.get_balance_stmt - + stmt:bind_values(p_name) local res = stmt:step() @@ -534,11 +534,6 @@ end -- Returns a list of orders, sorted by price. function ex_methods.search_orders(self, ex_name, order_type, item_name) - local params = { ex_name = ex_name, - order_type = order_type, - item_name = item_name, - } - local stmt if order_type == "buy" then stmt = self.stmts.search_asc_stmt @@ -546,12 +541,17 @@ function ex_methods.search_orders(self, ex_name, order_type, item_name) stmt = self.stmts.search_desc_stmt end - stmt:bind_names(params) + stmt:bind_names({ + ex_name = ex_name, + order_type = order_type, + item_name = item_name, + }) - local orders = {} + local orders,n = {},1 for tab in stmt:nrows() do - table.insert(orders, tab) + orders[n] = tab + n = n+1 end stmt:reset() @@ -561,17 +561,15 @@ end -- Same as above, except not sorted in any particular order. function ex_methods.search_player_orders(self, p_name) - local params = { p_name = p_name, - } - local stmt = self.stmts.search_own_stmt - stmt:bind_names(params) + stmt:bind_names({p_name = p_name}) - local orders = {} + local orders,n = {},1 for tab in stmt:nrows() do - table.insert(orders, tab) + orders[n] = tab + n = n+1 end stmt:reset() @@ -692,31 +690,31 @@ end -- remaining desired amount. Returns success. If succeeded, also returns amount -- bought. If failed, returns an error message function ex_methods.buy(self, p_name, ex_name, item_name, amount, rate) - if math.floor(amount) ~= amount then + if not is_integer(amount) then return false, "Noninteger quantity" elseif amount <= 0 then return false, "Nonpositive quantity" - elseif math.floor(rate) ~= rate then + elseif not is_integer(rate) then return false, "Noninteger rate" elseif rate <= 0 then return false, "Nonpositive rate" end local db = self.db - + local bal = self:get_balance(p_name) if not bal then return false, "Nonexistent account." end - + if bal < amount * rate then return false, "Not enough money." end - + db:exec("BEGIN TRANSACTION"); - + local remaining = amount local del_stmt = self.stmts.del_order_stmt @@ -748,7 +746,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, amount, rate) end del_stmt:reset() - local ch_succ, ch_err = + local ch_succ, ch_err = self:change_balance(poster, rate * row_amount) if not ch_succ then search_stmt:reset() @@ -756,7 +754,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, amount, rate) return false, ch_err end - local log_succ, log_err = + local log_succ, log_err = self:log(p_name .. " bought " .. row_amount .. " " .. item_name .. " from you. (+" .. rate * row_amount .. ")", poster) @@ -793,7 +791,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, amount, rate) end red_stmt:reset() - local ch_succ, ch_err = + local ch_succ, ch_err = self:change_balance(poster, rate * remaining) if not ch_succ then search_stmt:reset() @@ -801,7 +799,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, amount, rate) return false, ch_err end - local log_succ, log_err = + local log_succ, log_err = self:log(p_name .. " bought " .. remaining .. " " .. item_name .. " from you. (+" .. rate * remaining .. ")", poster) @@ -867,20 +865,20 @@ end -- Tries to sell to orders at the provided rate, and posts an offer with any -- remaining desired amount. Returns success. If failed, returns an error message. function ex_methods.sell(self, p_name, ex_name, item_name, amount, rate) - if math.floor(amount) ~= amount then + if not is_integer(amount) then return false, "Noninteger quantity" elseif amount <= 0 then return false, "Nonpositive quantity" - elseif math.floor(rate) ~= rate then + elseif not is_integer(rate) then return false, "Noninteger rate" elseif rate <= 0 then return false, "Nonpositive rate" end local db = self.db - + db:exec("BEGIN TRANSACTION"); - + local remaining = amount local revenue = 0 @@ -913,7 +911,7 @@ function ex_methods.sell(self, p_name, ex_name, item_name, amount, rate) end del_stmt:reset() - local in_succ, in_err = + local in_succ, in_err = self:put_in_inbox(poster, item_name, row_amount) if not in_succ then search_stmt:reset() @@ -921,7 +919,7 @@ function ex_methods.sell(self, p_name, ex_name, item_name, amount, rate) return false, in_err end - local log_succ, log_err = + local log_succ, log_err = self:log(p_name .. " sold " .. row_amount .. " " .. item_name .. " to you." , poster) if not log_succ then @@ -958,7 +956,7 @@ function ex_methods.sell(self, p_name, ex_name, item_name, amount, rate) end red_stmt:reset() - local in_succ, in_err = + local in_succ, in_err = self:put_in_inbox(poster, item_name, remaining) if not in_succ then search_stmt:reset() @@ -966,7 +964,7 @@ function ex_methods.sell(self, p_name, ex_name, item_name, amount, rate) return false, in_err end - local log_succ, log_err = + local log_succ, log_err = self:log(p_name .. " sold " .. remaining .. " " .. item_name .. " to you.", poster) if not log_succ then @@ -986,7 +984,6 @@ function ex_methods.sell(self, p_name, ex_name, item_name, amount, rate) end remaining = 0 - revenue = revenue + remaining * row.Rate end if remaining == 0 then break end @@ -1018,17 +1015,17 @@ end -- On success, returns true and a list of inbox entries. --- On failure, returns false and an error message. +-- TODO: On failure, return false and an error message. function ex_methods.view_inbox(self, p_name) - local db = self.db local stmt = self.stmts.view_inbox_stmt stmt:bind_values(p_name) - local res = {} + local res,n = {},1 for row in stmt:nrows() do - table.insert(res, row) + res[n] = row + n = n+1 end stmt:reset() @@ -1049,7 +1046,7 @@ function ex_methods.take_inbox(self, id, amount) id = id, change = amount }) - + local res = get_stmt:step() if res == sqlite3.BUSY then @@ -1066,7 +1063,7 @@ function ex_methods.take_inbox(self, id, amount) get_stmt:reset() db:exec("BEGIN TRANSACTION;") - + if available > amount then red_stmt:bind_names({ id = id, @@ -1115,18 +1112,18 @@ end -- 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 = {} + local res,n = {},1 for a in stmt:rows() do - table.insert(res, { + res[n] = { item_name = a[1], buy_volume = a[2], buy_max = a[3], sell_volume = a[4], sell_min = a[5], - }) + } + n = n+1 end stmt:reset() @@ -1138,11 +1135,12 @@ end function ex_methods.player_log(self, p_name) local stmt = self.stmts.transaction_log_stmt stmt:bind_names({ p_name = p_name }) - - local res = {} + + local res,n = {},1 for row in stmt:nrows() do - table.insert(res, row) + res[n] = row + n = n+1 end stmt:reset() @@ -1162,7 +1160,7 @@ function exports.test() print("Bob: ", ex:get_balance("Bob")) end - + -- Initialize balances if alice_bal then ex:set_balance("Alice", 420) @@ -1178,7 +1176,7 @@ function exports.test() print_balances() - + -- Transfer a valid amount print("Transfering 1000 credits from Bob to Alice") @@ -1207,7 +1205,7 @@ function exports.test() local succ, err = ex:sell("Bob", "", "default:cobble", 20, 1) print("Success: ", succ, " ", err) print_balances() - + ex:close() end diff --git a/exchange_machine.lua b/exchange_machine.lua index d071e38..17d2fee 100644 --- a/exchange_machine.lua +++ b/exchange_machine.lua @@ -3,46 +3,41 @@ local exchange = ... local search_cooldown = 2 local summary_interval = 600 +local summary_fs = "" 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 Min") + local res = { + "size[8,8]", + "label[0,0;Updated Periodically]", + "tablecolumns[text;text;text;text;text;text]", + "table[0,1;8,6;summary_table;", + "Item,Description,Buy Vol,Buy Max,Sell Vol,Sell Min" + } 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")) + for i, row in ipairs(exchange:market_summary()) do + local n = #res+1 + res[n] = "," .. row.item_name + local def = all_items[row.item_name] or {} + res[n+1] = "," .. (def.description or "Unknown Item") + res[n+2] = "," .. (row.buy_volume or 0) + res[n+3] = "," .. (row.buy_max or "N/A") + res[n+4] = "," .. (row.sell_volume or 0) + res[n+5] = "," .. (row.sell_min or "N/A") end - table.insert(res, "]") - table.insert(res, "button[3,7;2,1;back;Back]") - - return table.concat(res) + res[#res+1] = "]" + res[#res+1] = "button[3,7;2,1;back;Back]" + + summary_fs = table.concat(res) end -local summary_fs = "" -minetest.after(0, function() - summary_fs = mk_summary_fs() -end) +minetest.after(0, mk_summary_fs) local elapsed = 0 minetest.register_globalstep(function(dtime) elapsed = elapsed + dtime if elapsed >= summary_interval then - summary_fs = mk_summary_fs() + mk_summary_fs() elapsed = 0 end end) @@ -61,17 +56,12 @@ local main_state = {} -- a cooldown on searches -- sell: A boolean whether the player has sell selected - -local function default_main_state() - return { old_fields = {}, - search_results = {}, - last_search_time = 0, - } -end - - minetest.register_on_joinplayer(function(player) - main_state[player:get_player_name()] = default_main_state() + main_state[player:get_player_name()] = { + old_fields = {}, + search_results = {}, + last_search_time = 0, + } end) minetest.register_on_leaveplayer(function(player) @@ -87,16 +77,18 @@ local tablecolumns = local function table_from_results(results, x, y, w, h, selected) - local fs_tab = {} + local fs_tab local function insert(str) - table.insert(fs_tab, str) + fs_tab[#fs_tab+1] = str end - insert(tablecolumns) - insert("table[" .. x .. "," .. y .. ";" .. w .. "," .. h .. ";") - insert("result_table;") - insert("Poster,Type,Item,Description,Amount,Rate") + fs_tab = { + tablecolumns, + "table[" .. x .. "," .. y .. ";" .. w .. "," .. h .. ";", + "result_table;", + "Poster,Type,Item,Description,Amount,Rate" + } local all_items = minetest.registered_items @@ -108,11 +100,8 @@ local function table_from_results(results, x, y, w, h, selected) insert(",") insert(tostring(row.Item)) insert(",") - if all_items[row.Item] then - insert(all_items[row.Item].description) - else - insert("Unknown Item") - end + local def = all_items[row.Item] or {} + insert(def.description or "Unknown Item") insert(",") insert(tostring(row.Amount)) insert(",") @@ -130,8 +119,6 @@ end local function mk_main_fs(p_name, new_item, err_str, success) - local fs = "size[8,9]" - local state = main_state[p_name] if not state then return end -- Should have been initialized on player join @@ -145,21 +132,22 @@ local function mk_main_fs(p_name, new_item, err_str, success) local bal = exchange:get_balance(p_name) + local fs if bal then - fs = fs .. "label[0,0;Balance: " .. bal .. "]" + fs = "label[0,0;Balance: " .. bal .. "]" else - fs = fs .. "label[0.2,0.5;Use an ATM to make your account.]" + 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 .. "]" - fs = fs .. "button[6,1;2,1.4;select_item;Select Item]" - fs = fs .. "checkbox[5,3;sell;Sell;" .. tostring(sell_def) .. "]" - fs = fs .. "field[0.2,2.5;2,1;rate;Rate: ;" .. rate_def .. "]" - fs = fs .. "button[2,2;2,1.4;search;Search]" - fs = fs .. "button[4,2;3,1.4;post_order;Post Order]" + fs = fs .. "button[4,0;2,1;summary;Market Summary]" .. + "button[6,0;2,1;your_orders;Your Orders]" .. + "field[0.2,1.5;3,1;item;Item: ;" .. item_def .. "]" .. + "field[3.2,1.5;3,1;amount;Amount: ;" .. amount_def .. "]" .. + "button[6,1;2,1.4;select_item;Select Item]" .. + "checkbox[5,3;sell;Sell;" .. tostring(sell_def) .. "]" .. + "field[0.2,2.5;2,1;rate;Rate: ;" .. rate_def .. "]" .. + "button[2,2;2,1.4;search;Search]" .. + "button[4,2;3,1.4;post_order;Post Order]" if err_str then fs = fs .. "label[0,3;Error: " .. err_str .. "]" @@ -169,9 +157,7 @@ local function mk_main_fs(p_name, new_item, err_str, success) fs = fs .. "label[0,3;Success!]" end - fs = fs .. table_from_results(results, 0, 4, 8, 5, selected_def) - - return fs + return "size[8,9]" .. fs .. table_from_results(results, 0, 4, 8, 5, selected_def) end @@ -181,15 +167,16 @@ end -- Something similar to creative inventory -local selectable_inventory_size = 0 +local pagemax = 1 -- Create detached inventory after loading all mods minetest.after(0, function() local inv = minetest.create_detached_inventory("global_exchange", { - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + allow_move = function(inv, from_list, _, to_list, _,_, player) local p_name = player:get_player_name() - if from_list == "main" and to_list == "p_" .. p_name then + if from_list == "main" + and to_list == "p_" .. p_name then return 1 else return 0 @@ -201,7 +188,7 @@ minetest.after(0, function() allow_take = function() return 0 end, - on_move = function(inv, from_list, from_index, to_list, to_index, count, player) + on_move = function(inv, _, _, _, _, _, player) local p_name = player:get_player_name() local p_list = "p_" .. p_name @@ -212,11 +199,14 @@ minetest.after(0, function() end, }) - local selectable_list = {} + local selectable_list,n = {},1 for name, def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) - and def.description and def.description ~= "" then - table.insert(selectable_list, name) + if (not def.groups.not_in_creative_inventory + or def.groups.not_in_creative_inventory == 0) + and def.description + and def.description ~= "" then + selectable_list[n] = name + n = n+1 end end table.sort(selectable_list) @@ -225,32 +215,29 @@ minetest.after(0, function() inv:add_item("main", ItemStack(itemstring)) end - selectable_inventory_size = #selectable_list + pagemax = math.ceil((#selectable_list - 1) / (8 * 4)) end) minetest.register_on_joinplayer(function(player) - local big_inv = minetest.get_inventory({type="detached", name="global_exchange"}) - local p_list = "p_" .. player:get_player_name() - - big_inv:set_size(p_list, 1) + -- the inventory list name is "p_"..player_name + minetest.get_inventory({ + type="detached", + name="global_exchange" + }):set_size("p_" .. player:get_player_name(), 1) end) - + local select_form = "global_exchange:select_form" local function mk_select_formspec(p_name, start_i, pagenum) - pagenum = math.floor(pagenum) - local pagemax = math.floor((selectable_inventory_size - 1) / (8 * 4) + 1) - local p_list = "p_" .. p_name - return "size[9.3,8]" .. "list[detached:global_exchange;main;0.3,0.5;8,4;" .. tostring(start_i) .. "]" .. "button[0.3,4.5;1.6,1;select_prev;<<]".. "button[6.7,4.5;1.6,1;select_next;>>]".. - "label[2.0,5.55;"..tostring(pagenum).."/"..tostring(pagemax).."]".. - "list[detached:global_exchange;" .. p_list .. ";0.3,7;1,1;]" + "label[2.0,5.55;"..tostring(math.floor(pagenum)).."/"..tostring(pagemax).."]".. + "list[detached:global_exchange;p_" .. p_name .. ";0.3,7;1,1;]" end @@ -274,17 +261,12 @@ local own_state = {} -- own_results: Results for own orders. local function mk_own_orders_fs(p_name, results, selected) - local fs = "size[8,8]" - - local state = main_state[p_name] - - fs = fs .. "label[0.5,0.2;Your Orders]" - fs = fs .. "button[6,0;2,1;refresh;Refresh]" - fs = fs .. table_from_results(results, 0, 2, 8, 4.5, selected or "") - fs = fs .. "button[0,7;2,1;cancel;Cancel]" - fs = fs .. "button[3,7;2,1;back;Back]" - - return fs + return "size[8,8]" .. + "label[0.5,0.2;Your Orders]" .. + "button[6,0;2,1;refresh;Refresh]" .. + table_from_results(results, 0, 2, 8, 4.5, selected or "") .. + "button[0,7;2,1;cancel;Cancel]" .. + "button[3,7;2,1;back;Back]" end @@ -296,11 +278,11 @@ end -- Returns success, and also returns an error message if failed. local function post_order(player, ex_name, order_type, item_name, amount_str, rate_str) local p_name = player:get_player_name() - + if item_name == "" then return false, "You must input an item" end - + if not minetest.registered_items[item_name] then return false, "That item does not exist." end @@ -323,7 +305,7 @@ local function post_order(player, ex_name, order_type, item_name, amount_str, ra local p_inv = player:get_inventory() local stack = ItemStack(item_name) stack:set_count(amount) - + if order_type == "buy" then if not p_inv:room_for_item("main", stack) then return false, "Not enough space in inventory." @@ -353,8 +335,7 @@ local function post_order(player, ex_name, order_type, item_name, amount_str, ra end -local function handle_main(player, formname, fields) - if formname ~= main_form then return end +local function handle_main(player, fields) local p_name = player:get_player_name() local state = main_state[p_name] local old_fields = state.old_fields @@ -363,17 +344,17 @@ local function handle_main(player, formname, fields) old_fields[k] = v end - if fields["select_item"] then + if fields.select_item then show_select(p_name) end - if fields["search"] then + if fields.search then local now = os.time() local last_search = state.last_search_time if now - last_search < search_cooldown then show_main(p_name, nil, "Please wait before searching again.") - return true + return end -- If the player is selling, she wants "buy" type offers. @@ -392,22 +373,18 @@ local function handle_main(player, formname, fields) show_main(p_name) end - if fields["sell"] then - if fields["sell"] == "true" then - state.sell = true - else - state.sell = false - end + if fields.sell then + state.sell = fields.sell == "true" end - - if fields["post_order"] then + + if fields.post_order then local now = os.time() local last_search = state.last_search_time if now - last_search < search_cooldown then show_main(p_name, nil, "Please wait before posting.") - return true + return end local order_type @@ -416,12 +393,9 @@ local function handle_main(player, formname, fields) else order_type = "buy" end - local item_name = fields["item"] - local amount_str = fields["amount"] - local rate_str = fields["rate"] local succ, err = - post_order(player, "", order_type, item_name, amount_str, rate_str) + post_order(player, "", order_type, fields.item, fields.amount, fields.rate) if succ then state.search_results = {} @@ -432,17 +406,17 @@ local function handle_main(player, formname, fields) end - if fields["result_table"] then + if fields.result_table then local results = state.search_results - local event = minetest.explode_table_event(fields["result_table"]) + local event = minetest.explode_table_event(fields.result_table) if event.type ~= "CHG" then - return true + return end local index = event.row - 1 result = results[index] - + if result then old_fields.amount = tostring(result.Amount) old_fields.rate = tostring(result.Rate) @@ -451,11 +425,11 @@ local function handle_main(player, formname, fields) show_main(p_name) end - if fields["summary"] then + if fields.summary then show_summary(p_name) end - if fields["your_orders"] then + if fields.your_orders then if not own_state[p_name] then own_state[p_name] = {} end @@ -465,46 +439,37 @@ local function handle_main(player, formname, fields) show_own_orders(p_name, o_state.own_results) end - - return true end -local function handle_select(player, formname, fields) - if formname ~= select_form then return end - +local function handle_select(player, fields) local p_name = player:get_player_name() - - local pagemax = math.floor((selectable_inventory_size - 1) / (8 * 4) + 1) + local pagenum = player_pages[p_name] or 1 - if fields["select_prev"] then + if fields.select_prev then player_pages[p_name] = math.max(1, pagenum - 1) show_select(p_name) - elseif fields["select_next"] then + elseif fields.select_next then player_pages[p_name] = math.min(pagemax, pagenum + 1) show_select(p_name) end - - return true end -local function handle_own_orders(player, formname, fields) - if formname ~= own_form then return end - +local function handle_own_orders(player, fields) local p_name = player:get_player_name() local state = own_state[p_name] or {} local results = state.own_results or {} local idx = state.selected_index - if fields["refresh"] then + if fields.refresh then state.own_results = exchange:search_player_orders(p_name) or {} show_own_orders(p_name, state.own_results) end - if fields["cancel"] and idx then + if fields.cancel and idx then local row = results[idx] if not row then return true end local p_inv = player:get_inventory() @@ -535,39 +500,41 @@ local function handle_own_orders(player, formname, fields) show_own_orders(p_name, state.own_results) end - if fields["result_table"] then - local event = minetest.explode_table_event(fields["result_table"]) + if fields.result_table then + local event = minetest.explode_table_event(fields.result_table) if event.type == "CHG" then state.selected_index = event.row - 1 show_own_orders(p_name, results, event.row) end end - if fields["back"] then + if fields.back then show_main(p_name) end - - return true 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) +local function handle_summary(player, fields) + if fields.back then + show_main(player:get_player_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_on_player_receive_fields(function(player, formname, fields) + if formname == main_form then + handle_main(player, fields) + elseif formname == select_form then + handle_select(player, fields) + elseif formname == own_form then + handle_own_orders(player, fields) + elseif formname == summary_form then + handle_summary(player, fields) + else + return + end + return true +end) minetest.register_node("global_exchange:exchange", { @@ -577,7 +544,7 @@ minetest.register_node("global_exchange:exchange", { "global_exchange_exchange_side.png", }, groups = {cracky=2}, - on_rightclick = function(pos, node, clicker) + on_rightclick = function(_, _, clicker) local p_name = clicker:get_player_name() local state = main_state[p_name] if state then diff --git a/init.lua b/init.lua index 158b4f6..aed516b 100644 --- a/init.lua +++ b/init.lua @@ -1,9 +1,7 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) .. "/" -local savepath = minetest.get_worldpath() .. "/global_exchange.db" -local income_str = minetest.setting_get("citizens_income") -local income = income_str and tonumber(income_str) or 10 +local income = tonumber(minetest.setting_get("citizens_income")) or 10 local income_interval = 1200 @@ -11,41 +9,40 @@ local income_msg = "You receive your citizen's income (+" .. income .. ")" local next_payout = os.time() + income_interval -local ex = dofile(modpath .. "exchange.lua") -local exchange = ex.open_exchange(savepath) +local exchange = (dofile(modpath .. "exchange.lua")).open_exchange( + minetest.get_worldpath() .. "/global_exchange.db" +) minetest.register_on_shutdown(function() - exchange:close() + exchange:close() end) --- Only check once in a while -local elapsed = 0 +local function check_giving() + local now = os.time() + if now < next_payout then + return + end -minetest.register_globalstep(function(dtime) - elapsed = elapsed + dtime - if elapsed <= 5 then return end + next_payout = now + income_interval - elapsed = 0 + for _, player in ipairs(minetest.get_connected_players()) do + local p_name = player:get_player_name() - local now = os.time() - if now < next_payout then return end + local succ = exchange:give_credits(p_name, income, + "Citizen's Income (+" .. income .. ")") - next_payout = now + income_interval - - for i, player in ipairs(minetest.get_connected_players()) do - local p_name = player:get_player_name() - - local succ = - exchange:give_credits(p_name, income, - "Citizen's Income (+" .. income .. ")") - - if succ then - minetest.chat_send_player(p_name, income_msg) - end + if succ then + minetest.chat_send_player(p_name, income_msg) end -end) + end + + minetest.after(5, check_giving) +end + +minetest.after(5, check_giving) + assert(loadfile(modpath .. "atm.lua"))(exchange)