commit ce3f17ca3507a105755106d782ae39b31d37ba40 Author: crabman77 Date: Tue May 24 22:34:56 2016 +0200 first commit diff --git a/api.txt b/api.txt new file mode 100644 index 0000000..369e00c --- /dev/null +++ b/api.txt @@ -0,0 +1,62 @@ + + +table minercantile.stock + table minercantile.stock.items + items stock + int minercantile.stock.money + money stock + + +table minercantile.shop + function minercantile.shop.get_money() + return found money + + function minercantile.shop.give_money(amount, bool) + param amount:amount of money, bool:save file + add money + + function minercantile.shop.take_money(amount, bool) + param amount:amount of money, bool:save file + remove money + + + +files + minercantile_stock.txt + table money and items + + minercantile_stock_base.txt + table items defined by default + + + +wallets + table minercantile.wallets[player] + int money + table transactions + + table minercantile.wallet + function minercantile.wallet.load_wallet(name) + load player's money + + function minercantile.wallet.save_wallet(name) + save player's money + + function minercantile.wallet.get_money(name) + return player's money + + function minercantile.wallet.give_money(name, amount, transaction) + add money + + function minercantile.wallet.take_money(name, amount, transaction) + remove money + + function minercantile.wallet.get_transactions(name) + return player's transactions + + function minercantile.add_transactions(name, new_transaction) + + + function minercantile.send_money(sender, receiver, amount) + send money from sender to receiver + diff --git a/change.lua b/change.lua new file mode 100644 index 0000000..06278d1 --- /dev/null +++ b/change.lua @@ -0,0 +1,110 @@ + +--[[ +"maptools:copper_coin" +"maptools:silver_coin" +"maptools:gold_coin" + +100 pc = 1pa, 100pa = 1po +--]] + +local convertion = { ["maptools:copper_coin"] = 1, ["maptools:silver_coin"]=100, ["maptools:gold_coin"]=1000} + +local function get_bancomatic_formspec(pos, name) + local spos = pos.x .. "," .. pos.y .. "," .. pos.z + local formspec = + "size[8,9]label[3.35,0;Bancomatic]" .. + "label[0,0;Your money:"..minercantile.wallet.get_money(name).."$]" .. + "label[2,1;Put your coins to convert on your wallet]" .. + + "image[0,1.5;1,1;maptools_gold_coin.png]" .. + "label[1,1.7;= "..convertion["maptools:gold_coin"].."$]" .. + "image[0,2.5;1,1;maptools_silver_coin.png]" .. + "label[1,2.7;= "..convertion["maptools:silver_coin"].."$]" .. + "image[0,3.5;1,1;maptools_copper_coin.png]" .. + "label[1,3.7;= "..convertion["maptools:copper_coin"].."$]" .. + + "list[nodemeta:" .. spos .. ";main;3.5,2.5;1,1;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[nodemeta:" .. spos .. ";main]" .. + "listring[current_player;main]" --.. + --default.get_hotbar_bg(0,4.85) + return formspec +end + + + +--change money. +minetest.register_node("minercantile:bancomatic", { + description = "Bancomatic", + tiles = { + "minercantile_bancomatic_back.png", + "minercantile_bancomatic_back.png", + "minercantile_bancomatic_side.png", + "minercantile_bancomatic_side.png", + "minercantile_bancomatic_back.png", + "minercantile_bancomatic_front.png", + }, + --top, bottom, right, left, back, front + paramtype2 = "facedir", + --groups = {choppy = 2, oddly_breakable_by_hand = 2}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Bancomatic") + local inv = meta:get_inventory() + inv:set_size("main", 1 * 1) + end, + can_dig = function(pos,player) + local name = player:get_player_name() + return (minetest.check_player_privs(name, {protection_bypass = true}) or minetest.check_player_privs(name, {server = true})) + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local item = stack:get_name() + if item == "maptools:copper_coin" or item == "maptools:silver_coin" or item == "maptools:gold_coin" then + return stack:get_count() + end + return 0 + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + return 0 + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local item = stack:get_name() + if item == "maptools:copper_coin" or item == "maptools:silver_coin" or item == "maptools:gold_coin" then + local name = player:get_player_name() + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local nb = stack:get_count() + local amount = convertion[item]*nb + minercantile.wallet.give_money(name, amount) + inv:set_stack(listname, index, nil) + minetest.log("action", player:get_player_name() .. " put " .. stack:get_name() .. " to bancomatic at " .. minetest.pos_to_string(pos)) + minetest.show_formspec(name, "minercantile:bancomatic", get_bancomatic_formspec(pos, name)) + end + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + end, + on_rightclick = function(pos, node, clicker) + minetest.show_formspec(clicker:get_player_name(), "minercantile:bancomatic", get_bancomatic_formspec(pos, clicker:get_player_name())) + end, + on_blast = function() end, +}) + + +--nodes +minetest.register_craft({ + output = "minercantile:bancomatic", + recipe = { + {"default:wood", "default:mese", "default:wood"}, + {"default:wood", "default:mese", "default:wood"}, + {"default:wood", "default:mese", "default:wood"}, + }, +}) + diff --git a/depends.txt b/depends.txt new file mode 100755 index 0000000..48b7040 --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +default +unified_inventory? diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..aab857e --- /dev/null +++ b/init.lua @@ -0,0 +1,775 @@ +minercantile = {} + +--path +minercantile.path = minetest.get_worldpath() +minercantile.path_wallet = minercantile.path.. "/minercantile_wallet/" +minercantile.file_stock_base = minercantile.path.."/minercantile_stock_base.txt" +minercantile.file_stock = minercantile.path.."/minercantile_stock.txt" +minetest.mkdir(minercantile.path_wallet) + +--items +minercantile.stock_base = {} +minercantile.stock = {} -- table saved money, items list +minercantile.shop = {} +minercantile.shop.items_inventory = {} +minercantile.stock.items = {} +minercantile.stock.money = 10000 + +--functions specific to wallet +minercantile.wallet = {} +-- table players wallets +minercantile.wallets = {} +--load money +dofile(minetest.get_modpath("minercantile") .. "/wallets.lua") +dofile(minetest.get_modpath("minercantile") .. "/change.lua") +local shop = {} --formspec temporary variables +local shop_buy = {} +local shop_items_nb +--function save items_base +function minercantile.save_stock_base() + local input, err = io.open(minercantile.file_stock_base, "w") + if input then + input:write(minetest.serialize(minercantile.stock_base)) + input:close() + else + minetest.log("error", "open(" .. minercantile.file_stock_base .. ", 'w') failed: " .. err) + end +end + + +--function load items_base from file +function minercantile.load_stock_base() + local file = io.open(minercantile.file_stock_base, "r") + if file then + local data = minetest.deserialize(file:read("*all")) + file:close() + if data and type(data) == "table" then + minercantile.stock_base = table.copy(data) + end + end +end + + +--function save stock items +function minercantile.save_stock() + local input, err = io.open(minercantile.file_stock, "w") + if input then + input:write(minetest.serialize(minercantile.stock)) + input:close() + else + minetest.log("error", "open(" .. minercantile.file_stock .. ", 'w') failed: " .. err) + end + minercantile.set_items_inventory() +end + + +--function load stock items from file +function minercantile.load_stock() + local file = io.open(minercantile.file_stock, "r") + if file then + local data = minetest.deserialize(file:read("*all")) + file:close() + if data and type(data) == "table" then + if data.money then + minercantile.stock.money = data.money + end + if data.items then + minercantile.stock.items = table.copy(data.items) + end + minercantile.set_items_inventory() + return + end + end + if minercantile.stock_base then + minercantile.stock.items = table.copy(minercantile.stock_base) + end + minercantile.set_items_inventory() +end + + +function minercantile.shop.get_money() + return (minercantile.stock.money or 0) +end + + +function minercantile.shop.take_money(money, saving) + minercantile.stock.money = minercantile.shop.get_money() - money + if minercantile.shop.get_money() < 0 then + minercantile.stock.money = 0 + end + if saving then + minercantile.save_stock() + end +end + + +function minercantile.shop.give_money(money, saving) + minercantile.stock.money = minercantile.shop.get_money() + money + if saving then + minercantile.save_stock() + end +end + + +-- sell fonction +function minercantile.calcul_prices(item, object) + local price = nil + local money = minercantile.shop.get_money() + if not minercantile.stock.items[item] then + minercantile.stock.items[item] = {nb=1000} --FIXME random nb + --minercantile.save_stock() + end + + if minercantile.stock.items[item].price ~= nil then -- if defined price + price = math.ceil(minercantile.stock.items[item].price) + elseif object == "sell" then + local nb = minercantile.stock.items[item].nb + price = math.ceil((((money/2)/nb) - 0.49)) + elseif object == "buy" then + local nb = minercantile.stock.items[item].nb + price = math.ceil((((money/2)/nb) + 0.49)) + end + if price < 1 then price = 1 end + return price +end + + +function minercantile.get_formspec_shop_admin_shop(pos, node_name, name) + if not shop[name] then + shop[name] = {} + end + shop[name].pos = pos + shop[name].node_name = node_name + + local formspec = {"size[6,6]label[2.2,0;Shop Admin]button[4.5,0;1.5,1;shop;Shop]"} + local isnode = minetest.get_node_or_nil(pos) + if not isnode or isnode.name ~= node_name then return end + local meta = minetest.get_meta(pos) + + local isopen = meta:get_int("open") or 0 + if isopen == 1 then + table.insert(formspec, "label[1,1;Is Open: Yes]button[3.5,0.8;1.5,1;open_close;No]") + else + table.insert(formspec, "label[1,1;Is Open: No]button[3.5,0.8;1.5,1;open_close;Yes]") + end + + local always_open = meta:get_int("always_open") or 0 + if always_open == 1 then + table.insert(formspec, "label[1,2;Open 24/24: Yes]button[3.5,1.8;1.5,1;always_open;No]") + else + table.insert(formspec, "label[1,2;Open 24/24: No]button[3.5,1.8;1.5,1;always_open;Yes]") + end + + table.insert(formspec, "button_exit[2.4,5.3;1.5,1;close;Close]") + return table.concat(formspec) +end + + +function minercantile.set_items_inventory() + local count = 0 + for Index, Value in pairs(minercantile.stock.items) do + count = count + 1 + end + if shop_items_nb ~= count then + shop_items_nb = count + minercantile.shop.items_inventory = {} + for n, def in pairs(minercantile.stock.items) do + local item = minetest.registered_items[n] + if item then + table.insert(minercantile.shop.items_inventory, n) + end + end + table.sort(minercantile.shop.items_inventory) + end +end + + +local function set_pages_by_search(name, search) + shop_buy[name].page = 1 + shop_buy[name].search = minetest.formspec_escape(search) + shop_buy[name].items_list = {} + local match = false + for n, def in pairs(minercantile.stock.items) do + local item = minetest.registered_items[n] + if item then + if string.find(item.name, search) or (item.description and item.description ~= "" and string.find(string.lower(item.description), search)) then + table.insert(shop_buy[name].items_list, n) + --shop_buy[name].items_list[n] + end + end + end + table.sort(shop_buy[name].items_list) +end + + +local function get_shop_inventory_by_page(name) + local page = shop_buy[name].page + local search = shop_buy[name].search + local nb_items, nb_pages + local inv_list = {} + if search ~= "" then + nb_items = #shop_buy[name].items_list + nb_pages = math.ceil(nb_items/32) + if page > nb_pages then page = nb_pages end + local index = 0 + if nb_pages >1 then + index = (page*32)-32 + end + for i=1, 32 do + local item = shop_buy[name].items_list[index+i] + if not item then break end + local nb = minercantile.stock.items[item].nb + local price = minercantile.calcul_prices(item, "buy") + table.insert(inv_list, {name=item,nb=nb,price=price}) + end + else + nb_items = shop_items_nb + nb_pages = math.ceil(nb_items/32) + if page > nb_pages then page = nb_pages end + local index = 0 + if nb_pages >1 then + index = (page*32)-32 + end + for i=1, 32 do + local item = minercantile.shop.items_inventory[index+i] + if item then + local nb = minercantile.stock.items[item].nb + local price = minercantile.calcul_prices(item, "buy") + table.insert(inv_list, {name=item,nb=nb,price=price}) + else + break + end + end + + end + shop_buy[name].nb_pages = nb_pages + return inv_list +end + + +--buy +function minercantile.buy(name, item, nb, price) + local player = minetest.get_player_by_name(name) + if not player then return false end + local player_inv = player:get_inventory() + local shop_money = minercantile.shop.get_money() + local player_money = minercantile.wallet.get_money(name) + if player_money < 1 then + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;Sorry, you have not enough money]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + return false + end + + local items_nb = minercantile.stock.items[item].nb -4 + if items_nb < 1 then + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1.7,1;Sorry, shop have 0 item ..".. item.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + return false + end + + local item_can_sell = nb + if items_nb/4 < nb then + item_can_sell = items_nb/4 + end + + local price_total = math.floor(item_can_sell * price) + local player_can_buy = item_can_sell + if player_money < price_total then + player_can_buy = math.floor(player_money/price) + end + print("player_can_buy:"..dump(player_can_buy)) + local sell_price = player_can_buy * price + + + local stack = ItemStack(item.." "..player_can_buy) + --player_inv:room_for_item("main", stack) + local nn = player_inv:add_item("main", stack) + local count = nn:get_count() + if count > 0 then + minetest.spawn_item(player:getpos(), {name=item, count=count, wear=0, metadata=""}) + end + + + minercantile.stock.items[item].nb = minercantile.stock.items[item].nb - player_can_buy + minercantile.shop.give_money(sell_price, true) + + minercantile.wallet.take_money(name, sell_price, " Buy "..player_can_buy .." "..item..", price "..sell_price) + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;You buy "..player_can_buy .." "..item..", price "..sell_price.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + return true +end + +local function show_formspec_to_buy(name) + local player = minetest.get_player_by_name(name) + if not player then return end + if not shop_buy[name] then + shop_buy[name] = {page=1, search=""} + end + local formspec = {"size[10,10]bgcolor[#2A2A2A;]label[0,0;shop money:"..minercantile.shop.get_money().."$]label[4.4,0;Buy Items]"} + local inv_items = get_shop_inventory_by_page(name) + table.insert(formspec, "label[0,0.5;Your money:"..minercantile.wallet.get_money(name) .."$]") + table.insert(formspec, "label[0.2,1.4;Page: ".. shop_buy[name].page.." of ".. shop_buy[name].nb_pages.."]") + if shop_buy[name].search ~= "" then + table.insert(formspec, "label[2,1.4;Filter: ".. minetest.formspec_escape(shop_buy[name].search) .."]") + end + local x = 0.2 + local y = 2 + local j = 1 + for i=1, 32 do + local item = inv_items[i] + if item then + table.insert(formspec, "item_image_button["..x..","..y..";1,1;"..tostring(item.name)..";buttonchoice_"..tostring(item.name)..";"..item.nb.."]") + table.insert(formspec, "label["..(x)..","..(y+0.8)..";"..item.price.."$]") + else + table.insert(formspec, "image["..x..","..y..";1,1;minercantile_img_inv.png]") + end + x = x +1.2 + j = j +1 + if j > 8 then + j = 1 + x = 0.2 + y = y + 1.4 + end + end + + table.insert(formspec, "field[3.75,8.75;2.2,1;searchbox;;]") + table.insert(formspec, "image_button[5.55,8.52;.8,.8;ui_search_icon.png;searchbutton;]tooltip[searchbutton;Search]") + table.insert(formspec, "button[4,9.3;1,1;page_dec;<]") + table.insert(formspec, "button[4.9,9.3;1,1;page_inc;>]") + table.insert(formspec, "button_exit[8.2,9.3;1.5,1;choice;Close]") + minetest.show_formspec(name, "minercantile:shop_buy", table.concat(formspec)) +end + + +local function get_formspec_buy_items(name) + local item = shop_buy[name].item + local max = shop_buy[name].max + local nb = shop_buy[name].nb + local price = shop_buy[name].price + local formspec = {"size[8,6]label[3.5,0;Buy Items]"} + table.insert(formspec, "button[0.6,2;1,1;amount;-1]") + table.insert(formspec, "button[1.6,2;1,1;amount;-10]") + table.insert(formspec, "button[2.6,2;1,1;amount;-20]") + table.insert(formspec, "item_image_button[3.6,2;1,1;"..item..";buttonchoice_"..item..";"..nb.."]") + table.insert(formspec, "button[4.6,2;1,1;amount;+20]") + table.insert(formspec, "button[5.6,2;1,1;amount;+10]") + table.insert(formspec, "button[6.6,2;1,1;amount;+1]") + + table.insert(formspec, "size[8,6]label[3,3;Buy ".. nb.."x"..price.."="..nb * price.."]") + table.insert(formspec, "button[3.3,4;1.5,1;confirm;Confirm]") + table.insert(formspec, "button[0,0;1.5,1;abort;Return]") + return table.concat(formspec) +end + + + + + +-- sell +function minercantile.sell(name, item, nb, price) + local player = minetest.get_player_by_name(name) + if not player then return false end + local player_inv = player:get_inventory() + local shop_money = minercantile.shop.get_money() + + if shop_money < 1 then + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;Sorry, shop have not enough money]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + return false + end + + local items_nb = 0 + for i=1,player_inv:get_size("main") do + if player_inv:get_stack("main", i):get_name() == item then + items_nb = items_nb + player_inv:get_stack("main", i):get_count() + end + end + + if items_nb == 0 then + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1.7,1;Sorry, You have 0 item ..".. item.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + return false + end + + local item_can_sell = nb + if items_nb < nb then + item_can_sell = items_nb + end + + local price_total = math.floor(item_can_sell * price) + local shop_can_buy = item_can_sell + if (shop_money/4) < price_total then + shop_can_buy = math.floor((shop_money/4)/price) + elseif shop_money < price_total then + shop_can_buy = math.floor(shop_money/price) + end + print("shop_can_buy:"..dump(shop_can_buy)) + local sell_price = shop_can_buy * price + + for i=1,player_inv:get_size("main") do + if player_inv:get_stack("main", i):get_name() == item then + items_nb = items_nb + player_inv:get_stack("main", i):get_count() + end + end + + local stack = ItemStack(item.." "..shop_can_buy) + player_inv:remove_item("main", stack) + + minercantile.stock.items[item].nb = minercantile.stock.items[item].nb + shop_can_buy + minercantile.shop.take_money(sell_price, true) + + minercantile.wallet.give_money(name, sell_price, " Sell "..shop_can_buy .." "..item..", price "..sell_price) + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;You sell "..shop_can_buy .." "..item..", price "..sell_price.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + return true +end + + +-- show sell formspec +local function show_formspec_to_sell(name) + local player = minetest.get_player_by_name(name) + if not player then return end + local formspec = {"size[10,8]bgcolor[#2A2A2A;]label[4,0;Sell Items]"} + table.insert(formspec, "label[0,0;shop money:"..minercantile.shop.get_money().."$]") + table.insert(formspec, "label[0,0.5;Your money:"..minercantile.wallet.get_money(name) .."$]") + local player_inv = player:get_inventory() + local inv_items = {} + for i=1, player_inv:get_size("main") do + if not player_inv:get_stack("main", i):is_empty() and minetest.registered_items[player_inv:get_stack("main", i):get_name()] then + local item = player_inv:get_stack("main", i):get_name() + if not inv_items[item] then + inv_items[item] = {nb=0} + end + inv_items[item].nb = inv_items[item].nb + player_inv:get_stack("main", i):get_count() + if not inv_items[item].price then + inv_items[item].price = minercantile.calcul_prices(item, "sell") + end + end + end + shop[name] = {} + shop[name].items = table.copy(inv_items) + local x = 0.2 + local y = 1 + for n, def in pairs(inv_items) do + table.insert(formspec, "item_image_button["..x..","..y..";1,1;"..n..";buttonchoice_"..n..";"..def.nb.."]") + table.insert(formspec, "label["..(x+0.2)..","..(y+0.8)..";"..def.price.."]") + x = x +1.1 + if x > 8 then + x = 0.2 + y = y + 1.4 + end + end + table.insert(formspec, "button_exit[1.3,7.3;1.5,1;choice;Close]") + minetest.show_formspec(name, "minercantile:shop_sell", table.concat(formspec)) +end + + +local function get_formspec_sell_items(name) + local item = shop[name].item + local max = shop[name].max + local nb = shop[name].nb + local price = shop[name].price + local formspec = {"size[8,6]label[3.5,0;Sell Items]"} + + table.insert(formspec, "button[0.6,2;1,1;amount;-1]") + table.insert(formspec, "button[1.6,2;1,1;amount;-10]") + table.insert(formspec, "button[2.6,2;1,1;amount;-20]") + --table.insert(formspec, "label[3.7,5.2;"..tostring(nb).."]") + table.insert(formspec, "item_image_button[3.6,2;1,1;"..item..";buttonchoice_"..item..";"..nb.."]") + table.insert(formspec, "button[4.6,2;1,1;amount;+20]") + table.insert(formspec, "button[5.6,2;1,1;amount;+10]") + table.insert(formspec, "button[6.6,2;1,1;amount;+1]") + + table.insert(formspec, "size[8,6]label[3,3;sell ".. nb.."x"..price.."="..nb * price.."]") + table.insert(formspec, "button[3.3,4;1.5,1;confirm;Confirm]") + table.insert(formspec, "button[0,0;1.5,1;abort;Return]") + return table.concat(formspec) +end + + +local function get_formspec_welcome(name) + local formspec = {"size[6,5]label[2.6,0;Shop]"} + table.insert(formspec, "image[1,1;5,1.25;minercantile_shop_welcome.png]") + table.insert(formspec, "button[1.3,3.3;1.5,1;choice;Buy]") + table.insert(formspec, "button[3.5,3.3;1.5,1;choice;Sell]") + return table.concat(formspec) +end + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if not name or name == "" then return end + if formname == "minercantile:shop_welcome" then + if fields["choice"] then + if fields["choice"] == "Buy" then + show_formspec_to_buy(name) + elseif fields["choice"] == "Sell" then + show_formspec_to_sell(name) + end + return + end + + + elseif formname == "minercantile:shop_buy" then + for b, n in pairs(fields) do + if string.find(b, "buttonchoice_") then + if not shop_buy[name] then + shop_buy[name] = {} + end + local item = string.sub(b, 14) + shop_buy[name].item = item + shop_buy[name].max = tonumber(n) + shop_buy[name].nb = 1 + --shop_buy[name].price = shop_buy[name].items[shop_buy[name].item].price + shop_buy[name].price = minercantile.calcul_prices(item, "buy") + minetest.show_formspec(name, "minercantile:shop_buy_items", get_formspec_buy_items(name)) + return + end + end + + + if fields["quit"] then + return + elseif fields["searchbutton"] then + local search = string.sub(string.lower(fields["searchbox"]), 1, 14) + set_pages_by_search(name, search) + elseif fields["page_inc"] then + if shop_buy[name].page < shop_buy[name].nb_pages then + shop_buy[name].page = shop_buy[name].page+1 + end + elseif fields["page_dec"] then + if shop_buy[name].page > 1 then + shop_buy[name].page = shop_buy[name].page-1 + end + end + show_formspec_to_buy(name) + elseif formname == "minercantile:shop_buy_items" then + if fields["amount"] then + local inc = tonumber(fields["amount"]) + if inc ~= nil then + shop_buy[name].nb = shop_buy[name].nb + inc + end + if shop_buy[name].nb > shop_buy[name].max then + shop_buy[name].nb = shop_buy[name].max + end + if shop_buy[name].nb > 99 then + shop_buy[name].nb = 99 + end + if shop_buy[name].nb < 1 then + shop_buy[name].nb = 1 + end + elseif fields["abort"] then + show_formspec_to_buy(name) + return + elseif fields["confirm"] then + minercantile.buy(name, shop_buy[name].item, shop_buy[name].nb, shop_buy[name].price) + return + elseif fields["quit"] then + shop_buy[name] = nil + return + end + minetest.show_formspec(name, "minercantile:shop_buy_items", get_formspec_buy_items(name)) + elseif formname == "minercantile:shop_buy_confirm" then + + + + + + + elseif formname == "minercantile:shop_sell" then + for b, n in pairs(fields) do + if string.find(b, "buttonchoice_") then + if not shop[name] then + shop[name] = {} + end + shop[name].item = string.sub(b, 14) + shop[name].max = tonumber(n) + shop[name].nb = 1 + shop[name].price = shop[name].items[shop[name].item].price + minetest.show_formspec(name, "minercantile:shop_sell_items", get_formspec_sell_items(name)) + break + end + end + return + elseif formname == "minercantile:shop_sell_items" then + if fields["amount"] then + local inc = tonumber(fields["amount"]) + if inc ~= nil then + shop[name].nb = shop[name].nb + inc + end + if shop[name].nb > shop[name].max then + shop[name].nb = shop[name].max + end + if shop[name].nb > 99 then + shop[name].nb = 99 + end + if shop[name].nb < 1 then + shop[name].nb = 1 + end + elseif fields["abort"] then + show_formspec_to_sell(name) + return + elseif fields["confirm"] then + minercantile.sell(name, shop[name].item, shop[name].nb, shop[name].price) + return + elseif fields["quit"] then + shop[name] = nil + return + end + minetest.show_formspec(name, "minercantile:shop_sell_items", get_formspec_sell_items(name)) + elseif formname == "minercantile:confirmed" then + if fields["return"] then + show_formspec_to_sell(name) + end + return + + + + + elseif formname == "minercantile:shop_admin_shop" then + if fields["quit"] then + shop[name] = nil + return + elseif fields["shop"] then + minetest.show_formspec(name, "minercantile:shop_welcome", get_formspec_welcome(name)) + return + end + local pos = shop[name].pos + local node_name = shop[name].node_name + local isnode = minetest.get_node_or_nil(pos) + if not isnode or isnode.name ~= node_name then return end --FIXME + local meta = minetest.get_meta(pos) + + if fields["open_close"] then + local open = 0 + if fields["open_close"] == "Yes" then + open = 1 + end + meta:set_int("open", open) + elseif fields["always_open"] then + local always_open = 0 + if fields["always_open"] == "Yes" then + always_open = 1 + end + meta:set_int("always_open", always_open) + end + minetest.show_formspec(name, "minercantile:shop_admin_shop", minercantile.get_formspec_shop_admin_shop(pos, node_name, name)) + end +end) + + + + +--Barter shop. +minetest.register_node("minercantile:shop", { + description = "Barter Shop", + tiles = {"minercantile_shop.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + paramtype2 = "facedir", + drawtype = "mesh", + mesh = "minercantile_shop.obj", + paramtype = "light", + --visual_scale = 0.5, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Barter Shop") + meta:set_int("open", 0) + meta:set_int("always_open", 0) + end, + can_dig = function(pos,player) + --return minetest.get_player_privs(player:get_player_name())["money_admin"] --FIXME + --if minetest.check_player_privs(name, {protection_bypass = true}) or minetest.check_player_privs(name, {server = true}) then + return true + end, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + local name = player:get_player_name() + if not name or name == "" then return end + if minetest.check_player_privs(name, {protection_bypass = true}) or minetest.check_player_privs(name, {server = true}) then + minetest.show_formspec(name, "minercantile:shop_admin_shop", minercantile.get_formspec_shop_admin_shop(pos, node.name, name)) + else + local meta = minetest.get_meta(pos) + local isopen = meta:get_int("open") + if (isopen and isopen == 1) then + local always_open = meta:get_int("always_open") + local tod = (minetest.get_timeofday() or 0) * 24000 + if always_open == 1 or (tod > 4500 and tod < 19500) then --FIXME check tod 8h-21h + minetest.show_formspec(name, "minercantile:shop_welcome", get_formspec_welcome(name)) + else + minetest.show_formspec(name, "minercantile:closed", "size[6,3]label[2.6,0;Shop]label[1.2,1;Sorry shop is only open 7h-21h]button_exit[2.3,2.1;1.5,1;close;Close]") + end + else + minetest.show_formspec(name, "minercantile:closed", "size[6,3]label[2.6,0;Shop]label[1.7,1;Sorry shop is closed]button_exit[2.3,2.1;1.5,1;close;Close]") + end + end + end, +}) + + +--nodes +minetest.register_craft({ + output = "minercantile:shop", + recipe = { + {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:mese", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, + }, +}) + +--[[ +if (minetest.get_modpath("unified_inventory")) then + unified_inventory.register_button("shop_admin", { + type = "image", + image = "minercantile_shop.png", --FIXME change texture + tooltip = "Admin Shop", + show_with = "server", + action = function(player) + local name = player:get_player_name() + if not name then return end + local formspec = minercantile.get_formspec_shop_admin(name) + minetest.show_formspec(name, "minercantile:shop_admin", formspec) + end, + }) +else + minetest.register_chatcommand("shop_admin",{ + params = "", + description = "Show admin shop formspec", + privs = {server = true}, + func = function (name, params) + local formspec = minercantile.get_formspec_shop_admin(name) + minetest.show_formspec(name, "minercantile:shop_admin", formspec) + end, + }) +end +--]] + +minetest.register_chatcommand("shop_addmoney",{ + params = "money", + description = "give money to the shop", + privs = {server = true}, + func = function(name, param) + local amount = tonumber(param) + if amount == nil then + minetest.chat_send_player(name, "invalid, you must add amount at param") + return + end + minercantile.shop.give_money(amount, true) + minetest.chat_send_player(name, "you add "..amount.. ", new total:".. minercantile.shop.get_money()) + end, +}) + + +minetest.register_chatcommand("shop_delmoney",{ + params = "money", + description = "del money to the shop", + privs = {server = true}, + func = function(name, param) + local amount = tonumber(param) + if (amount == nil ) then + minetest.chat_send_player(name, "invalid, you must add amount at param") + return + end + minercantile.shop.take_money(amount, true) + minetest.chat_send_player(name, "you delete "..amount.. ", new total:".. minercantile.shop.get_money()) + end, +}) + + +--load items base and available +minercantile.load_stock_base() +minercantile.load_stock() +minetest.log("action", "[minercantile] Loaded") diff --git a/models/minercantile_shop.obj b/models/minercantile_shop.obj new file mode 100644 index 0000000..005b7f5 --- /dev/null +++ b/models/minercantile_shop.obj @@ -0,0 +1,329 @@ +# Blender v2.77 (sub 0) OBJ File: 'caisse1.blend' +# www.blender.org +mtllib caisse.mtl +o Cube +v -0.145637 -0.038666 0.253085 +v -0.145637 0.055666 0.253085 +v -0.205832 -0.038666 0.253010 +v -0.205832 0.055666 0.253010 +v -0.315176 0.055666 0.239985 +v -0.036259 0.055666 0.240241 +v -0.315176 0.167488 0.239985 +v -0.036259 0.167488 0.240241 +v -0.145637 -0.038666 0.298973 +v -0.145637 0.055666 0.298973 +v -0.205832 -0.038666 0.299048 +v -0.205832 0.055666 0.299048 +v -0.315176 0.055666 0.312073 +v -0.036259 0.055666 0.311817 +v -0.315176 0.167488 0.312073 +v -0.036259 0.167488 0.311817 +v -0.205860 0.055666 0.276029 +v -0.205860 -0.038666 0.276029 +v -0.145664 0.055666 0.276029 +v -0.145664 -0.038666 0.276029 +v -0.315226 0.055666 0.276029 +v -0.036308 0.055666 0.276029 +v -0.315226 0.167488 0.276029 +v -0.036308 0.167488 0.276029 +v -0.363016 -0.499073 -0.412719 +v -0.363016 -0.499073 0.391858 +v -0.363016 -0.198782 -0.412720 +v -0.363016 0.006452 0.391858 +v -0.363016 -0.295672 -0.412719 +v -0.331280 -0.277247 -0.380984 +v -0.363016 -0.258822 -0.412719 +v -0.363016 -0.295672 0.391858 +v -0.331280 -0.277247 0.360122 +v -0.363016 -0.258822 0.391858 +v -0.348973 -0.486905 -0.412719 +v -0.348973 -0.307840 -0.412719 +v -0.348973 -0.486905 -0.402216 +v -0.348973 -0.307840 -0.402216 +v -0.340920 -0.478646 -0.402216 +v -0.340920 -0.316099 -0.402216 +v -0.340920 -0.478646 -0.422506 +v -0.340920 -0.316099 -0.422506 +v -0.363016 -0.499073 0.163401 +v -0.363016 0.006452 0.163401 +v -0.363016 -0.258822 0.163401 +v -0.331280 -0.277247 0.149687 +v -0.363016 -0.295672 0.163401 +v 0.441561 -0.499073 -0.412720 +v 0.441561 -0.499073 0.391858 +v 0.441561 -0.198782 -0.412720 +v 0.441561 0.006452 0.391858 +v 0.441561 -0.295672 -0.412720 +v 0.409825 -0.277247 -0.380984 +v 0.441561 -0.258822 -0.412720 +v 0.441561 -0.295672 0.391858 +v 0.409825 -0.277247 0.360122 +v 0.441561 -0.258822 0.391858 +v 0.427518 -0.486905 -0.412720 +v 0.427518 -0.307840 -0.412720 +v 0.427518 -0.486905 -0.402216 +v 0.427518 -0.307840 -0.402216 +v 0.419465 -0.478646 -0.402216 +v 0.419465 -0.316099 -0.402216 +v 0.419465 -0.478646 -0.422507 +v 0.419465 -0.316099 -0.422507 +v 0.441561 -0.499073 0.163401 +v 0.441561 0.006452 0.163401 +v 0.441561 -0.258822 0.163401 +v 0.409825 -0.277247 0.149687 +v 0.441561 -0.295672 0.163401 +v 0.039272 -0.499073 -0.412719 +v 0.039273 -0.499073 0.391858 +v 0.039272 -0.198782 -0.412719 +v 0.039273 0.006452 0.391858 +v 0.039273 -0.295672 0.391858 +v 0.039273 -0.277247 0.360122 +v 0.039273 -0.258822 0.391858 +v 0.039272 -0.295672 -0.412719 +v 0.039272 -0.277247 -0.380984 +v 0.039272 -0.258822 -0.412719 +v 0.039272 -0.486905 -0.412719 +v 0.039272 -0.307840 -0.412719 +v 0.039272 -0.486905 -0.402216 +v 0.039272 -0.307840 -0.402216 +v 0.039272 -0.478646 -0.402216 +v 0.039272 -0.316099 -0.402216 +v 0.039272 -0.478646 -0.422506 +v 0.039272 -0.316099 -0.422506 +v 0.039272 0.006452 0.163401 +v 0.039272 -0.499073 0.163401 +vt 0.8315 0.7650 +vt 0.8089 0.7884 +vt 0.7999 0.6861 +vt 0.8171 0.6838 +vt 0.7237 0.7869 +vt 0.7577 0.6795 +vt 0.9264 0.8025 +vt 0.6024 0.8025 +vt 0.5608 0.8025 +vt 0.6024 0.9324 +vt 0.5608 0.9324 +vt 0.7043 0.7632 +vt 0.6008 0.7757 +vt 0.9264 0.9324 +vt 0.9683 0.8025 +vt 0.9683 0.9324 +vt 0.9265 0.9743 +vt 0.6024 0.9740 +vt 0.9280 0.7771 +vt 0.7355 0.6719 +vt 0.7999 0.6861 +vt 0.8089 0.7884 +vt 0.7577 0.6795 +vt 0.7237 0.7869 +vt 0.6024 0.8025 +vt 0.9264 0.8025 +vt 0.6024 0.9324 +vt 0.9264 0.8025 +vt 0.9264 0.9324 +vt 0.6024 0.9324 +vt 0.6024 0.8025 +vt 0.9264 0.9324 +vt 0.7608 0.2153 +vt 0.8893 0.2612 +vt 0.8197 0.4560 +vt 0.6912 0.4101 +vt 0.4114 0.4212 +vt 0.4466 0.3227 +vt 0.5572 0.3622 +vt 0.5220 0.4607 +vt 0.3527 0.5851 +vt 0.3986 0.4567 +vt 0.5093 0.4962 +vt 0.4634 0.6247 +vt 0.3984 0.4366 +vt 0.5003 0.4730 +vt 0.6268 0.1674 +vt 0.7253 0.2026 +vt 0.6557 0.3974 +vt 0.7431 0.2090 +vt 0.6789 0.3884 +vt 0.2372 0.0282 +vt 0.1676 0.2230 +vt 0.1638 0.2149 +vt 0.2325 0.0265 +vt 0.0678 0.2042 +vt 0.0736 0.1989 +vt 0.0792 0.1933 +vt 0.1604 0.2098 +vt 0.2284 0.0250 +vt 0.1576 0.2045 +vt 0.2252 0.0238 +vt 0.0829 0.1906 +vt 0.1515 0.1956 +vt 0.2173 0.0208 +vt 0.0929 0.1815 +vt 0.1414 0.3447 +vt 0.1324 0.3215 +vt 0.1197 0.3570 +vt 0.1093 0.3861 +vt 0.5162 0.1279 +vt 0.4637 0.6419 +vt 0.4637 0.9889 +vt 0.2354 0.9889 +vt 0.2354 0.6419 +vt 0.0832 0.0001 +vt 0.0964 0.0002 +vt 0.0798 0.0001 +vt 0.0679 0.0001 +vt 0.0728 0.0001 +vt 0.0492 0.1881 +vt 0.0306 0.2042 +vt 0.0306 0.0001 +vt 0.0492 0.0001 +vt 0.0001 0.2042 +vt 0.0002 0.0001 +vt 0.9303 0.4956 +vt 0.9999 0.3008 +vt 0.6912 0.4101 +vt 0.8197 0.4560 +vt 0.4114 0.4212 +vt 0.5220 0.4607 +vt 0.5572 0.3622 +vt 0.4466 0.3227 +vt 0.3527 0.5851 +vt 0.4634 0.6247 +vt 0.5093 0.4962 +vt 0.3986 0.4567 +vt 0.5003 0.4730 +vt 0.3984 0.4366 +vt 0.6557 0.3974 +vt 0.6789 0.3884 +vt 0.1638 0.2149 +vt 0.1676 0.2230 +vt 0.0736 0.1989 +vt 0.0678 0.2042 +vt 0.1604 0.2098 +vt 0.0792 0.1933 +vt 0.1576 0.2045 +vt 0.0829 0.1906 +vt 0.1515 0.1956 +vt 0.0929 0.1815 +vt 0.1414 0.3447 +vt 0.1324 0.3215 +vt 0.1197 0.3570 +vt 0.1093 0.3861 +vt 0.0072 0.6419 +vt 0.0072 0.9889 +vt 0.0492 0.1881 +vt 0.0306 0.2042 +vt 0.0001 0.2042 +vt 0.9303 0.4956 +vn -1.0000 0.0000 -0.0012 +vn 0.0012 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0014 +vn 0.0009 0.0000 -1.0000 +vn -1.0000 0.0000 -0.0014 +vn 0.0000 1.0000 0.0000 +vn 1.0000 0.0000 0.0012 +vn -1.0000 0.0000 0.0012 +vn 0.0013 0.0000 1.0000 +vn 1.0000 0.0000 -0.0014 +vn 0.0009 0.0000 1.0000 +vn -1.0000 0.0000 0.0014 +vn 1.0000 0.0000 -0.0012 +vn 0.0000 -0.0000 1.0000 +vn -1.0000 0.0000 -0.0000 +vn -0.5021 -0.8648 0.0000 +vn -0.5021 0.8648 0.0000 +vn 0.0000 0.8648 0.5021 +vn -0.0000 -0.8648 0.5021 +vn -0.0000 0.0000 -1.0000 +vn 1.0000 -0.0000 0.0000 +vn 0.0000 0.9420 -0.3356 +vn 0.0000 -0.8648 -0.5021 +vn -0.0000 0.8648 -0.5021 +vn 0.5021 -0.8648 -0.0000 +vn 0.5021 0.8648 -0.0000 +usemtl Material +s off +f 17/1/1 4/2/1 3/3/1 18/4/1 +f 4/2/2 2/5/2 1/6/2 3/3/2 +f 2/5/3 4/2/3 5/7/3 6/8/3 +f 22/9/4 6/8/4 8/10/4 24/11/4 +f 19/12/3 2/5/3 6/8/3 22/13/3 +f 6/8/5 5/7/5 7/14/5 8/10/5 +f 5/7/6 21/15/6 23/16/6 7/14/6 +f 8/10/7 7/14/7 23/17/7 24/18/7 +f 4/2/3 17/1/3 21/19/3 5/7/3 +f 2/5/8 19/12/8 20/20/8 1/6/8 +f 17/1/9 18/4/9 11/21/9 12/22/9 +f 12/22/10 11/21/10 9/23/10 10/24/10 +f 10/24/3 14/25/3 13/26/3 12/22/3 +f 22/9/11 24/11/11 16/27/11 14/25/11 +f 19/12/3 22/13/3 14/25/3 10/24/3 +f 14/28/12 16/29/12 15/30/12 13/31/12 +f 13/26/13 15/32/13 23/16/13 21/15/13 +f 16/27/7 24/18/7 23/17/7 15/32/7 +f 12/22/3 13/26/3 21/19/3 17/1/3 +f 10/24/14 9/23/14 20/20/14 19/12/14 +f 77/33/15 74/34/15 28/35/15 34/36/15 +f 47/37/16 43/38/16 26/39/16 32/40/16 +f 44/41/16 45/42/16 34/43/16 28/44/16 +f 45/42/17 46/45/17 33/46/17 34/43/17 +f 46/45/18 47/37/18 32/40/18 33/46/18 +f 72/47/15 75/48/15 32/49/15 26/39/15 +f 75/48/19 76/50/19 33/51/19 32/49/19 +f 76/50/20 77/33/20 34/36/20 33/51/20 +f 71/52/21 25/53/21 35/54/21 81/55/21 +f 25/53/21 29/56/21 36/57/21 35/54/21 +f 35/54/22 36/57/22 38/58/22 37/59/22 +f 81/55/7 35/54/7 37/59/7 83/60/7 +f 83/60/21 37/59/21 39/61/21 85/62/21 +f 37/59/21 38/58/21 40/63/21 39/61/21 +f 85/62/3 39/61/3 41/64/3 87/65/3 +f 39/61/16 40/63/16 42/66/16 41/64/16 +f 30/67/18 29/68/18 47/37/18 46/45/18 +f 31/69/17 30/67/17 46/45/17 45/42/17 +f 27/70/16 31/69/16 45/42/16 44/41/16 +f 29/68/16 25/53/16 43/38/16 47/37/16 +f 25/53/3 71/52/3 90/71/3 43/38/3 +f 27/72/23 44/73/23 89/74/23 73/75/23 +f 40/63/7 86/76/7 88/77/7 42/66/7 +f 41/64/21 42/66/21 88/77/21 87/65/21 +f 38/58/21 84/78/21 86/76/21 40/63/21 +f 29/56/21 78/79/21 82/80/21 36/57/21 +f 36/57/3 82/80/3 84/78/3 38/58/3 +f 30/81/24 31/82/24 80/83/24 79/84/24 +f 29/56/25 30/81/25 79/84/25 78/79/25 +f 31/82/21 27/85/21 73/86/21 80/83/21 +f 44/87/7 28/35/7 74/34/7 89/88/7 +f 43/38/3 90/71/3 72/47/3 26/39/3 +f 77/33/15 57/89/15 51/90/15 74/34/15 +f 70/91/22 55/92/22 49/93/22 66/94/22 +f 67/95/22 51/96/22 57/97/22 68/98/22 +f 68/98/26 57/97/26 56/99/26 69/100/26 +f 69/100/27 56/99/27 55/92/27 70/91/27 +f 72/47/15 49/93/15 55/101/15 75/48/15 +f 75/48/19 55/101/19 56/102/19 76/50/19 +f 76/50/20 56/102/20 57/89/20 77/33/20 +f 71/52/21 81/55/21 58/103/21 48/104/21 +f 48/104/21 58/103/21 59/105/21 52/106/21 +f 58/103/16 60/107/16 61/108/16 59/105/16 +f 81/55/7 83/60/7 60/107/7 58/103/7 +f 83/60/21 85/62/21 62/109/21 60/107/21 +f 60/107/21 62/109/21 63/110/21 61/108/21 +f 85/62/3 87/65/3 64/111/3 62/109/3 +f 62/109/22 64/111/22 65/112/22 63/110/22 +f 53/113/27 69/100/27 70/91/27 52/114/27 +f 54/115/26 68/98/26 69/100/26 53/113/26 +f 50/116/22 67/95/22 68/98/22 54/115/22 +f 52/114/22 70/91/22 66/94/22 48/104/22 +f 48/104/3 66/94/3 90/71/3 71/52/3 +f 50/117/23 73/75/23 89/74/23 67/118/23 +f 63/110/7 65/112/7 88/77/7 86/76/7 +f 64/111/21 87/65/21 88/77/21 65/112/21 +f 61/108/21 63/110/21 86/76/21 84/78/21 +f 52/106/21 59/105/21 82/80/21 78/79/21 +f 59/105/3 61/108/3 84/78/3 82/80/3 +f 53/119/24 79/84/24 80/83/24 54/120/24 +f 52/106/25 78/79/25 79/84/25 53/119/25 +f 54/120/21 80/83/21 73/86/21 50/121/21 +f 67/122/7 89/88/7 74/34/7 51/90/7 +f 66/94/3 49/93/3 72/47/3 90/71/3 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..05ae3cc --- /dev/null +++ b/readme.md @@ -0,0 +1 @@ +**A minetest mod** diff --git a/textures/minercantile_bancomatic_back.png b/textures/minercantile_bancomatic_back.png new file mode 100644 index 0000000..e5efd04 Binary files /dev/null and b/textures/minercantile_bancomatic_back.png differ diff --git a/textures/minercantile_bancomatic_front.png b/textures/minercantile_bancomatic_front.png new file mode 100644 index 0000000..36f4540 Binary files /dev/null and b/textures/minercantile_bancomatic_front.png differ diff --git a/textures/minercantile_bancomatic_side.png b/textures/minercantile_bancomatic_side.png new file mode 100644 index 0000000..0bcf2f4 Binary files /dev/null and b/textures/minercantile_bancomatic_side.png differ diff --git a/textures/minercantile_img_inv.png b/textures/minercantile_img_inv.png new file mode 100644 index 0000000..99f18ff Binary files /dev/null and b/textures/minercantile_img_inv.png differ diff --git a/textures/minercantile_minecoins2.png b/textures/minercantile_minecoins2.png new file mode 100644 index 0000000..31b2699 Binary files /dev/null and b/textures/minercantile_minecoins2.png differ diff --git a/textures/minercantile_money.png b/textures/minercantile_money.png new file mode 100644 index 0000000..fc7a76d Binary files /dev/null and b/textures/minercantile_money.png differ diff --git a/textures/minercantile_shop.png b/textures/minercantile_shop.png new file mode 100644 index 0000000..f0ea80e Binary files /dev/null and b/textures/minercantile_shop.png differ diff --git a/textures/minercantile_shop_welcome.png b/textures/minercantile_shop_welcome.png new file mode 100644 index 0000000..651f0b0 Binary files /dev/null and b/textures/minercantile_shop_welcome.png differ diff --git a/wallets.lua b/wallets.lua new file mode 100644 index 0000000..ea5574d --- /dev/null +++ b/wallets.lua @@ -0,0 +1,310 @@ +local states = {} + +--function load a player's wallet +function minercantile.wallet.load_wallet(name) + if minercantile.wallets[name] == nil then + minercantile.wallets[name] = {} + end + local file, err = io.open(minercantile.path_wallet..name, "r") + if file then + local data = minetest.deserialize(file:read("*all")) + file:close() + if data and type(data) == "table" then + if data.money then + minercantile.wallets[name].money = data.money + else + minercantile.wallets[name].money = 0 + end + if data.transactions then + minercantile.wallets[name].transactions = table.copy(data.transactions) + else + minercantile.wallets[name].transactions = {} + end + return + end + end + --if new player then wallet is empty + minercantile.wallets[name].money = 0 + minercantile.wallets[name].transactions = {} +end + + +function minercantile.wallet.save_wallet(name) + local input, err = io.open(minercantile.path_wallet..name, "w") + if input then + input:write(minetest.serialize(minercantile.wallets[name])) + input:close() + minetest.log("info", "saved " .. minercantile.path_wallet..name) + else + minetest.log("error", "open(" .. minercantile.path_wallet..name .. ", 'w') failed: " .. err) + end + + --unload wallet if player offline + local connected = false + for _, player in pairs(minetest.get_connected_players()) do + local player_name = player:get_player_name() + if player_name and player_name ~= "" and player_name == name then + connected = true + break + end + end + if not connected then + minercantile.wallets[name] = nil + end +end + + +function minercantile.wallet.get_money(name) + if minercantile.wallets[name] == nil then + minercantile.wallet.load_wallet(name) + end + return minercantile.wallets[name].money +end + + +function minercantile.wallet.give_money(name, amount, transaction) + if minercantile.wallets[name] == nil then + minercantile.wallet.load_wallet(name) + end + minercantile.wallets[name].money = minercantile.wallet.get_money(name) + amount + if transaction then + local trans = os.date().. ":"..transaction..", new amount:"..minercantile.wallet.get_money(name) + minercantile.add_transactions(name, trans) + end + minercantile.wallet.save_wallet(name) +end + + +function minercantile.wallet.take_money(name, amount, transaction) + if minercantile.wallets[name] == nil then + minercantile.wallet.load_wallet(name) + end + minercantile.wallets[name].money = minercantile.wallet.get_money(name) - amount + if transaction then + local trans = os.date().. ": "..transaction..", new amount:"..minercantile.wallet.get_money(name) + minercantile.add_transactions(name, trans) + end + minercantile.wallet.save_wallet(name) +end + + +function minercantile.wallet.get_transactions(name) + if minercantile.wallets[name] == nil then + minercantile.wallet.load_wallet(name) + end + return minercantile.wallets[name].transactions +end + + +function minercantile.add_transactions(name, new_transaction) + local old = minercantile.wallet.get_transactions(name) + minercantile.wallets[name].transactions = {new_transaction} + for _, trans in pairs(old) do + table.insert(minercantile.wallets[name].transactions, trans) + if #minercantile.wallets[name].transactions > 9 then + break + end + end +end + + +function minercantile.send_money(sender, receiver, amount) + if minercantile.wallet.get_money(sender) < amount then + return false + end + minercantile.wallet.take_money(sender, amount, "Send "..amount.." Minecoins to "..receiver) + minercantile.wallet.give_money(receiver, amount, "Received "..amount.." Minecoins from "..sender) + return true +end + + +function minercantile.get_formspec_wallet(name) + if minercantile.wallets[name] == nil then + minercantile.wallet.load_wallet(name) + end + local formspec = {} + table.insert(formspec,"size[10,9]label[4.4,0;My Wallet]") + table.insert(formspec,"image[1,2;1,1;minercantile_money.png]") --FIXME add image + table.insert(formspec,"label[2,2.2;total:".. tostring(minercantile.wallet.get_money(name)) .."]") + table.insert(formspec,"label[4,3.3;10 last transactions]") + + local transactions = minercantile.wallet.get_transactions(name) + if #transactions < 1 then + table.insert(formspec,"label[3.5,5;There are no transactions]") + else + local y = 4 + for _,transac in pairs(transactions) do + table.insert(formspec,"label[0,"..y..";".. transac .."]") + y = y+0.4 + end + end + + table.insert(formspec,"button[0,8.2;1.5,1;page;Transfert]") + table.insert(formspec,"button_exit[8,8.2;1.5,1;close;Close]") + return table.concat(formspec) +end + + +function minercantile.get_formspec_wallet_transfert(name) + local money = minercantile.wallet.get_money(name) + local formspec = {} + table.insert(formspec,"size[10,9]label[4.4,0;My Wallet]") + table.insert(formspec,"image[1,2;1,1;minercantile_money.png]") + table.insert(formspec,"label[2,2.2;total:".. tostring(money) .."]") + + if money < 5 then + table.insert(formspec, "label[2,4.5;Sorry you can't send Minecoins, minimum amount is 5]") + else + if not states[name] then + states[name] = {} + end + if not states[name].players_list or states[name].refresh then + states[name].refresh = nil + states[name].players_list = {} + states[name].selected_id = 0 + for _,player in pairs(minetest.get_connected_players()) do + local player_name = player:get_player_name() + if player_name and player_name ~= "" and player_name ~= name then + table.insert(states[name].players_list, player_name) + end + end + states[name]["receiver"] = nil + end + if not states[name].amount then + states[name].amount = 5 + end + if #states[name].players_list == 0 then + table.insert(formspec, "label[2,3.6;There are no player, refresh]") + table.insert(formspec,"button[6,3.4;2,1;refresh;refresh list]") + else + table.insert(formspec, "dropdown[3,3.5;3,1;receiver;"..table.concat(states[name].players_list, ",")..";"..states[name].selected_id.."]") + table.insert(formspec, "label[3.5,6.5;Send "..states[name]["amount"].." to "..(states[name]["receiver"] or "").." ?]") + table.insert(formspec,"button[4.1,7;1.5,1;send;send]") + table.insert(formspec,"button[6,3.4;1.5,1;refresh;refresh list]") + table.insert(formspec, "label[3.5,4.5;amount to send(minimum 5)]") + table.insert(formspec, "button[1.7,5;1,1;amount;-1]") + table.insert(formspec, "button[2.7,5;1,1;amount;-10]") + table.insert(formspec, "button[3.7,5;1,1;amount;-100]") + table.insert(formspec, "label[4.7,5.2;"..tostring(states[name]["amount"]).."]") + table.insert(formspec, "button[5.4,5;1,1;amount;+100]") + table.insert(formspec, "button[6.4,5;1,1;amount;+10]") + table.insert(formspec, "button[7.4,5;1,1;amount;+1]") + end + end + table.insert(formspec,"button[0,8.2;1.5,1;page;wallet]") + table.insert(formspec,"button_exit[8,8.2;1.5,1;close;Close]") + return table.concat(formspec) +end + + +function minercantile.get_formspec_wallet_transfert_send(name) + local formspec = {"size[6,3]label[2,0;Validate sending]"} + table.insert(formspec, "label[1,1.2;Send "..tostring(states[name]["amount"]).." Minecoins to ".. states[name]["receiver"] .."]") + table.insert(formspec, "button_exit[1.1,2.1;1.5,1;close;Abort]") + table.insert(formspec, "button[3.3,2.1;1.5,1;send;Send]") + return table.concat(formspec) +end + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if not name or name == "" then return end + if formname == "minercantile:ended" then + states[name] = nil + return + elseif formname == "minercantile:wallet" then + if fields["quit"] or fields["close"] then + states[name] = nil + return + elseif fields["page"] then + minetest.show_formspec(name, "minercantile:transfert", minercantile.get_formspec_wallet_transfert(name)) + return + end + elseif formname == "minercantile:transfert" then + if fields["quit"] then + states[name] = nil + return + elseif fields["page"] then + minetest.show_formspec(name, "minercantile:wallet", minercantile.get_formspec_wallet(name)) + return + elseif fields["refresh"] then + states[name].refresh = true + elseif fields["amount"] then + local inc = tonumber(fields["amount"]) + if inc ~= nil then + states[name]["amount"] = states[name]["amount"] + inc + end + if states[name]["amount"] > minercantile.wallet.get_money(name) then + states[name]["amount"] = minercantile.wallet.get_money(name) + end + if states[name]["amount"] < 5 then + states[name]["amount"] = 5 + end + elseif fields["send"] then + if states[name]["receiver"] and states[name]["receiver"] ~= "" then + minetest.show_formspec(name, "minercantile:transfert_send", minercantile.get_formspec_wallet_transfert_send(name)) + return + end + elseif fields["receiver"] then + for i, n in pairs(states[name].players_list) do + if n == fields["receiver"] then + states[name]["receiver"] = fields["receiver"] + states[name].selected_id = i + break + end + end + end + minetest.show_formspec(name, "minercantile:transfert", minercantile.get_formspec_wallet_transfert(name)) + elseif formname == "minercantile:transfert_send" then + if fields["send"] then + if minercantile.send_money( name, states[name]["receiver"], states[name]["amount"]) then + minetest.show_formspec(name, "minercantile:ended", "size[5,3]label[1.8,0;Validated]label[1.6,1;Minecoins sent]button_exit[1.8,2.1;1.5,1;close;Close]") + else + minetest.show_formspec(name, "minercantile:ended", "size[5,3]label[1.6,0;Error]label[1.5,1;Error occured]button_exit[1.8,2.1;1.5,1;close;Close]") + end + elseif fields["quit"] or fields["close"] then + states[name] = nil + return + end + end +end) + + +if (minetest.get_modpath("unified_inventory")) then + unified_inventory.register_button("wallet", { + type = "image", + image = "minercantile_money.png", + tooltip = "My Wallet", + show_with = "interact", + action = function(player) + local name = player:get_player_name() + if not name then return end + local formspec = minercantile.get_formspec_wallet(name) + minetest.show_formspec(name, "minercantile:wallet", formspec) + end, + }) +else + minetest.register_chatcommand("wallet",{ + params = "", + description = "Shows your money wallet", + privs = {interact= true}, + func = function (name, params) + local formspec = minercantile.get_formspec_wallet(name) + minetest.show_formspec(name, "minercantile:wallet", formspec) + end, + }) +end + + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + if not name or name == "" then return end + minercantile.wallet.load_wallet(name) +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + if not name or name == "" then return end + minercantile.wallets[name] = nil +end) +