added commands and reconcile original to guestlist

master
Tai Kedzierski 2019-01-23 22:45:48 +00:00
parent bbb82cc891
commit 9ea24ce8ce
4 changed files with 110 additions and 223 deletions

View File

@ -145,13 +145,6 @@ function rspawn:set_player_spawn(name, newpos)
return true
end
local function register_original_spawn(playername, pos)
if not rspawn.playerspawns["original spawns"] then
rspawn.playerspawns["original spawns"] = {}
end
rspawn.playerspawns["original spawns"][playername] = pos
end
function rspawn:set_newplayer_spawn(player)
-- only use for new players / players who have never had a randomized spawn
if not player then return end
@ -164,7 +157,6 @@ function rspawn:set_newplayer_spawn(player)
local newpos = rspawn:get_next_spawn()
if newpos then
register_original_spawn(playername, newpos)
rspawn:set_player_spawn(playername, newpos)
else

View File

@ -4,46 +4,13 @@ local cooldown_time = tonumber(minetest.settings:get("rspawn.cooldown_time")) or
-- Command privileges
minetest.register_privilege("spawn", "Can teleport to spawn position.")
minetest.register_privilege("setspawn", "Can manually set a spawn point")
minetest.register_privilege("spawn", "Can teleport to a spawn position and manage shared spawns.")
minetest.register_privilege("setspawn", "Can manually set a spawn point.")
minetest.register_privilege("newspawn", "Can get a new randomized spawn position.")
minetest.register_privilege("spawnadmin", "Can clean up timers and set new spawns for players.")
-- Support functions
local function splitstring(sdata, sep)
local idx
local tdata = {}
while sdata ~= "" do
idx = sdata:find(sep)
if idx then
tdata[#tdata+1] = sdata:sub(1,idx-1)
sdata = sdata:sub(idx+1, sdata:len() )
else -- last element
tdata[#tdata+1] = sdata
break
end
end
return tdata
end
local function set_original_spawn(tname)
local tpos = rspawn.playerspawns["original spawns"][tname]
if not tpos then
minetest.chat_send_player(tname, "Could not find your original spawn!")
elseif rspawn:consume_levvy(minetest.get_player_by_name(tname)) then
rspawn:set_player_spawn(tname, tpos)
else
minetest.chat_send_player(tname, "You do not have enough to pay the levvy. Aborting.")
end
end
local function request_new_spawn(username, targetname)
local timername = username
if targetname ~= username then
@ -67,12 +34,12 @@ end
-- Commands
minetest.register_chatcommand("spawn", {
description = "Teleport to spawn position, or manage invitations. See you current invitation with '/spawn invite'. If you are a guest at a spawn, return to your orgiinal spawn with '/spawn original'",
params = "[ invite [<player>] | accept | decline | original ]",
description = "Teleport to your spawn, or manage guests in your spawn.",
params = "[ add <player> | visit <player> | kick <player> | guests | hosts ]",
privs = "spawn",
func = function(name, args)
func = function(playername, args)
local target = rspawn.playerspawns[name]
local args = splitstring(args, " ")
local args = args:split(" ")
if #args == 0 then
if target then
@ -83,29 +50,24 @@ minetest.register_chatcommand("spawn", {
minetest.chat_send_player(name, "You have no spawn position!")
return
end
elseif #args < 3 then
for command,action in pairs({
["guests"] = function() rspawn.invites:listguests(playername) end,
["hosts"] = function() rspawn.invites:listhosts(playername) end,
["add"] = function(commandername,targetname) rspawn.invites:addplayer(commandername,targetname) end,
["visit"] = function(commandername,targetname) rspawn.invites:visitplayer(targetname, commandername) end,
["kick"] = function(commandername,targetname) rspawn.invites:exileplayer(commandername, targetname) end,
}) do
elseif args[1] == "accept" then
rspawn.invites:accept(name)
return
elseif args[1] == "decline" then
rspawn.invites:decline(name)
return
elseif args[1] == "original" then
set_original_spawn(name)
return
elseif args[1] == "invite" then
if #args == 2 then
rspawn.invites:invite_player_fromto(name, args[2])
return
elseif #args == 1 then
rspawn.invites:show_invite_for(name)
return
if args[1] == command then
if #args == 2 then
action(playername, args[2])
else
action()
end
return
end
end
end
minetest.chat_send_player(name, "Please check '/help spawn'")
@ -133,32 +95,18 @@ minetest.register_chatcommand("newspawn", {
})
minetest.register_chatcommand("playerspawn", {
description = "Randomly select a new spawn position for a player, or use specified position, 'original' for their original spawn.",
params = "<playername> { new | <pos> | original | setoriginal | go }",
description = "Randomly select a new spawn position for a player, or use specified position, or go to their spawn.",
params = "<playername> { new | <pos> | go }",
privs = "spawnadmin",
func = function(name, args)
if args ~= "" then
args = splitstring(args, " ")
args = args:splitstring(" ")
if #args == 2 then
local tname = args[1]
local tpos
if args[2] == "original" then
tpos = rspawn.playerspawns["original spawns"][tname]
if not tpos then
minetest.chat_send_player( name, "Could not find original spawn for "..tname)
minetest.chat_send_player(tname, "Could not find original spawn for "..tname)
return
end
elseif args[2] == "setoriginal" then
rspawn.playerspawns["original spawns"][tname] = rspawn.playerspawns[tname]
minetest.chat_send_player(name, "Saved "..tname..
"'s spawn "..minetest.pos_to_string(rspawn.playerspawns[tname])..
" as original.")
return
elseif args[2] == "go" then
if args[2] == "go" then
local user = minetest.get_player_by_name(name)
local dest = rspawn.playerspawns[args[1]]
if dest then
@ -168,18 +116,20 @@ minetest.register_chatcommand("playerspawn", {
minetest.chat_send_player(name, "No rspawn coords for "..args[1])
end
return
elseif args[2] == "new" then
request_new_spawn(name, args[1])
return
else
tpos = minetest.string_to_pos(args[2])
end
if tpos then
if not rspawn:set_player_spawn(tname, tpos) then
minetest.chat_send_player(name, name.."'s spawn could not be reset")
if tpos then
if not rspawn:set_player_spawn(tname, tpos) then
minetest.chat_send_player(name, name.."'s spawn could not be reset")
end
return
end
return
end
end
end

View File

@ -1,5 +1,13 @@
local spawnsfile = minetest.get_worldpath().."/dynamicspawns.lua.ser"
--[[ Reconcile functions
reconcile_original_spawns : convert from base implementation to invites with original spawns
reconcile_guestlist_spawns : convert from "original spawns" implementation to "guest lists"
--]]
-- Comatibility with old behaviour - players whose original spawns had not been registered receive the one they are now using
local function reconcile_original_spawns()
if not rspawn.playerspawns["original spawns"] then
@ -17,6 +25,36 @@ local function reconcile_original_spawns()
rspawn:spawnsave()
end
local function reconcile_guest(guestname, guestspawn)
for hostname,hostspawn in pairs(rspawn.playerspawns) do
if hostspawn == guestspawn then
local hostlist = rspawn.playerspawns["guest lists"][hostname] or {}
hostlist[guestname] = 1
rspawn.playerspawns["guest lists"][hostname] = hostlist
rspawn.playerspawns["original spawns"][guestname] = nil
end
end
end
local function reconcile_guestlist_spawns()
local original_spawns = rspawn.playerspawns["original spawns"]
if not original_spawns then return
for guestname,spawnpos in pairs(original_spawns) do
reconcile_guest(guestname, spawnpos)
rspawn.playerspawns[guestname] = spawnpos
end
if #rspawn.playerspawns["original spawns"] == 0 then
rspawn.playerspawns["original spawns"] = nil
else
minetest.log("error", "Failed to reconcile all spawns")
end
rspawn:spawnsave()
end
function rspawn:spawnsave()
local serdata = minetest.serialize(rspawn.playerspawns)
if not serdata then
@ -48,6 +86,7 @@ function rspawn:spawnload()
rspawn.playerspawns["pre gen"] = pregens
reconcile_original_spawns()
reconcile_guestlist_spawns()
minetest.debug("Loaded rspawn data with "..tostring(#pregens).." pregen nodes")
end

View File

@ -19,52 +19,9 @@ minetest.after(0,function()
end
end)
local function get_players(p1name, p2name)
-- Check both players are online.
-- It is easier to implement agains online players than to manage offline interactions
local err, p1, p2
local errmsg_generic = " is not online."
if not p1name then
minetest.log("error", "Missing p1name")
return nil,nil,"Internal error."
elseif not p2name then
minetest.log("error", "Missing p2name")
return nil,nil,"Internal error."
end
p1 = minetest.get_player_by_name(p1name)
p2 = minetest.get_player_by_name(p2name)
if not p1 then err = p1name..errmsg_generic end
if not p2 then err = p2name..errmsg_generic end
return p1,p2,err
end
function rspawn.invites:invite_player_fromto(hostname, guestname)
local host,guest = get_players(hostname, guestname)
if not (host and guest) then
minetest.chat_send_player(hostname, err or "player not online")
return
end
if not rspawn.invitations[guestname] then
rspawn.invitations[guestname] = hostname
else
minetest.chat_send_player(hostname, guestname.." already has a pending invitation, and cannot be invited.")
return
end
local hostspawn_s = minetest.pos_to_string(rspawn.playerspawns[hostname])
minetest.chat_send_player(guestname, hostname.." invited you to join their spawn point.\nIf you accept, your spawn point will be set to "..hostspawn_s.." and you will be taken there IMMEDIATELY.\nRun '/spawn accept' to accept, '/spawn decline' to decline and clear the invite.")
minetest.chat_send_player(hostname,
"You have invited "..guestname.." to join your spawn.\nIf they accept, you will be charged \n\n "..levvy_qtty.." "..levvy_nicename.." \n\nwhich will be taken from your inventory."
)
local function canvisit(hostname, guestname)
local glist = rspawn.playerspawns["guest lists"][hostname] or {}
return glist[guestname] == 1
end
local function find_levvy(player)
@ -102,7 +59,7 @@ local function find_levvy(player)
end
end
minetest.chat_send_player(pname, "You do not have enough "..levvy_nicename.." to pay the spawn levvy for your invitaiton.")
minetest.chat_send_player(pname, "You do not have enough "..levvy_nicename.." to pay the spawn levvy for your invitation.")
return false
end
@ -145,45 +102,35 @@ function rspawn:consume_levvy(player)
end
function rspawn.invites:addplayer(hostname, guestname)
local guestlist = rspawn.guestlists[hostname] or {}
if guestlist[guestname] ~= nil then
minetest.chat_send_player(hostname, guestname.." is already in your guest list.")
elseif rspawn:consume_levvy(minetest.get_player_by_name(hostname) ) then -- Automatically notifies host if they don't have enough
guestlist[guestname] = 1
rspawn.questlists[hostname] = guestlist
minetest.chat_send_player(guestname, hostname.." added you to their spawn! You can now visit them with /spawn visit "..hostname)
end
end
function rspawn.invites:exileplayer(hostname, guestname)
local guestlist = rspawn.guestlists[hostname] or {}
if guestlist[guestname] == 1 then
guestlist[guestname] = 0
rspawn.questlists[hostname] = guestlist
minetest.chat_send_player(guestname, hostname.." has exiled you!")
else
minetest.chat_send_player(hostname, guestname.." is not in your accepted guests list.")
end
end
function rspawn.invites:liftexileplayer(hostname, guestname)
local guestlist = rspawn.guestlists[hostname] or {}
local guestlist = rspawn.playerspawns["guest lists"][hostname] or {}
if guestlist[guestname] == 0 then
guestlist[guestname] = 1
rspawn.questlists[hostname] = guestlist
minetest.chat_send_player(guestname, hostname.." let you back into their spawn.")
rspawn.invites:kick(hostname, guestname)
minetest.chat_send_player(guestname, hostname.." has exiled you!")
else
minetest.chat_send_player(hostname, guestname.." is not in your exiled guests list.")
elseif rspawn:consume_levvy(minetest.get_player_by_name(hostname) ) then -- Automatically notifies host if they don't have enough
guestlist[guestname] = 1
minetest.chat_send_player(guestname, hostname.." added you to their spawn! You can now visit them with /spawn visit "..hostname)
end
minetest.chat_send_player(hostname, guestname.." is allowed to visit your spawn.")
rspawn.playerspawns["guest lists"][hostname] = guestlist
end
function rspawn.invites:exileplayer(hostname, guestname)
local guestlist = rspawn.playerspawns["guest lists"][hostname] or {}
if guestlist[guestname] == 1 then
guestlist[guestname] = 0
rspawn.playerspawns["guest lists"][hostname] = guestlist
else
minetest.chat_send_player(hostname, guestname.." is not in your accepted guests list.")
return
end
minetest.chat_send_player(guestname, hostname.." banishes you!")
rspawn.invites:kick(hostname, guestname)
end
function rspawn.invites:kick(hostname, guestname)
@ -199,7 +146,7 @@ end
function rspawn.invites:listguests(hostname)
local guests = ""
local guestlist = rspawn.guestlists[hostname] or {}
local guestlist = rspawn.playerspawns["guest lists"][hostname] or {}
for guestname,status in pairs(guestlist) do
if status == 1 then status = "" else status = " (exiled)"
@ -213,8 +160,8 @@ end
function rspawn.invites:listhosts(guestname)
local hosts = ""
for _,hostname in ipairs(rspawn.guestlists) do
for gname,status in pairs(rspawn.guestlists[hostname]) do
for _,hostname in ipairs(rspawn.playerspawns["guest lists"]) do
for gname,status in pairs(rspawn.playerspawns["guest lists"][hostname]) do
if guestname == gname then
if status == 1 then status = "" else status = " (exiled)"
@ -226,55 +173,14 @@ function rspawn.invites:listhosts(guestname)
minetest.chat_send_player(guestname, hosts)
end
function rspawn.invites:accept(guestname)
local hostname = rspawn.invitations[guestname]
function rspawn.invites:visitplayer(hostname, guestname)
local guest = minetest.get_player_by_name(guestname)
local hostpos = rspawn.playerspawns[hostname]
if not hostname then
minetest.chat_send_player(guestname, "No invitation to accept.")
return
end
local host,guest = get_players(hostname, guestname)
if not (host and guest) then
minetest.chat_send_player(guestname, err or "player not online")
return
end
if rspawn:consume_levvy(minetest.get_player_by_name(hostname) ) then -- Systematically notifies host if they don't have enough
local hostspawn = rspawn.playerspawns[hostname]
rspawn:set_player_spawn(guestname, hostspawn) -- sets new spawn position, saves, teleports player
local success_message = " has accepted the spawn invitation from "
minetest.chat_send_player(guestname, guestname..success_message..hostname)
minetest.chat_send_player(hostname, guestname..success_message..hostname)
minetest.chat_send_player(guestname, "You can return to your original spawn using '/spawn original' for \n\n "..levvy_qtty.." "..levvy_nicename.." \n\nwhich will be taken from your inventory.")
else -- Host was notified, now notify guest
minetest.chat_send_player(guestname, hostname.." was unable to pay the levvy. Invitation could not be accepted.")
end
end
function rspawn.invites:decline(guestname)
local hostname = rspawn.invitations[guestname]
if hostname then
rspawn.invitations[guestname] = nil
-- Player not online, message simply ignored.
minetest.chat_send_player(guestname, "Declined invitation to join "..hostname.."'s spawn for now.")
minetest.chat_send_player(hostname, guestname.." declined to join your spawn point for now.")
if guest and hostpos and canvisit(hostname, guestname) then
guest:setpos(hostpos)
else
minetest.chat_send_player(guestname, "No invitation to decline.")
end
end
function rspawn.invites:show_invite_for(guestname)
local hostname = rspawn.invitations[guestname]
if hostname then
minetest.chat_send_player(guestname, "You have been invited to join "..hostname.." at "..minetest.pos_to_string(rspawn.playerspawns[hostname]))
else
minetest.chat_send_player(guestname, "No pending invitation.")
minetest.log("error", "[rspawn] Missing spawn position data for "..hostname)
minetest.chat_send_player(guestname, "Could not find spawn position for "..hostname)
end
end