diff --git a/ctf/core.lua b/ctf/core.lua index fe69334..a78427b 100644 --- a/ctf/core.lua +++ b/ctf/core.lua @@ -245,7 +245,8 @@ function ctf.save() if file then local out = { teams = ctf.teams, - players = ctf.players + players = ctf.players, + applications = ctf.applications } for i = 1, #ctf.registered_on_save do diff --git a/ctf/gui.lua b/ctf/gui.lua index 4fc473b..b487015 100644 --- a/ctf/gui.lua +++ b/ctf/gui.lua @@ -55,7 +55,7 @@ function ctf.gui.get_tabs(name, tname) local result = "" local id = 1 local function addtab(name,text) - result = result .. "button[" .. (id*2-1) .. ",0;2,1;" .. name .. ";" .. text .. "]" + result = result .. "button[" .. (id*1.5-1) .. ",0;1.5,1;" .. name .. ";" .. text .. "]" id = id + 1 end @@ -99,8 +99,6 @@ ctf.gui.register_tab("news", "News", function(name, tname) end result = result .. "button[6," .. height .. ";1,1;btn_y" .. i .. ";Yes]" result = result .. "button[7," .. height .. ";1,1;btn_n" .. i .. ";No]" - else - result = result .. "label[0.5," .. height .. ";RANDOM REQUEST TYPE]" end end else @@ -131,6 +129,35 @@ ctf.gui.register_tab("news", "News", function(name, tname) result) end) +ctf.gui.register_tab("applications","Applications", function(name, tname) + local result = "" + local data = {} + + result = result .. "label[0.5,1;Applicants to join " .. tname .. "]" + + for key, value in pairs(ctf.teams) do + if key == tname then + local height = 1.5 + for key, value in pairs(value.applications) do + result = result .. "label[0.5.75," .. height .. ";" .. value .. "]" + if ctf.player(name).auth or ctf.player(name).recruit then + result = result .. "button[2.5," .. height .. ";2,1;player_" .. + value .. ";Accept]" + result = result .. "button[4.5," .. height .. ";2,1;player_" .. + value .. ";Reject]" + end + height = height + 1 + end + end + end + + minetest.show_formspec(name, "ctf:applications", + "size[10,7]" .. + ctf.gui.get_tabs(name, tname) .. + result + ) +end) + local scroll_diplomacy = 0 local scroll_max = 0 -- Team interface @@ -228,7 +255,19 @@ local function formspec_is_ctf_tab(fsname) end return false end - +function remove_application_log_entry(tname, pname) + local entries = ctf.team(tname).log + if not entries then + return + end + for i = 1, #entries do + if entries[i].mode == "applications" and entries[i].player == pname then + table.remove(entries, i) + return + end + end +end + minetest.register_on_player_receive_fields(function(player, formname, fields) if not formspec_is_ctf_tab(formname) then return false @@ -267,40 +306,75 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local tname = tplayer.team local team = ctf.team(tname) - if not team then + if not team or formname ~= "ctf:news" then return false end - if formname == "ctf:news" then - for key, field in pairs(fields) do - local ok, id = string.match(key, "btn_([yn])([0123456789]+)") - if ok and id then - if ok == "y" then - ctf.diplo.set(tname, team.log[tonumber(id)].team, team.log[tonumber(id)].msg) + for key, field in pairs(fields) do + local ok, id = string.match(key, "btn_([yn])([0123456789]+)") + if ok and id then + if ok == "y" then + ctf.diplo.set(tname, team.log[tonumber(id)].team, team.log[tonumber(id)].msg) - -- Post to acceptor's log - ctf.post(tname, { - msg = "You have accepted the " .. - team.log[tonumber(id)].msg .. " request from " .. - team.log[tonumber(id)].team }) + -- Post to acceptor's log + ctf.post(tname, { + msg = "You have accepted the " .. + team.log[tonumber(id)].msg .. " request from " .. + team.log[tonumber(id)].team }) - -- Post to request's log - ctf.post(team.log[tonumber(id)].team, { - msg = tname .. " has accepted your " .. - team.log[tonumber(id)].msg .. " request" }) + -- Post to request's log + ctf.post(team.log[tonumber(id)].team, { + msg = tname .. " has accepted your " .. + team.log[tonumber(id)].msg .. " request" }) - id = id + 1 - end + id = id + 1 + end - table.remove(team.log, id) - ctf.needs_save = true - ctf.gui.show(name, "news") + table.remove(team.log, id) + ctf.needs_save = true + ctf.gui.show(name, "news") + return true + end + local applicant_name, id = string.match(key, "player_([^_]+)_([0123456789]+)") + if applicant_name then + local acceptor_name = name + local team_name = tname + local decision = field + ctf.decide_application( + applicant_name, + acceptor_name, + team_name, + decision) + return true + end + end +end) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local acceptor_name = player:get_player_name() + local team_name = ctf.player(acceptor_name).team + local team = ctf.team(team_name) + + if not team or formname ~= "ctf:applications" then + return false + end + + for key, field in pairs(fields) do + if ctf.player(acceptor_name).auth or ctf.player(acceptor_name).recruit then + local applicant_name = string.match(key, "player_(.+)") + if applicant_name then + local decision = field + ctf.decide_application( + applicant_name, + acceptor_name, + team_name, + decision) + ctf.gui.show(acceptor_name, "applications") return true end end end end) - local cur_team = nil minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() diff --git a/ctf/teams.lua b/ctf/teams.lua index 670439b..6c1d138 100644 --- a/ctf/teams.lua +++ b/ctf/teams.lua @@ -13,6 +13,10 @@ function ctf.team(name) else local team = ctf.teams[name] if team then + --Migration to version with applications + if not team.applications then + team.applications = {} + end if not team.data or not team.players then ctf.warning("team", "Assertion failed, data{} or players{} not " .. "found in team{}") @@ -33,7 +37,8 @@ function ctf.create_team(name, data) ctf.teams[name] = { data = data, spawn = nil, - players = {} + players = {}, + applications = {} } for i = 1, #ctf.registered_on_new_team do @@ -150,8 +155,82 @@ function ctf.register_on_join_team(func) table.insert(ctf.registered_on_join_team, func) end +-- Player makes an application to team manager to join a team +-- Called by /apply +function ctf.application_join(name, tname) + if not name or name == "" or not tname or tname == "" then + ctf.log("teams", "Missing parameters to ctf.request_join") + end + local player = ctf.player(name) + + if player.team and player.team == tname then + minetest.chat_send_player(name, "You are already a member of team " .. tname) + return false + end + + if not ctf.setting("players_can_change_team") and player.team and ctf.team(player.team) then + ctf.action("teams", name .. " requested to change to " .. tname) + minetest.chat_send_player(name, "You are not allowed to switch teams, traitor!") + return false + end + + local team_data = ctf.team(tname) + if not team_data then + minetest.chat_send_player(name, "No such team.") + ctf.list_teams(name) + minetest.log("action", name .. " requested to join to " .. tname .. ", which doesn't exist") + return false + end + + table.insert(team_data.applications,name) + --ctf.post(tname, {msg = name .. " has applied to join!" }) + ctf.needs_save = true + return true +end + +function ctf.decide_application(applicant_name, acceptor_name, team_name, decision) + if not applicant_name then + return false + end + local applicant = ctf.player(applicant_name) + if not applicant then + return false + end + if decision == "Accept" then + if applicant.team and ctf.setting("players_can_change_team") then + minetest.chat_send_player(acceptor_name, "Player " .. applicant_name .. " already a member of team " .. applicant.team) + else + ctf.join(applicant_name, team_name, true, acceptor_name) + table.insert(ctf.teams[ctf.players[acceptor_name].team].log,{msg=applicant_name .. " was recruited " .. acceptor_name .. "!"}) + end + end + for key, field in pairs(ctf.teams) do + ctf.delete_application(applicant_name, key) + end + remove_application_log_entry(team_name, applicant_name) +end + +function ctf.delete_application(name, tname) + if not name or name == "" or not tname or tname == "" then + ctf.log("teams", "Missing parameters to ctf.delete_application") + end + local team = ctf.team(tname) + if not team then + minetest.chat_send_player(name, "No such team.") + return false + end + for key, field in pairs(team.applications) do + if field == name then + table.remove(team.applications, key) + ctf.needs_save = true + return true + end + end + return false +end + -- Player joins team --- Called by /join, /team join or auto allocate. +-- Called by /join, /team join, auto allocate or by response of the team manager. function ctf.join(name, team, force, by) if not name or name == "" or not team or team == "" then ctf.log("team", "Missing parameters to ctf.join") diff --git a/ctf_chat/init.lua b/ctf_chat/init.lua index b6c9955..fd51e76 100644 --- a/ctf_chat/init.lua +++ b/ctf_chat/init.lua @@ -144,6 +144,18 @@ minetest.register_chatcommand("team", { end }) +minetest.register_chatcommand("apply", { + params = "team name", + description = "Petition to join to team", + func = function(name, param) + if ctf.petition_join(name, param) then + return true, "Petition was successfully sent to team " .. param .. "!" + else + return false, "Failed to apply to team!" + end + end +}) + minetest.register_chatcommand("join", { params = "player name", description = "Add to team",