emeraldbank mod now focuses only on the bank and the economy API

The shops will be separated in another mod
This commit is contained in:
Freeman 2024-05-27 19:58:18 +02:00
parent 7608c916f2
commit 2e6c271f40
19 changed files with 12 additions and 2444 deletions

@ -15,20 +15,6 @@ You should have received a copy of the GNU Affero General Public License
along with Emeraldbank. If not, see <https://www.gnu.org/licenses/>.
Textures License:
admin_depo.png
admin_vend.png
copier.png
inactive.png
player_depo.png
player_vend_front.png
player_vend.png
upgrade_front.png
Copyright (c) 2018 ChimneySwift, LadyK under MIT License
Sounds License:
- cash.ogg:

176
README.md

@ -1,4 +1,5 @@
# Emerald Bank and Shops (MineClonia/MineClone2)
# Emerald Bank and Shops (MineClonia)
[![ContentDB](https://content.minetest.net/packages/NathanielFreeman/emeraldbank/shields/downloads/)](https://content.minetest.net/packages/NathanielFreeman/emeraldbank/)
@ -14,7 +15,7 @@ EmeraldBank Mod is [Libre/Free Software](https://www.gnu.org/philosophy/free-sw.
Keep your Emeralds in a bank!
Why Emeralds? In MineClonia/MineClone2 the emerald is money to trade with villagers!
Why Emeralds? In MineClonia the emerald is money to trade with villagers!
Multiplayer support!
@ -26,151 +27,7 @@ Rightclick on bank open the bank interface, where you can deposit or withdraw yo
You can transfer money to other players in Bank interface.
## Shops (Like fancy_vend mod)
The new shops are based in _fancy_vend_ mod shops
[Learn more about shops here](https://github.com/ChimneySwift/fancy_vend/blob/master/README.md)
There are many vendor mods for Minetest, but most have too few options, lack support for automation mods, or are too tedious to set up and maintain. Fancy vendors are entirely self-contained nodes which provide light, trade, display and store items. Fancy vendors are _pipeworks_, _digilines_ and _mcl_awards_ compatible, enabling a variety of automation-based features.
### Basic configuration
Each fancy vendor needs 2 nodes of room. If the area you wish to place the vendor doesn't have enough space, due to either a node or a protected area, the node will not be placed. If the vendor has sufficient room, it will place a vendor node in addition to a display node on top. The display node's only purpose is aesthetics, to "contain" the rotating display object.
Configuring a vendor is as simple as picking up and placing the input and output items into their respective slots as if they were regular inventories (items in these inventories are "ghosts", so don't actually take anything from the player's inventory) and setting the quantities for each item, as shown below:
![Setting up a vendor](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Setting%20up%20a%20vendor.PNG?raw=true "Setting up a vendor")
Stocking a vendor is as simple as placing the output item into the vendor's inventory (perhaps using one of the handy inventory movement buttons) as demonstrated below:
![Stocking a vendor](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Stocking%20a%20vendor.PNG?raw=true "Stocking a vendor")
After stocking a vendor, you may wish to press the "sort" button, which will combine unfilled stacks and sort the stacks in alphabetical order.
If the vendor is intended to be used to purchase items, you may wish to set the vendor to a depositor in the vendor settings, this will display the input item in the display case and change the vendor's appearance to make it clear to potential sellers the vendor's purpose. The previous example vendor set to a depositor can be seen below:
![A player depositor](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/A%20player%20depositor.PNG?raw=true "A player depositor")
### Buying items
Regular players who can't access a fancy vendor's inventory or configuration will be displayed a purchase screen when they access a vendor. This screen displays vendor information and status, as well as buying options. Unlike many vendor mods, fancy vendors give buyers to buy multiple "lots" at once. Doing this can save a lot of clicking, as the number of input and output items traded is multiplied by this number.
There is also a button labeled "Fill lots to max" which will pre-load the lots field with the maximum number of lots that the player can purchase from the vendor (which will be either the maximum the player can afford, or the maximum the shop can sell, whichever is smaller).
An example image of the buyer formspec can be seen below:
![Buying from a fancy vendor](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Buying%20from%20a%20fancy%20vendor.PNG?raw=true "Buying from a fancy vendor")
### Advanced settings
Fancy vendors have many additional options which enable sellers to greatly customize vendors.
![Fancy Vendor settings](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Fancy%20Vendor%20settings.PNG?raw=true "Fancy Vendor settings")
**Banned Buyers:**
This field is a list of players (separated by commas) who won't be able to purchase from the vendor. This setting might be useful if you wish to stop players buying out your vendor's stock and reselling it for a higher margin.
**Co-Sellers:**
This field is a list of players (separated by commas) who will be able to access the vendor's inventory. **Please note: Anyone added to the list has full access to the vendor's inventory, however cannot modify the vendor settings nor dig the vendor.**
**Buy/sell worn tools:**
These options allow for the seller to stop the vendor from purchasing or selling worn tools. A message will display on the buyer formspec if one of these options is disabled.
**Inactive force:**
While the seller is reconfiguring a vendor, or in the process of creating a shop, the owner might wish for the vendor to be inactive so players cannot purchase from it, in which case they can enable this option.
**Autosort:**
If this option is enabled, the vendor's inventory will automatically sort when the vendor formspec is closed by someone who can access the inventory.
**Logs:**
The logs formspec displays the 40 most-recent transactions. While only people who can modify the vendor are allowed to access this formspec, these logs are kept in metadata which could be easily read client-side.
**Geminio Wand:**
This tool can be used to easily copy vendor settings from one vendor to another. Simply right click a vendor with it to copy the settings to the tool, and left click any other vendor to set that vendor's settings. **The Geminio Wand will not copy input and output items nor quantities.** You must be able to modify the settings of the vendor to do this. You can craft one with the following recipe:
![Crafting a Geminio Wand](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Crafting%20a%20Geminio%20Wand.PNG?raw=true "Crafting a Geminio Wand")
### Automation
Fancy Vendors are digilines and pipeworks compatible, enabling the creation of highly automated shops.
#### Pipeworks
Fancy vendors connect to pipeworks devices from the bottom, rear and sides. When the optional pipeworks dependancy is satisfied, a number of pipeworks-specific options will also appear in the settings menu:
![Pipeworks Settings](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Pipeworks%20Settings.PNG?raw=true "Pipeworks Settings")
**Split incoming stacks:**
This option enabled incoming stacks from pipeworks tubes to be split if only some of the stack can be accepted.
**Eject incoming currency:**
When this option is enabled, the input items will be sent out of the **bottom** of the fancy vendor instead of being added to the vendor's internal inventory.
**Accept output only:**
When this option is enabled, incoming items which aren't the output item will be rejected and not added to the vendor's inventory.
#### Hoppers
Fancy vendors are MCL hopper compatible. Also they have been tested to work with [TenPlus1's hopper mod](https://github.com/tenplus1/hopper) however should work with all hopper mods and forks. Hoppers can filter into vendors from the sides, however cannot be drained from the bottom as hoppers are protected and Fancy Vendors are locked. However, the shop owner is given the `Eject incoming currency` option which operates on hoppers similarly to how it does on pipeworks, by manually adding incoming currency to the inventory of a hopper placed below the vendor (or into the vendor's inventory if the hopper is full). Due to API limitations, `Accept output only` is not hopper-compatible and `Split incoming stacks` is not necessary.
#### Digilines
Fancy vendors are digilines compatible. When the digilines dependency is satisfied, an option to set the digiline channel will appear in settings. If this channel is set, every purchase will result in the following table being sent over that channel:
```lua
local msg = {
buyer = player:get_player_name(), -- Purchaser's playername
lots = lots, -- Number of lots purchased
settings = settings, -- The settings table
}
```
The default settings table can be seen below:
```lua
local settings_default = {
input_item = "",
output_item = "",
input_item_qty = 1,
output_item_qty = 1,
admin_vendor = false,
depositor = false,
currency_eject = false,
accept_output_only = false,
split_incoming_stacks = false,
inactive_force = false,
accept_worn_input = true,
accept_worn_output = true,
digiline_channel = "",
co_sellers = "",
banned_buyers = "",
}
```
Fancy Vendors and Fancy Vendor Display Nodes conduct digiline signals also.
This feature could theoretically make rewards-based shops feasable.
### Out Of Stock Mail
This mod integrates with [Athous Mail Mod](https://github.com/mt-mods/mail) to alert shop owners when their shops lose stock.
When a vendor empties, the mod sends mail telling them that their vendor is out of stock. In the event another mod empties, the previous message will be edited so as to avoid flooding their inbox if they have many vendors.
### Upgrading vendors
**NOTE:** If you wish to simply run this mod in parallel with existing vendor mods, simply load this mod (no configuration required)
Many servers already have vendor mods in place. Fancy Vend makes it easier for servers to upgrade with it's unique upgrading system. Fancy Vend will replace vendors from the supported vendor mods (money, vendor, easyvend and currency) with upgrade nodes. Upgrade nodes allow for sellers to empty the old node's inventory (if applicable), dig the upgrade node (which will drop a regular vendor) and set up a new shop. if a user tried to place an upgrade node, the stack is turned into a stack of regular vendors.
Since upgrade functionality can be achieved without the old mod loaded, the server owner must add the old vendor mod's name to `minetest.conf` as follows:
`fancy_vend_old_vendor_mods = money`
If there are multiple vendor mods the the owner wishes to enable this functionality on, they can add several mods to the list, separating each mod name with commas as follows:
`fancy_vend_old_vendor_mods = emeraldbank,money,vendor,easyvend`
If the owner wishes to keep the mod loaded, but still replace vendor nodes, the will need to add the mod to both `minetest.conf` and `mod.conf`.
Vendor upgrade:
![Vendor upgrade](https://github.com/ChimneySwift/fancy_vend/blob/master/screenshots/Vendor%20upgrade.PNG?raw=true "Vendor upgrade")
## User Commands
## Commands
User /pay command. Pay emeralds to another player:
@ -184,7 +41,6 @@ User /money command. Show you the emeralds in your bank account in the chat.
/money
```
## Administration
EmeraldBank mod also include a variety of tools for server administrators.
**Admin Emerald command**
@ -198,31 +54,9 @@ Add `<num>` emeralds to `<player>` account.
If num is 0 return emeralds in player account.
**Temporarily disabling vendors:**
Any player with the disable_vendor privilege can run
```
/disable_all_vendors
```
to force all vendors into an inactive state. Please use this if you find a dangerous bug and are waiting for it to be fixed.
**Admin vendors:**
Admin vendors perform the same role as their regular counterparts, however they do so with no stock or inventory requirements, simply creating and destroying items as players purchase.
Since incorrectly configured admin vendors could be easily used to duplicate items, the `admin_vendor` privilege is required for the option to switch a vendor to one appears. If the user is ever revoked this privilege, all admin vendors they own will be forced into an inactive state until the privilege is re-granted or the vendor is set to a player vendor.
**Modifying vendors:**
If a user has the `protection_bypass` privilege, they will be able to access the full extent of the vendor as if they were the owner, including inventory and settings.
**Server and client load:**
Fancy vend uses only one infrequent abm to refresh vendor objects in the event of a clearobjects. No other vendor updating is done unless a player purchases from the vendor or adjusts settings.
Note: Some clients using mobile and/or older devices, including PCs, may experience additional lag if many fancy vendors are used in a small space, however not to an extent greater than the majority of shops where players use itemframes or pedestals to achieve the same functionality as the fancy vendor's display.
## More Info
This mod is for [MineClonia](https://content.minetest.net/packages/ryvnf/mineclonia/) or [MineClone2](https://content.minetest.net/packages/Wuzzy/mineclone2/) Games, dont work with MTG
This mod is for [MineClonia](https://content.minetest.net/packages/ryvnf/mineclonia/) or [VoxeLibre](https://content.minetest.net/packages/Wuzzy/mineclone2/) Games, dont work with MTG
Feel free to contribute, send MR/PR or issues.

@ -1,6 +1,6 @@
-- Copyright (C) 2021, 2023 Ale
-- Copyright (C) 2021, 2024 Sandro del Toro
-- This file is part of Emeraldbank Minetest Mod.

@ -1,6 +1,6 @@
-- Copyright (C) 2021, 2023 Ale
-- Copyright (C) 2021, 2024 Sandro del Toro
-- This file is part of Emeraldbank Minetest Mod.
@ -96,19 +96,3 @@ core.register_chatcommand("emeralds", {
end
end
})
-- experimental upgrade command
core.register_chatcommand("upgrade", {
description = S("Admin Command! Upgrade a shop"),
privs = {server=true},
func = function(name, param)
local player = core.get_player_by_name(name)
local pos = player:get_pos()
local nodename = core.get_node(pos).name
if nodename == "emeraldbank:shop" or nodename == "emeraldbank:shop_empty" then
emeraldbank.upgrade_shop(pos)
return true
end
return false
end
})

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
-- Copyright (C) 2021, 2023 Ale
-- Copyright (C) 2021, 2024 Sandro del Toro
-- This file is part of Emeraldbank Minetest Mod.
@ -72,44 +72,6 @@ function emeraldbank.update_accounts()
end
end
function emeraldbank.inv_emeralds_to_stonks(pos)
local meta = core.get_meta(pos)
local inv = meta:get_inventory()
local stonks = meta:get_int("stonks")
local fancy_inv = inv:get_list("main")
if not fancy_inv then return end
local has_emerald = inv:contains_item("main", "mcl_core:emerald 1", true)
if has_emerald then
meta:set_int("stonks", stonks+1)
inv:remove_item("main", "mcl_core:emerald 1")
emeraldbank.inv_emeralds_to_stonks(pos)
return true
else
return false
end
end
function emeraldbank.get_stonks(pos)
local meta = core.get_meta(pos)
local owner = meta:get_string("owner")
local player = core.get_player_by_name(owner)
local is_online = core.player_exists(owner)
emeraldbank.inv_emeralds_to_stonks(pos)
local stonks = meta:get_int("stonks")
if not player or player.is_fake_player then return end
if is_online and stonks > 0 then
core.sound_play("cash", {
to_player = owner,
gain = 1.0,
fade = 0.0,
pitch = 1.0,
})
emeraldbank.add_emeralds(player, stonks)
meta:set_int("stonks", 0)
core.chat_send_player(owner, S("You've earned @1 Emeralds with your shops.", stonks))
end
end
function emeraldbank.transfer_emeralds(player1, player2, num)
-- Determine player names based on whether input is a string or player object
local name1 = type(player1) == "string" and player1 or player1:get_player_name()
@ -154,71 +116,3 @@ function emeraldbank.transfer_emeralds(player1, player2, num)
core.chat_send_player(name1, S("Invalid pay"))
end
end
function emeraldbank.upgrade_shop(pos)
local oldnode = core.get_node(pos)
local old_meta = core.get_meta(pos)
local old_meta_table = core.get_meta(pos):to_table()
local nodename = core.get_node(pos).name
local old_inv = old_meta:get_inventory()
local old_list = old_inv:get_list("stock")
local old_stack = old_inv:get_stack("stock", 1)
-- set the new shop node
core.swap_node(pos, {name = "fancy_vend:player_vendor"})
-- setup the new shop node
-- Set variables for access later (for various checks, etc.)
pos.y = pos.y + 1
-- local above_node = minetest.get_node(pos).name
-- -- If node above is air or the display node, and it is not protected, attempt to place the vendor. If vendor sucessfully places, place display node above, otherwise alert the user
-- if (minetest.registered_nodes[above_node].buildable_to or above_node == "fancy_vend:display_node") and not minetest.is_protected(pos, owner) then
-- if above_node ~= "fancy_vend:display_node" then
-- minetest.set_node(pos, minetest.registered_nodes["fancy_vend:display_node"])
-- end
-- Set owner
local owner = old_meta:get_string("owner") or ""
local meta = minetest.get_meta(pos)
meta:set_string("owner", owner)
-- Set default meta
meta:set_string("log", minetest.serialize({"Vendor placed by "..owner,}))
emeraldbank.reset_vendor_settings(pos)
emeraldbank.refresh_vendor(pos)
if minetest.get_modpath("pipeworks") then
pipeworks.after_place(pos)
end
-- copy old metadata in new node
core.get_meta(pos):from_table(old_meta_table)
-- new node
local node = core.get_node(pos)
local meta = core.get_meta(pos)
local count = meta:get_int("count")
local price = meta:get_int("price")
local shop_item = meta:get_string("shop_item")
local settings = emeraldbank.get_vendor_settings(pos)
-- settings
settings.input_item = "mcl_core:emerald"
settings.input_item_qty = price
settings.output_item = shop_item
settings.output_item_qty = count
-- inv
-- local inv = meta:get_inventory()
-- inv:set_size("main", 15*6)
-- inv:set_size("wanted_item", 1*1)
-- inv:set_size("given_item", 1*1)
-- inv:set_stack("main", i, old_stack)
emeraldbank.set_vendor_settings(pos, settings)
emeraldbank.refresh_vendor(pos)
end

@ -1,6 +1,6 @@
-- Copyright (C) 2021, 2023 Ale
-- Copyright (C) 2021, 2024 Sandro del Toro
-- This file is part of Emeraldbank Minetest Mod.

@ -41,8 +41,6 @@ dofile(modpath .. "/forms.lua") -- file adapted from atm mod
dofile(modpath .. "/receive_fields.lua") -- file adapted from atm mod
dofile(modpath .. "/receive_fields_wt.lua") -- file from atm mod
dofile(modpath .. "/bank.lua")
dofile(modpath .. "/shop.lua")
dofile(modpath .. "/fancyshop.lua") -- file adapted from fancy_vend mod.
dofile(modpath .. "/commands.lua")
dofile(modpath .. "/hud.lua")

@ -1,5 +1,5 @@
name = emeraldbank
depends = mcl_core, mcl_sounds, mcl_inventory, mcl_formspec, mcl_title
optional_depends = irc, yl_matterbridge, pipeworks, digilines, awards, hopper, tell, email, mail, beerchat
description = Keep your Emeralds in a bank! And trade with shops.
supported_games = mineclonia, mineclone2
optional_depends = irc, yl_matterbridge, awards, mail, beerchat
description = Keep your Emeralds in a bank!.
supported_games = mineclonia

@ -21,23 +21,3 @@ emeraldbank.income_period (time between income) int 1800
# Length of time (in seconds) between updating emeralds player HUD
emeraldbank.hud_time (HUD update time) int 3
[Shops]
# If true shop can be crafted
emeraldbank.shop_craft (shop craft) bool true
# If true old shop can be crafted
emeraldbank.old_shop_craft (old shop craft) bool false
# The node to copy as the display node
fancy_vend.display_node (Display Node) string mcl_core:glass
# Maximum number of mods to store per vender
fancy_vend.log_max (Log Max) int 40
# Speed of display item auto rotation
fancy_vend.autorotate_speed (Autorotate Speed) int 1
# Whether to not send mail alerts
fancy_vend.no_alerts (Don't Send Mail Alerts) bool false

327
shop.lua

@ -1,327 +0,0 @@
-- Copyright (C) 2021, 2023 Ale
-- 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 Affero 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 Affero General Public License for more details.
-- You should have received a copy of the GNU Affero General Public License
-- along with Emeraldbank. If not, see <https://www.gnu.org/licenses/>.
local S = core.get_translator(core.get_current_modname())
local oldshopcraft = core.settings:get_bool("emeraldbank.old_shop_craft") or false
-- privilege
core.register_privilege("admin_shop", {
description = S("Enables the user to set regular vendors to admin vendors, or edit other players shops."),
give_to_singleplayer = false,
})
emeraldbank.shop_timer = 5
local shop_timer = emeraldbank.shop_timer
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 count = meta:get_int("count")
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 = ""
local is_admin = core.check_player_privs(pname, {admin_shop=true})
if (pname == owner or is_admin) 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,2;2,1;count;"..S("Count")..";"..count.."]"..
"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[5,1.5;"..S("x @1", count).."]"..
"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 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 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()
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 check_empty(pos)
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
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()
emeraldbank.get_stonks(pos)
--if nodename == "emeraldbank:shop" or 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)
emeraldbank.get_stonks(pos)
end
local function on_metadata_inventory_put(pos, listname, index, stack, player)
set_item(pos, stack, player) -- this func already show the fs
check_empty(pos)
end
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
check_empty(pos)
end
local function on_metadata_inventory_take(pos, listname, index, stack, player)
-- check_empty(pos) -- CRASH
core.show_formspec(player:get_player_name(), formspec_prefix..core.pos_to_string(pos), emeraldbank.get_shop_fs(pos, player) )
end
local function on_timer(pos, elapsed)
core.get_node_timer(pos):start(shop_timer)
check_empty(pos)
emeraldbank.get_stonks(pos)
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()
return inv:is_empty("stock") and (pname == owner or is_admin)
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},
sounds = mcl_sounds.node_sound_wood_defaults(),
_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
})
-- 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, 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
})
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_count = meta:get_int("count")
local new_count = tonumber(fields.count)
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()
atm.read_account(name)
local bankemeralds = atm.balance[name]
-- set or reset timer
core.get_node_timer(pos):start(shop_timer)
-- set item count
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)
end
end
-- set price
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
-- someone hit exchange button
if fields.exchange ~= nil and fields.exchange ~= "" then
-- owner try exchanges
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 can_exchange = true
-- have u money?
if bankemeralds < old_price then
can_exchange = false
core.chat_send_player(name, S("Not enough Emeralds in your account"))
end
--there are enough items?
if not minv:contains_item("stock", shop_item.." "..old_count, true) then
can_exchange = false
core.chat_send_player(name, S("Out of Stock!"))
end
-- do not trade air
if shop_item == "" or shop_item == "air" then
can_exchange = false
end
if can_exchange then
minv:remove_item("stock", shop_item.." "..old_count)
core.add_item(player_pos, shop_item.." "..old_count)
emeraldbank.add_emeralds(sender, -old_price)
meta:set_int("stonks", meta:get_int("stonks")+old_price)
mcl_title.set(sender, "subtitle", {text=S("Exchanged!"), color="green"})
check_empty(pos)
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)
if oldshopcraft 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B