From 4cee9a86ac6fcde65dc2855a716b52f4437323f0 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 30 Mar 2012 20:54:57 +0300 Subject: [PATCH] Improved teleport command --- builtin/builtin.lua | 105 ++++++++++++++++++++++++++++++++++++++++-- doc/lua_api.txt | 3 ++ src/servercommand.cpp | 46 ------------------ 3 files changed, 105 insertions(+), 49 deletions(-) diff --git a/builtin/builtin.lua b/builtin/builtin.lua index 45119be4..0cb76439 100644 --- a/builtin/builtin.lua +++ b/builtin/builtin.lua @@ -868,6 +868,7 @@ end minetest.register_privilege("interact", "Can interact with things and modify the world") minetest.register_privilege("teleport", "Can use /teleport command") +minetest.register_privilege("bring", "Can teleport other players") minetest.register_privilege("settime", "Can use /time") minetest.register_privilege("privs", "Can modify privileges") minetest.register_privilege("server", "Can do server maintenance stuff") @@ -892,8 +893,8 @@ end -- Register the help command minetest.register_chatcommand("help", { privs = {}, - params = "(nothing)/all/", - description = "Get help for commands", + params = "(nothing)/all/privs/", + description = "Get help for commands or list privileges", func = function(name, param) local format_help_line = function(cmd, def) local msg = "/"..cmd @@ -918,6 +919,11 @@ minetest.register_chatcommand("help", { minetest.chat_send_player(name, format_help_line(cmd, def)) end end + elseif param == "privs" then + minetest.chat_send_player(name, "Available privileges:") + for priv, desc in pairs(minetest.registered_privileges) do + minetest.chat_send_player(name, priv..": "..desc) + end else local cmd = param def = minetest.chatcommands[cmd] @@ -937,7 +943,6 @@ minetest.register_chatcommand("shutdown", {params = "", description = "shutdown minetest.register_chatcommand("setting", {params = " = ", description = "set line in configuration file", privs = {server=true}}) minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}}) minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}}) -minetest.register_chatcommand("teleport", {params = ",,", description = "teleport to given position", privs = {teleport=true}}) minetest.register_chatcommand("ban", {params = "", description = "ban IP of player", privs = {ban=true}}) minetest.register_chatcommand("unban", {params = "", description = "remove IP ban", privs = {ban=true}}) @@ -1006,6 +1011,7 @@ minetest.register_chatcommand("setpassword", { return end minetest.set_player_password(name, param) + minetest.chat_send_player(name, "Password set") end, }) minetest.register_chatcommand("clearpassword", { @@ -1014,6 +1020,99 @@ minetest.register_chatcommand("clearpassword", { privs = {password=true}, func = function(name, param) minetest.set_player_password(name, '') + minetest.chat_send_player(name, "Password cleared") + end, +}) + +minetest.register_chatcommand("teleport", { + params = ",, | | ,, | ", + description = "teleport to given position", + privs = {teleport=true}, + func = function(name, param) + -- Returns (pos, true) if found, otherwise (pos, false) + local function find_free_position_near(pos) + local tries = { + {x=1,y=0,z=0}, + {x=-1,y=0,z=0}, + {x=0,y=0,z=1}, + {x=0,y=0,z=-1}, + } + for _, d in ipairs(tries) do + local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z} + local n = minetest.env:get_node(p) + if not minetest.registered_nodes[n.name].walkable then + return p, true + end + end + return pos, false + end + + local teleportee = nil + local p = {} + p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") + teleportee = minetest.env:get_player_by_name(name) + if teleportee and p.x and p.y and p.z then + minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + + local teleportee = nil + local p = nil + local target_name = nil + target_name = string.match(param, "^([^ ]+)$") + teleportee = minetest.env:get_player_by_name(name) + if target_name then + local target = minetest.env:get_player_by_name(target_name) + if target then + p = target:getpos() + end + end + if teleportee and p then + p = find_free_position_near(p) + minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + + if minetest.check_player_privs(name, {bring=true}) then + local teleportee = nil + local p = {} + local teleportee_name = nil + teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") + if teleportee_name then + teleportee = minetest.env:get_player_by_name(teleportee_name) + end + if teleportee and p.x and p.y and p.z then + minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + + local teleportee = nil + local p = nil + local teleportee_name = nil + local target_name = nil + teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$") + if teleportee_name then + teleportee = minetest.env:get_player_by_name(teleportee_name) + end + if target_name then + local target = minetest.env:get_player_by_name(target_name) + if target then + p = target:getpos() + end + end + if teleportee and p then + p = find_free_position_near(p) + minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + end + + minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)") + return end, }) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index a355f893..e253d2a2 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -540,6 +540,9 @@ minetest.after(time, func, param) ^ Call function after time seconds ^ param is optional; to pass multiple parameters, pass a table. +Random: +minetest.get_connected_players() -> list of ObjectRefs + Global objects: minetest.env - environment reference diff --git a/src/servercommand.cpp b/src/servercommand.cpp index 64c43d4f..f6088925 100644 --- a/src/servercommand.cpp +++ b/src/servercommand.cpp @@ -103,50 +103,6 @@ void cmd_setting(std::wostringstream &os, os<< L"-!- Setting changed and configuration saved."; } -void cmd_teleport(std::wostringstream &os, - ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "teleport")) - { - os<parms.size() != 2) - { - os< coords = str_split(ctx->parms[1], L','); - if(coords.size() != 3) - { - os<player->getName()<<" teleports from " - <player->getPosition()/BS)<<" to " - <player->getPlayerSAO(); - if(sao) - { - sao->setPos(dest); - os<< L"-!- Teleported."; - } - else - { - errorstream<<"Teleport failed, player object not found!" - <server->checkPriv(ctx->player->getName(), "ban")) @@ -240,8 +196,6 @@ std::wstring processServerCommand(ServerCommandContext *ctx) cmd_shutdown(os, ctx); else if(ctx->parms[0] == L"setting") cmd_setting(os, ctx); - else if(ctx->parms[0] == L"teleport") - cmd_teleport(os, ctx); else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban") cmd_banunban(os, ctx); else if(ctx->parms[0] == L"me") -- 2.30.2