diff --git a/init.lua b/init.lua index 4d0fc94..54b8781 100644 --- a/init.lua +++ b/init.lua @@ -31,5 +31,5 @@ if income_enabled then end dofile(modpath .. "/bank.lua") --- dofile(modpath .. "/shop.lua") +dofile(modpath .. "/shop.lua") dofile(modpath .. "/commands.lua") diff --git a/shop.lua b/shop.lua new file mode 100644 index 0000000..30f6870 --- /dev/null +++ b/shop.lua @@ -0,0 +1,202 @@ + + +-- Copyright (C) 2021 Free Software Foundation + +-- This file is part of Emeraldbank Minetest Mod. + +-- Emeraldbank is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. + +-- Emeraldbank is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. + +-- You should have received a copy of the GNU General Public License +-- along with Emeraldbank. If not, see . + + + +local S = core.get_translator(core.get_current_modname()) + +local stock_h = 3 +local stock_w = 5 + +local formspec_prefix = "emeraldbank:shop_formspec" + +emeraldbank.player_inv = + "list[current_player;main;0,4.5;9,3;9]".. + mcl_formspec.get_itemslot_bg(0,4.5,9,3).. + "list[current_player;main;0,7.74;9,1;]".. + mcl_formspec.get_itemslot_bg(0,7.74,9,1).. + "listring[current_player;main]" + + +function emeraldbank.get_shop_fs(pos, clicker) + local meta = core.get_meta(pos) + local price = meta:get_int("price") + local shop_item = meta:get_string("shop_item") + local list_name = "nodemeta:"..pos.x..','..pos.y..','..pos.z + local pname = clicker:get_player_name() + local owner = meta:get_string("owner") + local player_press_key = clicker:get_player_control().aux1 + local shop_fs = "" + if pname == owner and not player_press_key then + shop_fs = "size[9,8.75]".. + "label[0,0;"..S("Your stock:").."]".. + "list["..list_name..";stock;0,0.5;"..stock_w..","..stock_h..";]".. + mcl_formspec.get_itemslot_bg(0,0.5,stock_w,stock_h).. + "field[6.5,3;2,1;price;"..S("Price")..";"..price.."]".. + "label[6,0;"..S("In exchange, you give:").."]".. + "item_image[6.5,0.5;1,1;"..shop_item.."]".. + mcl_formspec.get_itemslot_bg(6.5,0.5,1,1).. + "label[0,4;"..S("Owner, Use (special key + right mouse button) for customer interface").."]".. + emeraldbank.player_inv + else + shop_fs = "size[9,8.75]".. + "label[3.7,0;"..S("Owner gives:").."]".. + "item_image[4,1;1,1;"..shop_item.."]".. + mcl_formspec.get_itemslot_bg(4,1,1,1).. + "label[4,2;"..S("Price: @1", price).."]".. + "button[3.5,3;2,1;exchange;"..S("Exchange").."]".. + emeraldbank.player_inv + end + + return shop_fs + +end + + +local function set_item(pos, listname, index, stack, player) + local meta = core.get_meta(pos) + local itemname = stack:get_name() + local itemcount = stack:get_count() + meta:set_string("shop_item", itemname) + core.show_formspec(player:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, player) ) +end + +local function get_stonks(pos, clicker) + local name = clicker:get_player_name() + local owner = clicker:get_player_name() + local meta = core.get_meta(pos) + local stonks = meta:get_int("stonks") + if name == owner and stonks > 0 then + emeraldbank.add_emeralds(clicker, stonks) + meta:set_int("stonks", 0) + core.chat_send_player(name, S("You've earned @1 Emeralds with this shop.", stonks) ) + end +end + + +-- register shop node +core.register_node("emeraldbank:shop", { + description = S("Shop"), + _doc_items_longdesc = S("A shop to sell your items with emeralds."), + is_ground_content = false, + tiles = { + "default_tree.png", + "default_tree.png", + "default_tree.png^mcl_core_emerald.png" + }, + stack_max = 64, + groups = {axey=1, handy=1, building_block=1, enderman_takable=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 5, + _mcl_hardness = 1, + + after_place_node = function(pos, placer, itemstack) + local owner = placer:get_player_name() + local meta = core.get_meta(pos) + meta:set_string("infotext", S("Exchange shop (owned by @1)", owner)) + meta:set_string("owner", owner) + local inv = meta:get_inventory() + inv:set_size("stock", stock_w*stock_h) + end, + + on_rightclick = function(pos, node, clicker, itemstack) + get_stonks(pos, clicker) + core.show_formspec(clicker:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, clicker) ) + end, + + on_metadata_inventory_put = set_item, + -- on_metadata_inventory_take = set_item, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = core.get_meta(pos) + local meta2 = meta + meta:from_table(oldmetadata) + local inv = meta:get_inventory() + for _, listname in ipairs({"stock"}) do + local stack = inv:get_stack(listname, 1) + if not stack:is_empty() then + local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + core.add_item(p, stack) + end + end + meta:from_table(meta2:to_table()) + end, + +}) + + +core.register_on_player_receive_fields(function(sender, formname, fields) + local prefix_len = string.len(formspec_prefix) + if formname:sub(1,prefix_len) == formspec_prefix then + + local pos_string = formname:sub(prefix_len+1) + local pos = core.string_to_pos(pos_string) + local meta = core.get_meta(pos) + local name = sender:get_player_name() + local playermeta = sender:get_meta() + local player_pos = sender:get_pos() + local old_price = meta:get_int("price") + local new_price = tonumber(fields.price) + local shop_item = meta:get_string("shop_item") + local minv = meta:get_inventory() + local pinv = sender:get_inventory() + local bankemeralds = playermeta:get_int("emeraldbank:emerald") + + if fields.price and string.find(fields.price, "^[0-9]+$") then + if new_price >= 1 and new_price <= 10000 and new_price ~= meta:get_int("price") then + meta:set_int("price", new_price) + end + end + + if fields.exchange ~= nil and fields.exchange ~= "" then + + if meta:get_string("owner") == name then + + core.chat_send_player(name, S("This is your own shop, you can't exchange to yourself!")) + + else + + local stocklist = minv:get_list("stock") + local can_exchange = true + + if bankemeralds < old_price then + can_exchange = false + core.chat_send_player(name, S("Not enough Emeralds in your account") ) + end + + if not minv:contains_item("stock", shop_item) then + can_exchange = false + core.chat_send_player(name, S("Out of Stock!") ) + end + + if can_exchange then + minv:remove_item("stock", shop_item) + core.add_item(player_pos, shop_item) + emeraldbank.add_emeralds(sender, -old_price) + meta:set_int("stonks", meta:get_int("stonks")+old_price) + core.chat_send_player(name, S("Exchanged!")) + core.show_formspec(sender:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, sender) ) + end + + end + + end + + end +end)