forked from nalc/global_exchange
379 lines
11 KiB
Lua
379 lines
11 KiB
Lua
-- A telling machine. Call this file with the exchange argument.
|
|
local exchange, formlib = ...
|
|
local S = minetest.get_translator("global_exchange")
|
|
|
|
local atm_form = "global_exchange:atm_form"
|
|
local atm_pos = {}
|
|
|
|
local unique = (function(unique_num)
|
|
return function()
|
|
unique_num = unique_num + 1
|
|
return unique_num
|
|
end
|
|
end)(0)
|
|
|
|
local coins = {
|
|
[1] = "bitchange:minecoinblock", [2] = "bitchange:minecoin", [3] = "bitchange:mineninth",
|
|
[4] = "maptools:gold_coin", [5] = "maptools:silver_coin", [6] = "maptools:copper_coin"
|
|
}
|
|
|
|
local coins_convert = {
|
|
[coins[6]]=1, [coins[5]]=9, [coins[4]]=81, [coins[3]]=729, [coins[2]]=6561, [coins[1]]=59049,
|
|
["minercantile:copper_coin"]=1, ["minercantile:silver_coin"]=9, ["minercantile:gold_coin"]=81
|
|
}
|
|
|
|
local function withdraw_fs(fs, p_name, amount)
|
|
local spos = atm_pos[p_name].x..","..atm_pos[p_name].y..","..atm_pos[p_name].z
|
|
local inv = minetest.get_inventory({ type = "node", pos={x=atm_pos[p_name].x, y=atm_pos[p_name].y, z=atm_pos[p_name].z} })
|
|
|
|
local msg = ""
|
|
local w_amount = tonumber(amount)
|
|
if w_amount and math.floor(w_amount) == w_amount and w_amount > 0 then
|
|
local succ, err = exchange:give_credits(p_name, 0 - w_amount, S("Cash withdrawal: (-@1)", w_amount))
|
|
if succ then
|
|
local index = 1
|
|
repeat
|
|
local m = math.floor(w_amount / coins_convert[coins[index]])
|
|
if m > 0 then
|
|
inv:add_item( "main", ItemStack({ name = coins[index], count = m }) )
|
|
end
|
|
w_amount = w_amount - (coins_convert[coins[index]] * m)
|
|
index = index + 1
|
|
until ( w_amount == 0)
|
|
else
|
|
msg = err
|
|
end
|
|
elseif w_amount then
|
|
msg = S("Invalid number ! Must be an Integer > 0")
|
|
end
|
|
|
|
local balance = exchange:get_balance(p_name)
|
|
|
|
fs:size(8,10)
|
|
|
|
if not balance then
|
|
fs:label(0.5, 0.5, S("You don't have an account."))
|
|
else
|
|
fs:label(3,8.9, S("Balance: @1", balance))
|
|
fs:field(0.75, 1.25, 3.25, 1, "w_amount", S("Desired amount:"))
|
|
fs:button(4, 1, 3.25, 1, "withdraw", S("Get !"))
|
|
fs:label(1, 2.25, S("Or deposit your coins to credit your account:"))
|
|
fs:list(1,3,6,1, "nodemeta:"..spos, "main")
|
|
fs:list(0,4.25, 8,4, "current_player", "main")
|
|
fs("listring[current_player;main]"..
|
|
"listring[nodemeta:"..spos..";main]"
|
|
)
|
|
fs:label(0,9.75, msg)
|
|
end
|
|
fs:button(0,8.75, 2,1, "logout", S("Log Out"))
|
|
end
|
|
|
|
local function info_fs(fs, p_name)
|
|
local balance = exchange:get_balance(p_name)
|
|
|
|
fs:size(4,3)
|
|
|
|
if balance then
|
|
fs:label(0.5,0.5, S("Balance: @1", balance))
|
|
else
|
|
fs:label(0.5,0.5, S("You don't have an account."))
|
|
end
|
|
|
|
fs:button(1,2, 2,1, "logout", S("Log Out"))
|
|
end
|
|
|
|
|
|
local function wire_fs(fs, p_name)
|
|
local balance = exchange:get_balance(p_name)
|
|
|
|
fs:size(4,5)
|
|
|
|
if balance then
|
|
-- To detect duplicate/stale form submission
|
|
fs:field(-100, -100, 0,0, "trans_id", "", unique())
|
|
|
|
fs:label(0.50,0.325, S("Balance: @1", balance))
|
|
fs:field(0.75,1.750, 3,1, "recipient", S("Send to:"), "")
|
|
fs:field(0.75,3.000, 3,1, "amount", S("Amount"), "")
|
|
|
|
fs:button(0,4.25, 2,1, "logout", S("Log Out"))
|
|
fs:button(2,4.25, 2,1, "send", S("Send"))
|
|
else
|
|
fs:button(0,4, 2,1, "logout", S("Back"))
|
|
fs:label(0.5,0.5, S("You don't have an account."))
|
|
end
|
|
end
|
|
|
|
|
|
local function send_fs(fs, p_name, receiver, amt_str)
|
|
fs:size(10,3)
|
|
|
|
fs:button(4,2, 2,1, "wire", S("Back"))
|
|
|
|
local amt = tonumber(amt_str)
|
|
local msg = nil
|
|
|
|
if not amt or amt <= 0 then
|
|
msg = S("Invalid transfer amount.")
|
|
else
|
|
local succ, err = exchange:transfer_credits(p_name, receiver, amt)
|
|
|
|
if not succ then
|
|
msg = "Error: " .. err
|
|
else
|
|
msg = "Successfully sent " .. amt ..
|
|
" credits to " .. receiver .. "."
|
|
end
|
|
end
|
|
|
|
fs:label(0.5,0.5, msg)
|
|
end
|
|
|
|
|
|
local function log_fs(fs, p_name)
|
|
fs:size(14,8)
|
|
|
|
fs:label(0,0, S("Transaction Log"))
|
|
|
|
fs:element("tablecolumns", "text", "text")
|
|
|
|
fs("table[0,0.75;13.75,6.75;log_table;Time,Message")
|
|
for _, entry in ipairs(exchange:player_log(p_name)) do
|
|
fs(","):escape_list(entry.Time, entry.Message)
|
|
end
|
|
fs("]")
|
|
|
|
fs:button(6,7.5, 2,1, "logout", S("Log Out"))
|
|
end
|
|
|
|
|
|
local function main_menu_fs(fs, p_name)
|
|
fs:size(8,2)
|
|
fs:button(0,0.125, 4,1, "withdraw", S("Cash deposit and withdrawal"))
|
|
fs:button(4,0.125, 2,1, "info", S("Account Info"))
|
|
fs:button(6,0.125, 2,1, "wire", S("Wire Monies"))
|
|
fs:button(0.50, 1.125, 7, 1, "transaction_log", S("Transaction Log"))
|
|
end
|
|
|
|
|
|
local function show_atm_form(fs_fn, p_name, ...)
|
|
local fs = formlib.Builder()
|
|
fs_fn(fs, p_name, ...)
|
|
minetest.show_formspec(p_name, atm_form, tostring(fs))
|
|
end
|
|
|
|
|
|
local trans_ids = {}
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= atm_form then return end
|
|
if fields.quit then return true end
|
|
|
|
local p_name = player:get_player_name()
|
|
|
|
local this_id = tonumber(fields.trans_id)
|
|
|
|
if this_id and trans_ids[p_name] and this_id <= trans_ids[p_name] then
|
|
-- Ignore duplicate/stale form submittal
|
|
return true
|
|
end
|
|
|
|
trans_ids[p_name] = this_id
|
|
|
|
if fields.logout then
|
|
show_atm_form(main_menu_fs, p_name)
|
|
elseif fields.info then
|
|
show_atm_form(info_fs, p_name)
|
|
elseif fields.wire then
|
|
show_atm_form(wire_fs, p_name)
|
|
elseif fields.withdraw then
|
|
show_atm_form(withdraw_fs, p_name, fields and fields.w_amount)
|
|
elseif fields.send then
|
|
show_atm_form(send_fs, p_name, fields.recipient, fields.amount)
|
|
elseif fields.transaction_log then
|
|
show_atm_form(log_fs, p_name)
|
|
end
|
|
|
|
return true
|
|
end)
|
|
|
|
|
|
minetest.register_node("global_exchange:atm_bottom", {
|
|
description = "ATM",
|
|
inventory_image = "global_exchange_atm_icon.png",
|
|
wield_image = "global_exchange_atm_hi_front.png",
|
|
drawtype = "nodebox",
|
|
tiles = {
|
|
"global_exchange_atm_lo_top.png",
|
|
"global_exchange_atm_side.png",
|
|
"global_exchange_atm_side.png",
|
|
"global_exchange_atm_side.png",
|
|
"global_exchange_atm_back.png^[transform2",
|
|
"global_exchange_atm_lo_front.png",
|
|
},
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
is_ground_content = false,
|
|
stack_max = 1,
|
|
light_source = 3,
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
}
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.500, -0.500, -0.5000, 0.500, 0.500, 0.50},
|
|
{-0.500, 0.500, -0.5000, -0.375, 1.125, -0.25},
|
|
{ 0.375, 0.500, -0.5000, 0.500, 1.125, -0.25},
|
|
{-0.500, 0.500, -0.2500, 0.500, 1.500, 0.50},
|
|
{-0.500, 1.125, -0.4375, -0.375, 1.250, -0.25},
|
|
{ 0.375, 1.125, -0.4375, 0.500, 1.250, -0.25},
|
|
{-0.500, 1.250, -0.3750, -0.375, 1.375, -0.25},
|
|
{ 0.375, 1.250, -0.3750, 0.500, 1.375, -0.25},
|
|
{-0.500, 1.375, -0.3125, -0.375, 1.500, -0.25},
|
|
{ 0.375, 1.375, -0.3125, 0.500, 1.500, -0.25},
|
|
},
|
|
},
|
|
groups = {cracky=2, atm = 1},
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
local under = pointed_thing.under
|
|
local pos
|
|
if minetest.registered_items[minetest.get_node(under).name].buildable_to then
|
|
pos = under
|
|
else
|
|
pos = pointed_thing.above
|
|
end
|
|
if minetest.is_protected(pos, placer:get_player_name()) and
|
|
not minetest.check_player_privs(placer, "protection_bypass") then
|
|
minetest.record_protection_violation(pos, placer:get_player_name())
|
|
return itemstack
|
|
end
|
|
local def = minetest.registered_nodes[minetest.get_node(pos).name]
|
|
if not def or not def.buildable_to then
|
|
minetest.remove_node(pos)
|
|
return itemstack
|
|
end
|
|
local dir = minetest.dir_to_facedir(placer:get_look_dir())
|
|
local pos2 = {x = pos.x, y = pos.y + 1, z = pos.z}
|
|
local def2 = minetest.registered_nodes[minetest.get_node(pos2).name]
|
|
if not def2 or not def2.buildable_to then
|
|
return itemstack
|
|
end
|
|
minetest.set_node(pos, {name = "global_exchange:atm_bottom", param2 = dir})
|
|
minetest.set_node(pos2, {name = "global_exchange:atm_top", param2 = dir})
|
|
if not minetest.setting_getbool("creative_mode") then
|
|
itemstack:take_item()
|
|
return itemstack
|
|
end
|
|
end,
|
|
can_dig = function(pos,player)
|
|
local meta = minetest.get_meta(pos);
|
|
local inv = meta:get_inventory()
|
|
return inv:is_empty("main")
|
|
end,
|
|
on_destruct = function(pos)
|
|
local pos2 = {x = pos.x, y = pos.y + 1, z = pos.z}
|
|
local n2 = minetest.get_node(pos2)
|
|
if minetest.get_item_group(n2.name, "atm") == 2 then
|
|
minetest.remove_node(pos2)
|
|
end
|
|
end,
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("infotext", "ATM")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("main", 6)
|
|
end,
|
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
local itname = stack:get_name()
|
|
if coins_convert[itname] ~= nil then
|
|
return stack:get_count()
|
|
end
|
|
return 0
|
|
end,
|
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
return stack:get_count()
|
|
end,
|
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
local itname = stack:get_name()
|
|
if coins_convert[itname] ~= nil then
|
|
local p_name = player:get_player_name()
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
local nb = stack:get_count()
|
|
local amount = coins_convert[itname] * nb
|
|
local succ, msg = exchange:give_credits(p_name, amount, S("Cash deposit (+@1)", amount))
|
|
if succ then
|
|
inv:set_stack(listname, index, nil)
|
|
minetest.log("action", p_name.." put "..nb.." "..stack:get_name() .. " to ATM at " .. minetest.pos_to_string(pos))
|
|
show_atm_form(withdraw_fs, p_name)
|
|
--minetest.show_formspec(p_name, atm_form, deposit_fs(p_name))
|
|
else
|
|
minetest.log("error", p_name.." want to put "..nb.." "..stack:get_name().." to ATM at ".. minetest.pos_to_string(pos).." but: "..msg)
|
|
end
|
|
end
|
|
end,
|
|
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
minetest.log("action", player:get_player_name().." take "..stack:get_count().." "..stack:get_name().." from ATM at "..minetest.pos_to_string(pos))
|
|
end,
|
|
on_rightclick = function(pos, _, clicker)
|
|
local p_name = clicker:get_player_name()
|
|
atm_pos[p_name] = pos
|
|
minetest.sound_play("atm_beep", {pos = pos, gain = 0.3, max_hear_distance = 5})
|
|
show_atm_form(main_menu_fs, clicker:get_player_name())
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("global_exchange:atm_top", {
|
|
drawtype = "nodebox",
|
|
tiles = {
|
|
"global_exchange_atm_hi_top.png",
|
|
"global_exchange_atm_side.png",--not visible anyway
|
|
"global_exchange_atm_side.png",
|
|
"global_exchange_atm_side.png",
|
|
"global_exchange_atm_back.png",
|
|
"global_exchange_atm_hi_front.png",
|
|
},
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
is_ground_content = false,
|
|
light_source = 3,
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.500, -0.500, -0.5000, -0.375, 0.125, -0.25},
|
|
{ 0.375, -0.500, -0.5000, 0.500, 0.125, -0.25},
|
|
{-0.500, -0.500, -0.2500, 0.500, 0.500, 0.50},
|
|
{-0.500, 0.125, -0.4375, -0.375, 0.250, -0.25},
|
|
{ 0.375, 0.125, -0.4375, 0.500, 0.250, -0.25},
|
|
{-0.500, 0.250, -0.3750, -0.375, 0.375, -0.25},
|
|
{ 0.375, 0.250, -0.3750, 0.500, 0.375, -0.25},
|
|
{-0.500, 0.375, -0.3125, -0.375, 0.500, -0.25},
|
|
{ 0.375, 0.375, -0.3125, 0.500, 0.500, -0.25},
|
|
}
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {0, 0, 0, 0, 0, 0},
|
|
},
|
|
groups = {
|
|
atm = 2,
|
|
not_in_creative_inventory = 1
|
|
},
|
|
})
|
|
|
|
minetest.register_craft( {
|
|
output = "global_exchange:atm",
|
|
recipe = {
|
|
{ "default:stone", "default:stone", "default:stone" },
|
|
{ "default:stone", "default:gold_ingot", "default:stone" },
|
|
{ "default:stone", "default:stone", "default:stone" },
|
|
}
|
|
})
|
|
|
|
minetest.register_alias("global_exchange:atm", "global_exchange:atm_bottom")
|
|
-- vim:set ts=4 sw=4 noet:
|