-- 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 = " [ ]", 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").." , 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").." [], buy of item(s) currently holding in hand, when 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").." [], buy of from store, if is not provided then amount is 1\n".. minetest.colorize("#00FFFF", "/mp sellinv").." , sell all items 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 })