diff --git a/mods/capturetheflag/ctf/cli.lua b/mods/capturetheflag/ctf/cli.lua index e36f754..bc5bd06 100644 --- a/mods/capturetheflag/ctf/cli.lua +++ b/mods/capturetheflag/ctf/cli.lua @@ -170,9 +170,9 @@ minetest.register_chatcommand("ctf", { description = "Do admin cleaning stuff", privs = {team=true}, func = function(name, param) - cf.clean_flags() cf.clean_player_lists() cf.collect_claimed() + minetest.chat_send_player(name, "CTF cleaned!") end, }) @@ -182,7 +182,8 @@ minetest.register_chatcommand("reload_ctf", { func = function(name, param) cf.save() cf.init() - end, + minetest.chat_send_player(name, "CTF core reloaded!") + end }) minetest.register_chatcommand("team_owner", { diff --git a/mods/capturetheflag/ctf/core.lua b/mods/capturetheflag/ctf/core.lua new file mode 100644 index 0000000..37b58c3 --- /dev/null +++ b/mods/capturetheflag/ctf/core.lua @@ -0,0 +1,209 @@ +function cf.init() + print("[CaptureTheFlag] Initialising...") + + -- Set up structures + cf._defsettings = {} + cf.teams = {} + cf.players = {} + cf.claimed = {} + cf.diplo = {diplo = {}} + + -- Settings: Feature enabling + cf._set("node_ownership",true) + cf._set("multiple_flags",true) + cf._set("flag_capture_take",false) -- whether flags need to be taken to home flag when captured + cf._set("gui",true) -- whether GUIs are used + cf._set("team_gui",true) -- GUI on /team is used + cf._set("flag_teleport_gui",true) -- flag tab in /team + cf._set("spawn_in_flag_teleport_gui",false) -- show spawn in the flag teleport team gui + cf._set("news_gui",true) -- news tab in /team + cf._set("diplomacy",true) + cf._set("flag_names",true) -- can flags be named + cf._set("team_channel",true) -- do teams have their own chat channel + cf._set("global_channel",true) -- Can players chat with other teams on /all. If team_channel is false, this does nothing. + cf._set("players_can_change_team",true) + + -- Settings: Teams + --cf._set("allocate_mode",0) -- (COMING SOON):how are players allocated to teams? + cf._set("default_diplo_state","war") -- what is the default diplomatic state? (war/peace/alliance) + --cf._setb("delete_teams",false) -- (COMING SOON):should teams be deleted when they are defeated? + + -- Settings: Misc + --cf._set("on_game_end",0) -- (COMING SOON):what happens when the game ends? + cf._set("flag_protect_distance",25) -- how far do flags protect? + cf._set("team_gui_initial","news") -- [news/flags/diplo/admin] - the starting tab + + local file = io.open(minetest.get_worldpath().."/ctf.txt", "r") + if file then + local table = minetest.deserialize(file:read("*all")) + if type(table) == "table" then + cf.teams = table.teams + cf.players = table.players + cf.diplo.diplo = table.diplo + return + end + end +end + +-- Set settings +function cf._set(setting,default) + cf._defsettings[setting] = default +end + +function cf.setting(name) + if minetest.setting_get("ctf_"..name) then + return minetest.setting_get("ctf_"..name) + elseif cf._defsettings[name] ~= nil then + return cf._defsettings[name] + else + print("[CaptureTheFlag] Setting "..name.." not found!") + return nil + end +end + +-- Save game +function cf.save() + print("[CaptureTheFlag] Saving data...") + local file = io.open(minetest.get_worldpath().."/ctf.txt", "w") + if file then + file:write(minetest.serialize({ + teams = cf.teams, + players = cf.players, + diplo = cf.diplo.diplo + })) + file:close() + end +end + +-- Get or add a team +function cf.team(name) -- get or add a team + if type(name) == "table" then + if not name.add_team then + error("Invalid table given to cf.team") + return + end + + print("Defining team "..name.name) + + cf.teams[name.name]={ + data = name, + spawn=nil, + players={}, + flags = {} + } + + cf.save() + + return cf.teams[name.name] + else + return cf.teams[name] + end +end + +-- get a player +function cf.player(name) + return cf.players[name] +end + +-- Player joins team +function cf.join(name, team, force) + if not name or name == "" or not team or team == "" then + return false + end + + local player = cf.player(name) + + if not player then + player = {name = name} + end + + if not force and not cf.setting("players_can_change_team") and (not player.team or player.team == "") then + minetest.chat_send_player(name, "You are not allowed to switch teams, traitor!") + return false + end + + if cf.add_user(team, player) == true then + minetest.chat_send_all(name.." has joined team "..team) + return true + end + return false +end + +-- Add a player to a team in data structures +function cf.add_user(team, user) + local _team = cf.team(team) + local _user = cf.player(user.name) + if _team and user and user.name then + if _user and _user.team and cf.team(_user.team) then + cf.teams[_user.team].players[user.name] = nil + end + + user.team = team + user.auth = false + _team.players[user.name]=user + cf.players[user.name] = user + cf.save() + + return true + else + return false + end +end + +-- Cleans up the player lists +function cf.clean_player_lists() + for _, str in pairs(cf.players) do + if str and str.team and cf.teams[str.team] then + print("Adding player "..str.name.." to team "..str.team) + cf.teams[str.team].players[str.name] = str + else + print("Skipping player "..str.name) + end + end +end + +-- Get info for cf.claimed +function cf.collect_claimed() + cf.claimed = {} + for _, team in pairs(cf.teams) do + for i = 1, #team.flags do + if team.flags[i].claimed then + table.insert(cf.claimed, team.flags[i]) + end + end + end +end + +-- Sees if the player can change stuff in a team +function cf.can_mod(player,team) + local privs = minetest.get_player_privs(player) + + if privs then + if privs.team == true then + return true + end + end + + if player and cf.teams[team] and cf.teams[team].players and cf.teams[team].players[player] then + if cf.teams[team].players[player].auth == true then + return true + end + end + return false +end + +-- post a message to a team board +function cf.post(team,msg) + if not cf.team(team) then + return false + end + + if not cf.team(team).log then + cf.team(team).log = {} + end + + table.insert(cf.team(team).log,1,msg) + cf.save() + + return true +end diff --git a/mods/capturetheflag/ctf/diplomacy.lua b/mods/capturetheflag/ctf/diplomacy.lua new file mode 100644 index 0000000..af8ce36 --- /dev/null +++ b/mods/capturetheflag/ctf/diplomacy.lua @@ -0,0 +1,67 @@ +-- diplo states: war, peace, alliance +cf.diplo = {} + +function cf.diplo.get(one,two) + if not cf.diplo.diplo then + return cf.setting("default_diplo_state") + end + + for i=1,#cf.diplo.diplo do + local dip = cf.diplo.diplo[i] + if (dip.one == one and dip.two == two) or (dip.one == two and dip.two == one) then + return dip.state + end + end + + return cf.setting("default_diplo_state") +end + +function cf.diplo.set(one,two,state) + if not cf.diplo.diplo then + cf.diplo.diplo = {} + else + for i=1,#cf.diplo.diplo do + local dip = cf.diplo.diplo[i] + if (dip.one == one and dip.two == two) or (dip.one == two and dip.two == one) then + dip.state = state + return + end + end + end + + table.insert(cf.diplo.diplo,{one=one,two=two,state=state}) + return +end + +function cf.diplo.check_requests(one,two) + local team = cf.team(two) + + if not team.log then + return nil + end + + for i=1,#team.log do + if team.log[i].team == one and team.log[i].type=="request" and team.log[i].mode=="diplo" then + return team.log[i].msg + end + end + + return nil +end + +function cf.diplo.cancel_requests(one,two) + local team = cf.team(two) + + if not team.log then + return + end + + for i=1,#team.log do + if team.log[i].team == one and team.log[i].type=="request" and team.log[i].mode=="diplo" then + table.remove(team.log,i) + return + end + end + + return +end \ No newline at end of file diff --git a/mods/capturetheflag/ctf/gui.lua b/mods/capturetheflag/ctf/gui.lua index 8307d8a..7991a4d 100644 --- a/mods/capturetheflag/ctf/gui.lua +++ b/mods/capturetheflag/ctf/gui.lua @@ -76,7 +76,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e "label[0.5,1.5;News such as attacks will appear here]" end - minetest.show_formspec(name, "capturetheflag:board", + minetest.show_formspec(name, "ctf:board", "size[10,7]".. cf.gui.tabs(name,team).. result @@ -132,7 +132,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e x = x + 2 end - minetest.show_formspec(name, "capturetheflag:flags", + minetest.show_formspec(name, "ctf:flags", "size[10,7]".. cf.gui.tabs(name,team).. result @@ -190,7 +190,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e end end - minetest.show_formspec(name, "capturetheflag:dip", + minetest.show_formspec(name, "ctf:dip", "size[10,7]".. cf.gui.tabs(name,team).. result @@ -217,7 +217,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e result = "label[0.5,1;You do not own this team!" end - minetest.show_formspec(name, "capturetheflag:team_settings", + minetest.show_formspec(name, "ctf:team_settings", "size[10,7]".. cf.gui.tabs(name,team).. result @@ -225,7 +225,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e end minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() - if formname=="capturetheflag:board" or formname=="capturetheflag:flags" or formname=="capturetheflag:dip" or formname=="capturetheflag:team_settings" then + if formname=="ctf:board" or formname=="ctf:flags" or formname=="ctf:dip" or formname=="ctf:team_settings" then if fields.flags then if cf and cf.players and cf.players[name] and cf.players[name].team then cf.gui.team_flags(name,cf.players[name].team) @@ -258,12 +258,12 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e end return true end - if fields.save and formname=="capturetheflag:team_settings" then + if fields.save and formname=="ctf:team_settings" then if cf and cf.players and cf.players[name] and cf.players[name].team then cf.gui.team_settings(name,cf.players[name].team) end if cf and cf.team(cf.players[name].team) and cf.team(cf.players[name].team).data then - if minetest.registered_items["capturetheflag:flag_top_"..fields.color] then + if minetest.registered_items["ctf:flag_top_"..fields.color] then print("Setting color...") cf.team(cf.players[name].team).data.color = fields.color cf.save() @@ -278,7 +278,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() - if formname=="capturetheflag:board" then + if formname=="ctf:board" then for key, field in pairs(fields) do local ok, id = string.match(key, "btn_([yn])([0123456789]+)") if ok and id then @@ -302,7 +302,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() - if formname=="capturetheflag:flags" then + if formname=="ctf:flags" then for key, field in pairs(fields) do local x,y,z = string.match(key, "goto_(%d+)_(%d+)_(%d+)") if x and y and x then @@ -315,7 +315,7 @@ if cf.setting("team_gui") and cf.setting("gui") then -- check if team guis are e minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() - if formname=="capturetheflag:dip" then + if formname=="ctf:dip" then for key, field in pairs(fields) do local newteam = string.match(key, "team_(.+)") if newteam then @@ -423,7 +423,7 @@ function cf.gui.flag_board(name,pos) cf.gui.flag_data[name] = {pos=pos} - minetest.show_formspec(name, "capturetheflag:flag_board", + minetest.show_formspec(name, "ctf:flag_board", "size[6,3]".. "field[1,1;4,1;flag_name;Flag Name;"..flag_name.."]".. "button_exit[1,2;2,1;save;Save]".. @@ -433,7 +433,7 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() - if not formname=="capturetheflag:flag_board" then + if not formname=="ctf:flag_board" then return false end diff --git a/mods/capturetheflag/ctf/init.lua b/mods/capturetheflag/ctf/init.lua index a6f3217..9849b3b 100644 --- a/mods/capturetheflag/ctf/init.lua +++ b/mods/capturetheflag/ctf/init.lua @@ -1,295 +1,10 @@ -- CAPTURE THE FLAG -- by Andrew "rubenwardy" Ward ----------------------------------------- + cf = {} --- init game -function cf.init() - print("[CaptureTheFlag] Initialising...") - - -- Set up structures - cf._defsettings = {} - cf.teams = {} - cf.players = {} - cf.claimed = {} - cf.diplo.diplo = {} - - -- Settings: Feature enabling - cf._set("node_ownership",true) - cf._set("multiple_flags",true) - cf._set("flag_capture_take",false) -- whether flags need to be taken to home flag when captured - cf._set("gui",true) -- whether GUIs are used - cf._set("team_gui",true) -- GUI on /team is used - cf._set("flag_teleport_gui",true) -- flag tab in /team - cf._set("spawn_in_flag_teleport_gui",false) -- show spawn in the flag teleport team gui - cf._set("news_gui",true) -- news tab in /team - cf._set("diplomacy",true) - cf._set("flag_names",true) -- can flags be named - cf._set("team_channel",true) -- do teams have their own chat channel - cf._set("global_channel",true) -- Can players chat with other teams on /all. If team_channel is false, this does nothing. - cf._set("players_can_change_team",true) - - -- Settings: Teams - --cf._set("allocate_mode",0) -- (COMING SOON):how are players allocated to teams? - cf._set("default_diplo_state","war") -- what is the default diplomatic state? (war/peace/alliance) - --cf._setb("delete_teams",false) -- (COMING SOON):should teams be deleted when they are defeated? - - -- Settings: Misc - --cf._set("on_game_end",0) -- (COMING SOON):what happens when the game ends? - cf._set("flag_protect_distance",25) -- how far do flags protect? - cf._set("team_gui_initial","news") -- [news/flags/diplo/admin] - the starting tab - - local file = io.open(minetest.get_worldpath().."/ctf.txt", "r") - if file then - local table = minetest.deserialize(file:read("*all")) - if type(table) == "table" then - cf.teams = table.teams - cf.players = table.players - cf.diplo.diplo = table.diplo - return - end - end -end - --- Set settings -function cf._set(setting,default) - cf._defsettings[setting] = default -end - -function cf.setting(name) - if minetest.setting_get("ctf_"..name) then - return minetest.setting_get("ctf_"..name) - elseif cf._defsettings[name]~= nil then - return cf._defsettings[name] - else - print("[CaptureTheFlag] Setting "..name.." not found!") - return nil - end -end - --- Save game -function cf.save() - print("[CaptureTheFlag] Saving data...") - local file = io.open(minetest.get_worldpath().."/ctf.txt", "w") - if file then - file:write(minetest.serialize({ - teams = cf.teams, - players = cf.players, - diplo = cf.diplo.diplo - })) - file:close() - end -end - --- Get or add a team -function cf.team(name) -- get or add a team - if type(name) == "table" then - if not name.add_team then - error("Invalid table given to cf.team") - return - end - - print("Defining team "..name.name) - - cf.teams[name.name]={ - data = name, - spawn=nil, - players={}, - flags = {} - } - - cf.save() - - return cf.teams[name.name] - else - return cf.teams[name] - end -end - --- get a player -function cf.player(name) - return cf.players[name] -end - --- Player joins team -function cf.join(name, team, force) - if not name or name == "" or not team or team == "" then - return false - end - - local player = cf.player(name) - - if not player then - player = {name = name} - end - - if not force and not cf.setting("players_can_change_team") and (not player.team or player.team == "") then - minetest.chat_send_player(name, "You are not allowed to switch teams, traitor!") - return false - end - - if cf.add_user(team, player) == true then - minetest.chat_send_all(name.." has joined team "..team) - return true - end - return false -end - --- Add a player to a team in data structures -function cf.add_user(team, user) - local _team = cf.team(team) - local _user = cf.player(user.name) - if _team and user and user.name then - if _user and _user.team and cf.team(_user.team) then - cf.teams[_user.team].players[user.name] = nil - end - - user.team = team - user.auth = false - _team.players[user.name]=user - cf.players[user.name] = user - cf.save() - - return true - else - return false - end -end - --- Cleans up the player lists -function cf.clean_player_lists() - for _, str in pairs(cf.players) do - if str and str.team and cf.teams[str.team] then - print("Adding player "..str.name.." to team "..str.team) - cf.teams[str.team].players[str.name] = str - else - print("Skipping player "..str.name) - end - end -end - --- Cleans up the flag lists -function cf.clean_flags() - for _, team in pairs(cf.teams) do - cf.assert_flags(team.data.name) - end -end - --- Get info for cf.claimed -function cf.collect_claimed() - cf.claimed = {} - for _, team in pairs(cf.teams) do - for i = 1, #team.flags do - if team.flags[i].claimed then - table.insert(cf.claimed,team.flags[i]) - end - end - end -end - --- Sees if the player can change stuff in a team -function cf.can_mod(player,team) - local privs = minetest.get_player_privs(player) - - if privs then - if privs.team == true then - return true - end - end - - if player and cf.teams[team] and cf.teams[team].players and cf.teams[team].players[player] then - if cf.teams[team].players[player].auth == true then - return true - end - end - return false -end - --- post a message to a team board -function cf.post(team,msg) - if not cf.team(team) then - return false - end - - if not cf.team(team).log then - cf.team(team).log = {} - end - - table.insert(cf.team(team).log,1,msg) - cf.save() - - return true -end - --- diplo states: war, peace, alliance -cf.diplo = {} - -function cf.diplo.get(one,two) - if not cf.diplo.diplo then - return cf.setting("default_diplo_state") - end - - for i=1,#cf.diplo.diplo do - local dip = cf.diplo.diplo[i] - if (dip.one == one and dip.two == two) or (dip.one == two and dip.two == one) then - return dip.state - end - end - - return cf.setting("default_diplo_state") -end - -function cf.diplo.set(one,two,state) - if not cf.diplo.diplo then - cf.diplo.diplo = {} - else - for i=1,#cf.diplo.diplo do - local dip = cf.diplo.diplo[i] - if (dip.one == one and dip.two == two) or (dip.one == two and dip.two == one) then - dip.state = state - return - end - end - end - - table.insert(cf.diplo.diplo,{one=one,two=two,state=state}) - return -end - -function cf.diplo.check_requests(one,two) - local team = cf.team(two) - - if not team.log then - return nil - end - - for i=1,#team.log do - if team.log[i].team == one and team.log[i].type=="request" and team.log[i].mode=="diplo" then - return team.log[i].msg - end - end - - return nil -end - -function cf.diplo.cancel_requests(one,two) - local team = cf.team(two) - - if not team.log then - return - end - - for i=1,#team.log do - if team.log[i].team == one and team.log[i].type=="request" and team.log[i].mode=="diplo" then - table.remove(team.log,i) - return - end - end - - return -end - --- Vector stuff +-- Helpers v3={} function v3.distance(v, w) return math.sqrt( @@ -344,15 +59,16 @@ function v3.get_direction(pos1,pos2) end -- Load the core +dofile(minetest.get_modpath("ctf").."/core.lua") cf.init() -cf.clean_player_lists() --- Load Modules +-- Modules +dofile(minetest.get_modpath("ctf").."/diplomacy.lua") dofile(minetest.get_modpath("ctf").."/area.lua") dofile(minetest.get_modpath("ctf").."/gui.lua") dofile(minetest.get_modpath("ctf").."/cli.lua") dofile(minetest.get_modpath("ctf").."/flag.lua") --- Load other +-- Init +cf.clean_player_lists() cf.collect_claimed() -