2021-10-21 02:08:59 +02:00
|
|
|
|
|
|
|
|
2022-07-03 18:20:28 +02:00
|
|
|
-- Copyright (C) 2021, 2022 Ale
|
2021-10-21 02:08:59 +02:00
|
|
|
|
|
|
|
-- This file is part of Emeraldbank Minetest Mod.
|
|
|
|
|
|
|
|
-- Emeraldbank is free software: you can redistribute it and/or modify
|
2022-03-11 19:02:35 +01:00
|
|
|
-- it under the terms of the GNU Affero General Public License as
|
|
|
|
-- published by the Free Software Foundation, either version 3 of the
|
|
|
|
-- License, or (at your option) any later version.
|
2021-10-21 02:08:59 +02:00
|
|
|
|
|
|
|
-- 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
|
2022-03-11 19:02:35 +01:00
|
|
|
-- GNU Affero General Public License for more details.
|
2021-10-21 02:08:59 +02:00
|
|
|
|
2022-03-11 19:02:35 +01:00
|
|
|
-- You should have received a copy of the GNU Affero General Public License
|
2021-10-21 02:08:59 +02:00
|
|
|
-- along with Emeraldbank. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
local S = core.get_translator(core.get_current_modname())
|
|
|
|
|
2021-12-16 18:21:56 +01:00
|
|
|
local shopcraft = core.settings:get_bool("emeraldbank.shop_craft") or true
|
|
|
|
|
2022-03-07 17:54:31 +01:00
|
|
|
-- privilege
|
|
|
|
core.register_privilege("admin_shop", {
|
2022-12-20 20:06:59 +01:00
|
|
|
description = "Permission to edit others shops",
|
2022-03-07 17:54:31 +01:00
|
|
|
give_to_singleplayer = false,
|
|
|
|
})
|
|
|
|
|
2021-12-16 19:41:21 +01:00
|
|
|
local shop_timer = 5
|
|
|
|
|
2021-10-21 02:08:59 +02:00
|
|
|
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)
|
2021-12-16 18:21:56 +01:00
|
|
|
local count = meta:get_int("count")
|
2021-10-21 02:08:59 +02:00
|
|
|
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 = ""
|
2022-03-07 17:54:31 +01:00
|
|
|
local is_admin = core.check_player_privs(pname, {admin_shop=true})
|
2021-12-16 18:44:20 +01:00
|
|
|
if (pname == owner or is_admin) and not player_press_key then
|
2021-10-21 02:08:59 +02:00
|
|
|
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)..
|
2021-12-16 18:21:56 +01:00
|
|
|
"field[6.5,2;2,1;count;"..S("Count")..";"..count.."]"..
|
2021-10-21 02:08:59 +02:00
|
|
|
"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)..
|
2021-12-16 18:21:56 +01:00
|
|
|
"label[5,1.5;"..S("x @1", count).."]"..
|
2021-10-21 02:08:59 +02:00
|
|
|
"label[4,2;"..S("Price: @1", price).."]"..
|
|
|
|
"button[3.5,3;2,1;exchange;"..S("Exchange").."]"..
|
|
|
|
emeraldbank.player_inv
|
|
|
|
end
|
|
|
|
|
|
|
|
return shop_fs
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2022-12-20 20:06:59 +01:00
|
|
|
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
|
2022-12-20 20:29:27 +01:00
|
|
|
if closed then
|
2022-12-20 20:06:59 +01:00
|
|
|
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)
|
2021-10-21 02:08:59 +02:00
|
|
|
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
|
|
|
|
|
2022-12-20 20:19:33 +01:00
|
|
|
local function check_empty(pos)
|
2021-10-21 02:08:59 +02:00
|
|
|
local meta = core.get_meta(pos)
|
2021-10-21 19:06:05 +02:00
|
|
|
local inv = meta:get_inventory()
|
2022-12-20 20:06:59 +01:00
|
|
|
local count = meta:get_int("count")
|
|
|
|
local shop_item = meta:get_string("shop_item")
|
2021-10-21 19:06:05 +02:00
|
|
|
if inv:is_empty("stock") then
|
|
|
|
meta:set_string("shop_item", "")
|
2022-12-20 20:06:59 +01:00
|
|
|
swap_shop(pos, true)
|
|
|
|
elseif not inv:contains_item("stock", shop_item.." "..count, true) then
|
|
|
|
swap_shop(pos, true)
|
|
|
|
else
|
|
|
|
swap_shop(pos)
|
2021-10-21 19:06:05 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function get_stonks(pos, player)
|
|
|
|
local name = player:get_player_name()
|
|
|
|
local meta = core.get_meta(pos)
|
|
|
|
local owner = meta:get_string("owner")
|
2021-10-21 02:08:59 +02:00
|
|
|
local stonks = meta:get_int("stonks")
|
|
|
|
if name == owner and stonks > 0 then
|
2021-12-16 20:19:08 +01:00
|
|
|
core.sound_play("cash", {
|
2022-12-20 20:06:59 +01:00
|
|
|
to_player = name,
|
|
|
|
gain = 1.0,
|
|
|
|
fade = 0.0,
|
|
|
|
pitch = 1.0,
|
2021-12-16 20:19:08 +01:00
|
|
|
})
|
2021-10-21 19:06:05 +02:00
|
|
|
emeraldbank.add_emeralds(player, stonks)
|
2021-10-21 02:08:59 +02:00
|
|
|
meta:set_int("stonks", 0)
|
2021-12-16 20:26:54 +01:00
|
|
|
core.chat_send_player(name, S("You've earned @1 Emeralds with your shops.", stonks) )
|
2021-10-21 02:08:59 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-12-20 20:06:59 +01:00
|
|
|
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)
|
2022-12-20 20:29:27 +01:00
|
|
|
--if nodename == "emeraldbank:shop" or pname == owner then
|
2022-12-20 20:06:59 +01:00
|
|
|
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)
|
2022-12-20 20:29:27 +01:00
|
|
|
set_item(pos, stack, player) -- this func already show the fs
|
2022-12-20 20:19:33 +01:00
|
|
|
check_empty(pos)
|
2022-12-20 20:06:59 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
2022-12-20 20:19:33 +01:00
|
|
|
check_empty(pos)
|
|
|
|
|
2022-12-20 20:06:59 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
local function on_metadata_inventory_take(pos, listname, index, stack, player)
|
2022-12-20 20:19:33 +01:00
|
|
|
check_empty(pos)
|
|
|
|
core.show_formspec(player:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, player) )
|
2022-12-20 20:06:59 +01:00
|
|
|
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)
|
2022-12-20 20:19:33 +01:00
|
|
|
check_empty(pos)
|
2022-12-20 20:06:59 +01:00
|
|
|
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
|
2021-10-21 02:08:59 +02:00
|
|
|
|
|
|
|
-- 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,
|
|
|
|
|
2022-12-20 20:06:59 +01:00
|
|
|
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
|
|
|
|
})
|
2021-12-16 19:41:21 +01:00
|
|
|
|
2022-12-20 20:06:59 +01:00
|
|
|
-- 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,
|
2021-10-21 02:08:59 +02:00
|
|
|
|
2022-12-20 20:06:59 +01:00
|
|
|
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
|
2021-10-21 02:08:59 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
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()
|
2021-12-16 18:21:56 +01:00
|
|
|
local old_count = meta:get_int("count")
|
|
|
|
local new_count = tonumber(fields.count)
|
2021-10-21 02:08:59 +02:00
|
|
|
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")
|
2021-12-16 19:41:21 +01:00
|
|
|
|
|
|
|
-- set or reset timer
|
|
|
|
core.get_node_timer(pos):start(shop_timer)
|
2022-12-20 20:06:59 +01:00
|
|
|
|
2022-12-20 20:42:07 +01:00
|
|
|
-- set item count
|
2021-12-16 18:21:56 +01:00
|
|
|
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)
|
2022-12-20 20:19:33 +01:00
|
|
|
check_empty(pos)
|
2021-12-16 18:21:56 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-12-20 20:42:07 +01:00
|
|
|
-- set price
|
2021-10-21 02:08:59 +02:00
|
|
|
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
|
2022-12-20 20:42:07 +01:00
|
|
|
|
|
|
|
-- someone hit exchange button
|
2021-10-21 02:08:59 +02:00
|
|
|
if fields.exchange ~= nil and fields.exchange ~= "" then
|
|
|
|
|
2022-12-20 20:42:07 +01:00
|
|
|
-- owner try exchanges
|
2021-10-21 02:08:59 +02:00
|
|
|
if meta:get_string("owner") == name then
|
2023-01-04 21:36:43 +01:00
|
|
|
mcl_title.set(sender, "subtitle", {text=S("This is your own shop, you can't exchange to yourself!"), color="dark_red"})
|
2021-10-21 02:08:59 +02:00
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
local can_exchange = true
|
|
|
|
|
2022-12-20 20:42:07 +01:00
|
|
|
-- have u money?
|
2021-10-21 02:08:59 +02:00
|
|
|
if bankemeralds < old_price then
|
|
|
|
can_exchange = false
|
2023-01-04 21:36:43 +01:00
|
|
|
mcl_title.set(sender, "subtitle", {text=S("Not enough Emeralds in your account"), color="dark_red"})
|
2021-10-21 02:08:59 +02:00
|
|
|
end
|
2022-12-20 20:42:07 +01:00
|
|
|
|
|
|
|
--there are enough items?
|
2021-12-16 18:21:56 +01:00
|
|
|
if not minv:contains_item("stock", shop_item.." "..old_count, true) then
|
2021-10-21 02:08:59 +02:00
|
|
|
can_exchange = false
|
2023-01-04 21:36:43 +01:00
|
|
|
mcl_title.set(sender, "subtitle", {text=S("Out of Stock!"), color="dark_red"})
|
2021-10-21 02:08:59 +02:00
|
|
|
end
|
2022-12-20 20:42:07 +01:00
|
|
|
|
|
|
|
-- do not trade air
|
|
|
|
if shop_item == "" or shop_item == "air" then
|
|
|
|
can_exchange = false
|
|
|
|
end
|
2021-10-21 02:08:59 +02:00
|
|
|
|
|
|
|
if can_exchange then
|
2021-12-16 18:21:56 +01:00
|
|
|
minv:remove_item("stock", shop_item.." "..old_count)
|
|
|
|
core.add_item(player_pos, shop_item.." "..old_count)
|
2021-10-21 02:08:59 +02:00
|
|
|
emeraldbank.add_emeralds(sender, -old_price)
|
|
|
|
meta:set_int("stonks", meta:get_int("stonks")+old_price)
|
2023-01-04 21:36:43 +01:00
|
|
|
mcl_title.set(sender, "subtitle", {text=S("Exchanged!"), color="green"})
|
2022-12-20 20:19:33 +01:00
|
|
|
check_empty(pos)
|
|
|
|
core.show_formspec(sender:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, sender) )
|
2021-10-21 02:08:59 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end)
|
2021-12-16 18:21:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
if shopcraft then
|
|
|
|
core.register_craft({
|
|
|
|
output = "emeraldbank:shop 3",
|
|
|
|
recipe = {
|
|
|
|
{"mcl_core:emerald", "mcl_core:emerald", "mcl_core:emerald"},
|
|
|
|
{"mcl_core:emerald", "mcl_core:tree", "mcl_core:emerald"},
|
|
|
|
{"mcl_core:emerald", "mcl_core:emerald", "mcl_core:emerald"},
|
|
|
|
}
|
|
|
|
})
|
|
|
|
end
|