x_marketplace/chatcommands.lua

301 lines
11 KiB
Lua

-- Minetest API method. Adds definition to minetest.registered_chatcommands.
-- @param cmd the string - commnad name
-- @param chatcommand definition the table
minetest.register_chatcommand("mp", {
params = "<command> [<item name> <amount>]",
description = "Marketplace commands, type '/mp help' for more help.",
privs = { interact = true },
func = function(caller, param)
local params = {}
for substring in param:gmatch("%S+") do
table.insert(params, substring)
end
-- print("caller", dump(caller))
-- print("params", dump(params))
--
-- find
--
if params[1] == "find" then
local items = x_marketplace.store_find(params[2])
if not items then
return false, "Oops there is no item like this in the store. Check out other items in the store: "..x_marketplace.store_get_random()
end
return true, items
--
-- show balance
--
elseif params[1] == "balance" then
return true, "Your balance is: "..x_marketplace.get_player_balance(caller).." BitGold"
--
-- sell hand
--
elseif params[1] == "sellhand" then
local player = minetest.get_player_by_name(caller)
local hand = player:get_wielded_item()
local item_name = hand:get_name()
local item_count = hand:get_count()
local store_item = x_marketplace.store_list[item_name]
local itemstack = ItemStack({ name = item_name })
-- check what is the max items we can sell
if item_count > (itemstack:get_stack_max()) then
return false, "You can sell this item by max. of "..itemstack:get_stack_max().." item(s) at the time."
end
-- item exists in the store
if store_item then
player:set_wielded_item(ItemStack(""))
local sell_price = store_item.sell * item_count
local new_balance = x_marketplace.set_player_balance(caller, sell_price)
return true, "You sold "..item_count.." item(s) of "..item_name.." for "..sell_price.." BitGold. Your new balance is: "..new_balance.." BitGold"
else
-- item does not exists in the store
return false, "You cannot sell this item. Search in store for items you can sell, example: /mp find stone. See some suggestion from the store: "..x_marketplace.store_get_random()
end
--
-- info hand
--
elseif params[1] == "infohand" then
local player = minetest.get_player_by_name(caller)
local hand = player:get_wielded_item()
local item_name = hand:get_name()
local item_count = hand:get_count()
local store_item = x_marketplace.store_list[item_name]
-- item exists in the store
if store_item then
local sell_price = store_item.sell * item_count
return true, item_name.." buy: "..store_item.buy.." sell: "..store_item.sell..". You can sell the item(s) you are holding for: "..sell_price.." BitGold. example: /mp sellhand"
else
-- item does not exists in the store
return false, "This item is not in store. See some suggestion from the store: "..x_marketplace.store_get_random()
end
--
-- buy hand
--
elseif params[1] == "buyhand" then
local player = minetest.get_player_by_name(caller)
local hand = player:get_wielded_item()
local item_name = hand:get_name()
local store_item = x_marketplace.store_list[item_name]
local itemstack = ItemStack({ name = item_name })
-- item exists in the store
if store_item then
local amount = params[2] or 1
local inv = player:get_inventory("main")
local itemstack = ItemStack({
name = item_name,
count = amount
})
-- check if amount is a number
if not tonumber(amount) then
return false, "Amount of items must be a number. example: /mp buyhand "..math.random(1, 99)
end
-- check what is the max items we can buy
if tonumber(amount) > (itemstack:get_stack_max()) then
return false, "You can buy this item by max. of "..itemstack:get_stack_max().." item(s) at the time."
end
local buy_price = amount * store_item.buy
local new_balance = x_marketplace.set_player_balance(caller, buy_price * -1)
-- not enough money
if not new_balance then
return false, "You don't have enought BitGold. Price for "..amount.." item(s) of "..item_name.." is "..buy_price.." BitGold, but your current balance is: "..x_marketplace.get_player_balance(caller).." BitGold"
end
-- drop items what doesn't fit in the inventory
local leftover_item = inv:add_item("main", itemstack)
if leftover_item:get_count() > 0 then
local p = table.copy(player:get_pos())
p.y = p.y + 1.2
local obj = minetest.add_item(p, itemstack)
if obj then
local dir = player:get_look_dir()
dir.x = dir.x * 2.9
dir.y = dir.y * 2.9 + 2
dir.z = dir.z * 2.9
obj:set_velocity(dir)
obj:get_luaentity().dropped_by = caller
end
end
return true, "You bought "..amount.." item(s) of "..item_name.." for "..buy_price.." BitGold. Your new balance is: "..new_balance.." BitGold"
else
-- item does not exists in the store
return false, "This item is not in store. See some suggestion from the store: "..x_marketplace.store_get_random()
end
--
-- sell inventory
--
elseif params[1] == "sellinv" then
-- item name is missing from param[2]
if not params[2] then
return false, "You need to write the item name you want to sell. example: /mp sellinv default:stone. See some suggestion from the store: "..x_marketplace.store_get_random()
end
local player = minetest.get_player_by_name(caller)
local inv = player:get_inventory("main")
local store_item = x_marketplace.store_list[params[2]]
local amount = 0
-- item exists in the store
if store_item then
local itemstack = ItemStack({ name = params[2] })
for k, v in ipairs(inv:get_list("main")) do
if v:get_name() == params[2] and
v:get_count() <= itemstack:get_stack_max() then
local removed = inv:remove_item("main", v)
amount = amount + removed:get_count()
end
end
local sell_price = amount * store_item.sell
local new_balance = x_marketplace.set_player_balance(caller, sell_price)
return true, "You sold "..amount.." item(s) of "..params[2].." for "..sell_price.." BitGold. Your new balance is: "..new_balance.." BitGold"
else
-- item does not exists in the store
return false, "You cannot sell this item. Search in store for items you can sell, example: /mp find stone. See some suggestion from the store: "..x_marketplace.store_get_random()
end
--
-- buy
--
elseif params[1] == "buy" then
local item = params[2]
-- item name is missing from param[2]
if not item then
return false, "You need to write the item name you want to buy. example: /mp buy default:stone 10, or check out other items in the store: "..x_marketplace.store_get_random()
end
-- item not in store
if not x_marketplace.store_list[params[2]] then
local suggestions = x_marketplace.store_find(params[2])
local suggest = ""
-- try suggest item from store, else show random items
if suggestions then
suggest = "This item is not in store, check out other items from the store: \n"..suggestions
return false, suggest
else
-- still not found in the store - pick random
return false, "This item is not in store, check out other items from the store: "..x_marketplace.store_get_random()
end
end
-- add items to main inventory
local player = minetest.get_player_by_name(caller)
local store_item = x_marketplace.store_list[params[2]]
local amount = params[3] or 1
local inv = player:get_inventory("main")
local itemstack = ItemStack({
name = params[2],
count = amount
})
-- check if amount is a number
if not tonumber(amount) then
return false, "Amount of items must be a number. example: /mp buy default:stone 99"
end
-- check what is the max items we can buy
if tonumber(amount) > (itemstack:get_stack_max()) then
return false, "You can buy this item by max. of "..itemstack:get_stack_max().." item(s) at the time."
end
local buy_price = amount * store_item.buy
local new_balance = x_marketplace.set_player_balance(caller, buy_price * -1)
-- not enough money
if not new_balance then
return false, "You don't have enought BitGold. Price for "..amount.." item(s) of "..params[2].." is "..buy_price.." BitGold, but your current balance is: "..x_marketplace.get_player_balance(caller).." BitGold"
end
-- drop items what doesn't fit in the inventory
local leftover_item = inv:add_item("main", itemstack)
if leftover_item:get_count() > 0 then
local p = table.copy(player:get_pos())
p.y = p.y + 1.2
local obj = minetest.add_item(p, itemstack)
if obj then
local dir = player:get_look_dir()
dir.x = dir.x * 2.9
dir.y = dir.y * 2.9 + 2
dir.z = dir.z * 2.9
obj:set_velocity(dir)
obj:get_luaentity().dropped_by = caller
end
end
return true, "You bought "..amount.." item(s) of "..params[2].." for "..buy_price.." BitGold. Your new balance is: "..new_balance.." BitGold"
--
-- top 5 richest
--
elseif params[1] == "top" then
local players = minetest.get_connected_players()
local temp_tbl = {}
for k, v in ipairs(players) do
local pname = v:get_player_name()
local balance = x_marketplace.get_player_balance(pname)
table.insert(temp_tbl, { name = pname, balance = tonumber(balance) })
end
table.sort(temp_tbl, function(a, b) return a.balance > b.balance end)
local msg = ""
local length = 5
if length > #temp_tbl then
length = #temp_tbl
end
for i = 1, length do
msg = msg..i..". "..temp_tbl[i].name.."\n"
end
-- print(dump(temp_tbl))
return true, msg
--
-- help
--
elseif params[1] == "help" then
local msg =
minetest.colorize("#00FFFF", "/mp find").." <item name>, find item in store\n"..
minetest.colorize("#00FFFF", "/mp balance")..", show your current balance in BitGold\n"..
minetest.colorize("#00FFFF", "/mp sellhand")..", sell item(s) currently holding in hand\n"..
minetest.colorize("#00FFFF", "/mp buyhand").." [<amount>], buy <amount> of item(s) currently holding in hand, when <amount> is not provided then amount is 1\n"..
minetest.colorize("#00FFFF", "/mp infohand")..", show more information about the item(s) you are currently holding in hand from the store\n"..
minetest.colorize("#00FFFF", "/mp buy").." <item name> [<amount>], buy <amount> of <item name> from store, if <amount> is not provided then amount is 1\n"..
minetest.colorize("#00FFFF", "/mp sellinv").." <item name>, sell all items <item name> from the 'main' inventory list\n"..
minetest.colorize("#00FFFF", "/mp top")..", show top 5 richest players currently online\n"..
minetest.colorize("#00FFFF", "/mp help")..", print out this help\n"
-- print(msg)
return true, msg
end
end
})