From 6563758dad6f3f7506138a1e359d41826fd1459e Mon Sep 17 00:00:00 2001 From: Guill4um gamer Date: Thu, 22 Oct 2020 15:07:52 +0000 Subject: [PATCH] adding a second spawnpoint associated with a privilege --- README.md | 16 ++++-- init.lua | 142 ++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 128 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 605972c..e85f627 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,23 @@ The most unique thing about this spawn mod is that it includes a feature allowin ### Commands - `/spawnpoint`: Display spawnpoint position if set (also see configuration section) -- `/spawn `: Teleports you or the player specified to the spawnpoint (requires `spawn` privilege, and `bring` privilege to teleport another player) -- `/setspawn `: Sets the spawn to the position specified (in format `x, y, z`) or to your current location (requires `server` privilege) +- `/spawn`: Teleports you to your spawnpoint +- `/spawn `: Teleports the player specified to the spawnpoint (requires `spawn` privilege, and `bring` privilege to teleport another player) +- `/setspawn`: Sets the spawn to your current location (requires `server` privilege) +- `/setspawn `: Sets the spawn to the position specified (in format `x, y, z`) (requires `server` privilege) +- `/setspawn `: Sets the **second spawn position associated with the privilege** (if exists) to your current location (requires `server` privilege) all playgers with that privs will be forced to /spawn there __Note:__ If no spawnpoint is specified and a player attempts to execute `/spawn`, he/she will be told "No spawnpoint set!" ### Configuration The different "variables" of SpawnPoint can be configured per-world using the `/spawnpoint` command (requires server privilege). This command displays the spawnpoint if no parameters are provided, but when a setting name is provided, the value of the setting is returned (assuming such a setting exists). If a setting name and value is provided, the setting is changed. Valid setting names are listed below. -* `time`: Time before teleportation is completed (if `0` teleportation is immediate) -* `do_not_move`: Whether a player should be required to not move to allow teleportation to be successful -* `pos`: Position in the format `(,,)` - can only be set via `/setspawn` or manually in configuration files +* `time`: Time before teleportation is completed (if `0` teleportation is immediate) (ex: write=`/spawnpoint time 10` read=`/spawnpoint time`) +* `do_not_move`: Whether a player should be required to not move to allow teleportation to be successful (ex: write=`/spawnpoint do_not_move true` read=`/spawnpoint do_not_move`) +* `pos`: Position in the format `(,,)` - can only be set via `/setspawn` or manually in configuration files (ex: write`/setspawn 10,20,30` read=`/spawnpoint`) + +you can adjust the same parameter for the second spawnpoint linked to the privilege addin the privilege name as thrid parameter (ex: /spawnpoint time 10 sandbox) + This per-world configuration (including the spawn position itself) is stored in the world directory. If Minetest 0.4.16's new modstorage is available, SpawnPoint will use that to store configuration. Otherwise, configuration will be handled by the Minetest `Settings` API and placed in a `spawnpoint.conf` file. If you would like to configure SpawnPoint manually, create a `spawnpoint.conf` file in the world directory and assign values to the applicable settings as documented above, each setting on a new line in the format `setting_name = setting_value`. diff --git a/init.lua b/init.lua index 9fc8616..18eaf58 100644 --- a/init.lua +++ b/init.lua @@ -73,6 +73,12 @@ function spawnpoint.load() spawnpoint.pos = minetest.string_to_pos(pos) end + local privilegespawnpoint = data:get("privilegespawnpoint") + if privilegespawnpoint then + spawnpoint.privilegespawnpoint = minetest.deserialize(privilegespawnpoint) + end + + if storage then os.remove(path) end @@ -82,6 +88,11 @@ function spawnpoint.load() spawnpoint.pos = minetest.string_to_pos(pos) end + local privilegespawnpoint = storage:get_string("privilegespawnpoint") + if privilegespawnpoint then + spawnpoint.privilegespawnpoint = minetest.deserialize(privilegespawnpoint) + end + local do_not_move = storage:get_string("do_not_move") if do_not_move == "true" or do_not_move == true then spawnpoint.do_not_move = true @@ -107,6 +118,11 @@ function spawnpoint.load() spawnpoint.pos = minetest.string_to_pos(res[3]) end + if res[4] then + spawnpoint.privilegespawnpoint = minetest.deserialize(res[4]) + end + + f:close() -- Clear file os.remove(path) @@ -124,6 +140,10 @@ function spawnpoint.save() storage:set_string("pos", minetest.pos_to_string(spawnpoint.pos)) end + if spawnpoint.privilegespawnpoint then + storage:set_string("privilegespawnpoint", minetest.serialize(spawnpoint.privilegespawnpoint)) + end + return true elseif data then data:set("time", tostring(spawnpoint.time)) @@ -133,33 +153,64 @@ function spawnpoint.save() data:set("pos", minetest.pos_to_string(spawnpoint.pos)) end + if spawnpoint.privilegespawnpoint then + data:set("privilegespawnpoint", minetest.serialize(spawnpoint.privilegespawnpoint)) + end + data:write() return true end end -- [function] Set -function spawnpoint.set(pos) +function spawnpoint.set(pos,privilege) if type(pos) == "string" then pos = minetest.string_to_pos(pos) end if type(pos) == "table" then - spawnpoint.pos = pos + if privilege then + spawnpoint.privilegespawnpoint = {} + spawnpoint.privilegespawnpoint.pos = pos + spawnpoint.privilegespawnpoint.privilege = privilege + spawnpoint.log("Set a second spawnpoint to "..minetest.pos_to_string(pos).." associated to privilege "..privilege) + else + spawnpoint.pos = pos + spawnpoint.log("Set spawnpoint to "..minetest.pos_to_string(pos)) + end spawnpoint.save() - spawnpoint.log("Set spawnpoint to "..minetest.pos_to_string(pos)) end end -- [function] Bring -function spawnpoint.bring(player) +function spawnpoint.bring(player,forcePrivilegeSpawnpoint) -- forcePrivilegeSpawnpoint used in area mod + forcePrivilegeSpawnpoint = forcePrivilegeSpawnpoint or false if type(player) == "string" then player = minetest.get_player_by_name(player) end - - if player and spawnpoint.pos then - local pos = spawnpoint.pos - player:setpos({x=pos.x, y=pos.y+0.5, z=pos.z}) + if player then + local is_bring_to_privilegespawnpoint = false + local is_privilegespawnpoint = spawnpoint.privilegespawnpoint and spawnpoint.privilegespawnpoint.privilege + if is_privilegespawnpoint then + local is_priv = minetest.check_player_privs(player, {[spawnpoint.privilegespawnpoint.privilege] = true }) + if forcePrivilegeSpawnpoint or is_priv then + is_priv = minetest.check_player_privs(player, {server = true }) + if not is_priv then + is_bring_to_privilegespawnpoint = true + end + end + end + if is_bring_to_privilegespawnpoint then + local pos = spawnpoint.privilegespawnpoint.pos + if pos then + player:setpos({x=pos.x, y=pos.y+0.5, z=pos.z}) + end + else + local pos = spawnpoint.pos + if pos then + player:setpos({x=pos.x, y=pos.y+0.5, z=pos.z}) + end + end end end @@ -259,17 +310,24 @@ minetest.register_chatcommand("setspawn", { privs = {server=true}, func = function(name, param) local pos = minetest.get_player_by_name(name):getpos() + local privilege = nil if param then local ppos = minetest.string_to_pos(param) if type(ppos) == "table" then pos = ppos + elseif minetest.registered_privileges[param] then -- define a /setspawn cmd only with player pos (cant put pos in parameter) + privilege = param end end pos = vector.round(pos) - spawnpoint.set(pos) + spawnpoint.set(pos,privilege) - return true, "Set spawnpoint to "..minetest.pos_to_string(pos) + if privilege then + return true, "Set a second spawnpoint to "..minetest.pos_to_string(pos).." associated to privilege "..privilege + else + return true, "Set default spawnpoint to "..minetest.pos_to_string(pos) + end end, }) @@ -281,7 +339,7 @@ minetest.register_chatcommand("spawn", { local player = minetest.get_player_by_name(name) if param ~= "" then local pplayer = minetest.get_player_by_name(param) - if pplayer and minetest.check_player_privs(pplayer, {bring=true}) then + if pplayer and minetest.check_player_privs(player, {bring=true}) then player = pplayer else return false, "Cannot teleport another player to spawn without bring privilege" @@ -300,7 +358,20 @@ minetest.register_chatcommand("spawn", { minetest.register_chatcommand("spawnpoint", { description = "Get/Set SpawnPoint information", func = function(name, param) - if not param or param == "" then + local is_privilegespawnpoint = spawnpoint.privilegespawnpoint ~= nil + if is_privilegespawnpoint then + local is_priv = minetest.check_player_privs(player, {[spawnpoint.privilegespawnpoint.privilege] = true }) + if (is_privilegespawnpoint and is_priv) then + if not param or param == "" then + local pos = "Not set!" + if spawnpoint.privilegespawnpoint.pos then + pos = minetest.pos_to_string(spawnpoint.pos) + end + return true, "SpawnPoint Position: "..pos + end + end + + elseif not param or param == "" then local pos = "Not set!" if spawnpoint.pos then pos = minetest.pos_to_string(spawnpoint.pos) @@ -309,29 +380,50 @@ minetest.register_chatcommand("spawnpoint", { return true, "SpawnPoint Position: "..pos elseif minetest.check_player_privs(minetest.get_player_by_name(name), {server=true}) then local p = param:split(" ") - + local is_privilegespawnpoint = minetest.registered_privileges[p[3]] ~= nil and spawnpoint.privilegespawnpoint ~= nil if p[1] == "time" then local num = tonumber(p[2]) if not num then - return true, "SpawnPoint->time: "..dump(spawnpoint.time) - elseif num == spawnpoint.time then - return false, "Time already set to "..p[2].."!" + if is_privilegespawnpoint then + return true, "SpawnPoint "..p[3].." ->time: "..dump(spawnpoint.privilegespawnpoint.time) + else + return true, "SpawnPoint->time: "..dump(spawnpoint.time) + end else - spawnpoint.time = num - spawnpoint.save() - spawnpoint.log("Set time to "..dump(num)) - return true, "Set time to "..dump(num) + if is_privilegespawnpoint then + spawnpoint.privilegespawnpoint.time = num + spawnpoint.save() + spawnpoint.log("Set time to "..dump(num).." for "..p[3].."spawn point") + return true, "Set time to "..dump(num).." for "..p[3].."spawn point" + else + spawnpoint.time = num + spawnpoint.save() + spawnpoint.log("Set time to "..dump(num)) + return true, "Set time to "..dump(num) + end end elseif p[1] == "do_not_move" then local move = minetest.is_yes(p[2]) if move == nil or not p[2] then - return true, "SpawnPoint->do_not_move: "..dump(spawnpoint.do_not_move) + if is_privilegespawnpoint then + return true, "SpawnPoint "..p[3].." ->do_not_move: "..dump(spawnpoint.privilegespawnpoint.do_not_move) + else + return true, "SpawnPoint->do_not_move: "..dump(spawnpoint.do_not_move) + end else - spawnpoint.do_not_move = move - spawnpoint.save() - spawnpoint.log("Set do_not_move to "..dump(move)) - return true, "Set do_not_move to "..dump(move) + if is_privilegespawnpoint then + spawnpoint.privilegespawnpoint.do_not_move = move + spawnpoint.save() + spawnpoint.log("Set do_not_move to "..dump(move).." for "..p[3].."spawn point") + return true, "Set do_not_move to "..dump(move).." for "..p[3].."spawn point" + else + spawnpoint.do_not_move = move + spawnpoint.save() + spawnpoint.log("Set do_not_move to "..dump(move)) + return true, "Set do_not_move to "..dump(move) + end + end end end