From 560cc4a7a713698119005dc2357c73bd140353a2 Mon Sep 17 00:00:00 2001 From: Freeman Date: Tue, 20 Dec 2022 20:06:59 +0100 Subject: [PATCH] shop closed if inv is empty separated shop node functions register shop_empty node, not in creative inv, drop a normal shop item TODO: fix formspec update on move / on receive fields --- shop.lua | 182 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 126 insertions(+), 56 deletions(-) diff --git a/shop.lua b/shop.lua index bc63e7d..3c7e61e 100644 --- a/shop.lua +++ b/shop.lua @@ -24,7 +24,7 @@ local shopcraft = core.settings:get_bool("emeraldbank.shop_craft") or true -- privilege core.register_privilege("admin_shop", { - description = "Permission edit others shops", + description = "Permission to edit others shops", give_to_singleplayer = false, }) @@ -82,7 +82,19 @@ function emeraldbank.get_shop_fs(pos, clicker) end -local function set_item(pos, listname, index, stack, player) +local function swap_shop(pos, closed) + local oldnode = core.get_node(pos) + local oldnodemeta = core.get_meta(pos):to_table() + local nodename = core.get_node(pos).name + if nodename == "emeraldbank:shop" and closed then + core.swap_node(pos, {name = "emeraldbank:shop_empty"}) + else + core.swap_node(pos, {name = "emeraldbank:shop"}) + end + core.get_meta(pos):from_table(oldnodemeta) +end + +local function set_item(pos, stack, player) local meta = core.get_meta(pos) local itemname = stack:get_name() local itemcount = stack:get_count() @@ -90,11 +102,18 @@ local function set_item(pos, listname, index, stack, player) core.show_formspec(player:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, player) ) end -local function check_empty(pos, listname, index, stack, player) +local function check_empty(pos, player) local meta = core.get_meta(pos) local inv = meta:get_inventory() + local count = meta:get_int("count") + local shop_item = meta:get_string("shop_item") if inv:is_empty("stock") then meta:set_string("shop_item", "") + swap_shop(pos, true) + elseif not inv:contains_item("stock", shop_item.." "..count, true) then + swap_shop(pos, true) + else + swap_shop(pos) end core.show_formspec(player:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, player) ) end @@ -106,10 +125,10 @@ local function get_stonks(pos, player) local stonks = meta:get_int("stonks") if name == owner and stonks > 0 then core.sound_play("cash", { - to_player = name, - gain = 1.0, - fade = 0.0, - pitch = 1.0, + to_player = name, + gain = 1.0, + fade = 0.0, + pitch = 1.0, }) emeraldbank.add_emeralds(player, stonks) meta:set_int("stonks", 0) @@ -117,6 +136,69 @@ local function get_stonks(pos, player) end end +local function after_place_node(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) + meta:set_int("count", 10) -- default count + meta:set_int("price", 5) -- default price + core.get_node_timer(pos):start(shop_timer) + local inv = meta:get_inventory() + inv:set_size("stock", stock_w*stock_h) +end + +local function on_rightclick(pos, node, clicker, itemstack) + local meta = core.get_meta(pos) + local nodename = core.get_node(pos).name + local owner = meta:get_string("owner") + local pname = clicker:get_player_name() + get_stonks(pos, clicker) + --if nodename == "emeraldbank:shop" and pname == owner then + core.show_formspec(pname, formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, clicker) ) + --end +end + +local function on_punch(pos, node, puncher, pointed_thing) + get_stonks(pos, puncher) +end + +local function on_metadata_inventory_put(pos, listname, index, stack, player) + set_item(pos, stack, player) + check_empty(pos, player) +end + +local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + check_empty(pos, player) +end + +local function on_metadata_inventory_take(pos, listname, index, stack, player) + check_empty(pos, player) +end + + +local function on_timer(pos, elapsed) + local meta = core.get_meta(pos) + local owner = meta:get_string("owner") + local is_online = core.player_exists(owner) + core.get_node_timer(pos):start(shop_timer) + if is_online then + local player = core.get_player_by_name(owner) + if not player or player.is_fake_player then return end + get_stonks(pos, player) + end +end + +local function can_dig(pos, player) + local pname = player:get_player_name() + local is_admin = core.check_player_privs(pname, {admin_shop=true}) + local meta = core.get_meta(pos) + local owner = meta:get_string("owner") + local inv = meta:get_inventory() + if inv:is_empty("stock") and (pname == owner or is_admin) then + return true + end +end -- register shop node core.register_node("emeraldbank:shop", { @@ -133,56 +215,42 @@ core.register_node("emeraldbank:shop", { 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) - meta:set_int("count", 10) -- default count - meta:set_int("price", 5) -- default price - core.get_node_timer(pos):start(shop_timer) - local inv = meta:get_inventory() - inv:set_size("stock", stock_w*stock_h) - end, - - on_rightclick = function(pos, node, clicker, itemstack) - local pname = clicker:get_player_name() - get_stonks(pos, clicker) - core.show_formspec(pname, formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, clicker) ) - end, - - on_punch = function(pos, node, puncher, pointed_thing) - get_stonks(pos, puncher) - end, - on_metadata_inventory_put = set_item, + after_place_node = after_place_node, + on_rightclick = on_rightclick, + on_punch = on_punch, + on_metadata_inventory_put = on_metadata_inventory_put, + on_metadata_inventory_move = on_metadata_inventory_move, + on_metadata_inventory_take = on_metadata_inventory_take, + on_timer = on_timer, + can_dig = can_dig +}) - on_metadata_inventory_take = check_empty, - - on_timer = function(pos, elapsed) - local meta = core.get_meta(pos) - local owner = meta:get_string("owner") - local is_online = core.player_exists(owner) - core.get_node_timer(pos):start(shop_timer) - if is_online then - local player = core.get_player_by_name(owner) - if not player or player.is_fake_player then return end - get_stonks(pos, player) - end - end, - - can_dig = function(pos, player) - local pname = player:get_player_name() - local is_admin = core.check_player_privs(pname, {admin_shop=true}) - local meta = core.get_meta(pos) - local owner = meta:get_string("owner") - local inv = meta:get_inventory() - if inv:is_empty("stock") and (pname == owner or is_admin) then - return true - end - end +-- register shop node +core.register_node("emeraldbank:shop_empty", { + description = S("Shop Empty"), + _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^mcl_core_barrier.png" + }, + stack_max = 64, + groups = {axey=1, handy=1, building_block=1, enderman_takable=1, not_in_creative_inventory=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + drop = "emeraldbank:shop", + _mcl_blast_resistance = 5, + _mcl_hardness = 1, + after_place_node = after_place_node, + on_rightclick = on_rightclick, + on_punch = on_punch, + on_metadata_inventory_put = on_metadata_inventory_put, + on_metadata_inventory_move = on_metadata_inventory_move, + on_metadata_inventory_take = on_metadata_inventory_take, + on_timer = on_timer, + can_dig = can_dig }) @@ -207,10 +275,11 @@ core.register_on_player_receive_fields(function(sender, formname, fields) -- set or reset timer core.get_node_timer(pos):start(shop_timer) - + if fields.count and string.find(fields.count, "^[0-9]+$") then if new_count >= 1 and new_count <= 64 and new_count ~= meta:get_int("count") then meta:set_int("count", new_count) + check_empty(pos, sender) end end @@ -246,7 +315,8 @@ core.register_on_player_receive_fields(function(sender, formname, fields) 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) ) + check_empty(pos, sender) --this func already shows formspec, so I comment it bellow + --core.show_formspec(sender:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, sender) ) end end