commit
This commit is contained in:
commit
eedd923582
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Xeno333/TX_Miner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
94
init.lua
Normal file
94
init.lua
Normal file
@ -0,0 +1,94 @@
|
||||
shopping = {}
|
||||
shopping.storage = minetest.get_mod_storage()
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
dofile(modpath.."/player_to_player_shop.lua")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_privilege("server_shop_admin", {
|
||||
description = "Lets player remove, add things to server shop, or nuke shop",
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("buy", {
|
||||
params = "<index>",
|
||||
description = "Buy from shop.",
|
||||
privs = {
|
||||
interact = true,
|
||||
},
|
||||
func = function(name, index)
|
||||
index = tonumber(index)
|
||||
if (not name) or (not index) then
|
||||
return false, "Bad args!"
|
||||
end
|
||||
|
||||
return shopping.buy(name, index)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("shop", {
|
||||
description = "Show shop.",
|
||||
privs = {
|
||||
interact = true,
|
||||
},
|
||||
func = function(name)
|
||||
if not name then
|
||||
return false, "Bad args!"
|
||||
end
|
||||
|
||||
return shopping.shop(name, 1)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("nukeshop", {
|
||||
description = "Clears shop",
|
||||
privs = {
|
||||
server_shop_admin = true,
|
||||
},
|
||||
func = function()
|
||||
local mod_storage = shopping.storage
|
||||
mod_storage:set_string("shop", minetest.serialize({}))
|
||||
return true, "Shop nuked!"
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("sell", {
|
||||
params = "<price>",
|
||||
description = "List for sale in player to player shop.",
|
||||
privs = {
|
||||
interact = true,
|
||||
},
|
||||
func = function(name, price)
|
||||
if (not name) then
|
||||
return false, "Bad args!"
|
||||
end
|
||||
|
||||
--get price
|
||||
local num_price = tonumber(price)
|
||||
if not num_price then
|
||||
return false, "Invalid price"
|
||||
end
|
||||
local player = minetest.get_player_by_name(name)
|
||||
|
||||
-- make sure player is valid
|
||||
if not player then
|
||||
return false, "Player not found."
|
||||
end
|
||||
-- get item_stack
|
||||
local item_stack = player:get_wielded_item()
|
||||
if item_stack:is_empty() then
|
||||
return false, "You are not holding any item."
|
||||
end
|
||||
|
||||
return shopping.sell(name, item_stack, num_price)
|
||||
end
|
||||
})
|
3
mod.conf
Normal file
3
mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = shopping
|
||||
description = A shopping mod for Jean's Economy (By TX_Miner aka Xeno333)
|
||||
depends = default, jeans_economy
|
224
player_to_player_shop.lua
Normal file
224
player_to_player_shop.lua
Normal file
@ -0,0 +1,224 @@
|
||||
|
||||
shopping.items_per_page = 48
|
||||
|
||||
|
||||
|
||||
|
||||
local function give_item_to_player(player_name, item_stack)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if not player then
|
||||
-- Player not found, handle error
|
||||
return false
|
||||
end
|
||||
|
||||
local inv = player:get_inventory()
|
||||
if not inv:room_for_item("main", item_stack) then
|
||||
-- Player does not have enough room for the item stack
|
||||
minetest.chat_send_player(player_name, "Not enough room in your inventory.")
|
||||
return false
|
||||
end
|
||||
|
||||
inv:add_item("main", item_stack)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function remove_entry(list, index)
|
||||
-- Shift elements to the left starting from the removed index
|
||||
for i = index, #list - 1 do
|
||||
list[i] = list[i + 1]
|
||||
end
|
||||
-- Remove the last element (which is now a duplicate)
|
||||
list[#list] = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function add_item_to_shop(itemstack, price, name)
|
||||
local mod_storage = shopping.storage
|
||||
local shop = minetest.deserialize(mod_storage:get_string("shop")) or {}
|
||||
|
||||
shop[#shop + 1] = {itemstack:to_string(), price, name}
|
||||
|
||||
mod_storage:set_string("shop", minetest.serialize(shop))
|
||||
return true, "Item listed!"
|
||||
end
|
||||
|
||||
local function get_item_from_shop(name, index)
|
||||
local mod_storage = shopping.storage
|
||||
local shop = minetest.deserialize(mod_storage:get_string("shop")) or {}
|
||||
|
||||
if (index == 0) or (index > #shop) then
|
||||
return false, "Invalid index!"
|
||||
end
|
||||
|
||||
|
||||
privs = minetest.get_player_privs(name)
|
||||
if privs["server_shop_admin"] then
|
||||
if give_item_to_player(name, shop[index][1]) then
|
||||
remove_entry(shop, index)
|
||||
else
|
||||
return false, "Failed!"
|
||||
end
|
||||
|
||||
mod_storage:set_string("shop", minetest.serialize(shop))
|
||||
return true, "Item bought as admin!"
|
||||
end
|
||||
|
||||
|
||||
if (jeans_economy.get_account(name) < shop[index][2]) and (not name == shop[index][3]) then
|
||||
return false, "You don't have enough money!"
|
||||
else
|
||||
if not name == shop[index][3] then
|
||||
jeans_economy.book(name, shop[index][3], shop[index][2], name .. " bought item for " .. shop[index][2])
|
||||
end
|
||||
|
||||
if give_item_to_player(name, shop[index][1]) then
|
||||
remove_entry(shop, index)
|
||||
else
|
||||
return false, "Failed!"
|
||||
end
|
||||
|
||||
mod_storage:set_string("shop", minetest.serialize(shop))
|
||||
return true, "Item bought!"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Buy
|
||||
function shopping.buy(name, index)
|
||||
return get_item_from_shop(name, index)
|
||||
end
|
||||
|
||||
|
||||
-- Shop
|
||||
function shopping.shop(name, page)
|
||||
local mod_storage = shopping.storage
|
||||
local shop = minetest.deserialize(mod_storage:get_string("shop")) or {}
|
||||
|
||||
local formspec = "size[9,8.5]" -- Increased width to accommodate the scrollbar
|
||||
formspec = formspec .. "label[4.2,0;Shop]" -- Title of the formspec
|
||||
formspec = formspec .. "button_exit[0.2,0.2;2,1;close;Close]" -- Add a Close button
|
||||
|
||||
-- Pagination logic
|
||||
local total_pages = math.ceil(#shop / shopping.items_per_page)
|
||||
page = page or 1 -- Ensure page is initialized
|
||||
local start_index = (page - 1) * shopping.items_per_page + 1
|
||||
local end_index = math.min(page * shopping.items_per_page, #shop)
|
||||
|
||||
-- Display items in the shop for the current page
|
||||
local row = 1
|
||||
local col = 0
|
||||
for i = start_index, end_index do
|
||||
if col == 8 then
|
||||
col = 0
|
||||
row = row + 1
|
||||
end
|
||||
local item_stack = shop[i][1]
|
||||
local price = shop[i][2]
|
||||
local seller_name = shop[i][3]
|
||||
formspec = formspec .. "item_image_button[" .. col .. "," .. row .. ";1,1;" .. item_stack .. ";buy_" .. i .. ";" .. "$" .. price .. "]"
|
||||
col = col + 1
|
||||
end
|
||||
|
||||
-- Previous page button
|
||||
if page > 1 then
|
||||
formspec = formspec .. "button[0,8;2,1;prev;<< Prev]"
|
||||
end
|
||||
-- Next page button
|
||||
if page < total_pages then
|
||||
formspec = formspec .. "button[7,8;2,1;next;Next >>]"
|
||||
end
|
||||
|
||||
formspec = formspec .. "field[3.5,8;2,1;page;;" .. page .. "]" -- Add a hidden field to hold the current page
|
||||
|
||||
minetest.show_formspec(name, "shopping:shop_formspec", formspec)
|
||||
end
|
||||
|
||||
-- Register a callback to handle button clicks in the shop formspec
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname == "shopping:shop_formspec" then
|
||||
local player_name = player:get_player_name()
|
||||
local page = tonumber(fields.page) or 1
|
||||
|
||||
|
||||
if fields.next then
|
||||
page = page + 1
|
||||
shopping.shop(player_name, page)
|
||||
return
|
||||
elseif fields.prev then
|
||||
page = page - 1
|
||||
shopping.shop(player_name, page)
|
||||
return
|
||||
elseif fields.close then
|
||||
return
|
||||
end
|
||||
for field, _ in pairs(fields) do
|
||||
if field:sub(1, 4) == "buy_" then
|
||||
local index = tonumber(field:sub(5))
|
||||
if index then
|
||||
local success, s = shopping.buy(player_name, index)
|
||||
minetest.chat_send_player(player_name, s)
|
||||
shopping.shop(player_name, page)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif fields.page then
|
||||
local mod_storage = shopping.storage
|
||||
local shop = minetest.deserialize(mod_storage:get_string("shop")) or {}
|
||||
local total_pages = math.ceil(#shop / shopping.items_per_page)
|
||||
|
||||
if page < 1 then
|
||||
page = 1
|
||||
elseif page > 1 then
|
||||
page = total_pages
|
||||
end
|
||||
|
||||
shopping.shop(player_name, page)
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- I had to insult AI to figure this out -_-
|
||||
local function remove_held_item(player_name)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if not player then
|
||||
-- Player not found, handle error
|
||||
return
|
||||
end
|
||||
|
||||
local wielded_item = player:get_wielded_item()
|
||||
|
||||
if wielded_item:is_empty() then
|
||||
-- Player is not holding anything, no need to remove
|
||||
return
|
||||
end
|
||||
|
||||
local inv = player:get_inventory()
|
||||
local wielded_index = player:get_wield_index()
|
||||
|
||||
-- Remove the wielded item from the player's inventory
|
||||
inv:set_stack("main", wielded_index, ItemStack(nil))
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Sell
|
||||
function shopping.sell(name, itemstack, price)
|
||||
rc, s = add_item_to_shop(itemstack, price, name)
|
||||
remove_held_item(name)
|
||||
return rc, s
|
||||
--return true, player_name .. " listed " .. item_name .. " for " .. price
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user