Allow more than two teams in a match at once (#724)
* Fix bugs with more than two teams * Fix team allocation * Fix bugz * Fix crash * Fix crash with crash fix
This commit is contained in:
parent
0ef16edb23
commit
fbf0126599
14 changed files with 87 additions and 30 deletions
|
@ -116,6 +116,8 @@ function ctf.chat_send_team(team, msg)
|
||||||
team = ctf.team(team)
|
team = ctf.team(team)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not team then return end
|
||||||
|
|
||||||
for pname, _ in pairs(team.players) do
|
for pname, _ in pairs(team.players) do
|
||||||
minetest.chat_send_player(pname, msg)
|
minetest.chat_send_player(pname, msg)
|
||||||
end
|
end
|
||||||
|
@ -199,6 +201,7 @@ function ctf.join(name, team, force, by)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local prevteam = player.team
|
||||||
player.team = team
|
player.team = team
|
||||||
team_data.players[player.name] = player
|
team_data.players[player.name] = player
|
||||||
ctf.player_last_team[name] = team
|
ctf.player_last_team[name] = team
|
||||||
|
@ -219,7 +222,7 @@ function ctf.join(name, team, force, by)
|
||||||
minetest.log("action", name .. " joined team " .. team)
|
minetest.log("action", name .. " joined team " .. team)
|
||||||
|
|
||||||
for i = 1, #ctf.registered_on_join_team do
|
for i = 1, #ctf.registered_on_join_team do
|
||||||
ctf.registered_on_join_team[i](name, team)
|
ctf.registered_on_join_team[i](name, team, prevteam)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -421,6 +424,7 @@ minetest.register_on_joinplayer(function(player)
|
||||||
|
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
if ctf.team(ctf.player(name).team) then
|
if ctf.team(ctf.player(name).team) then
|
||||||
|
minetest.log("action", name.." already in team so not allocating")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -52,12 +52,14 @@ local function update_lowest()
|
||||||
-- Update lowest.score and lowest.team
|
-- Update lowest.score and lowest.team
|
||||||
lowest = {}
|
lowest = {}
|
||||||
for tname, score in pairs(scores) do
|
for tname, score in pairs(scores) do
|
||||||
|
if tname == "red" or tname == "blue" then
|
||||||
if not lowest.score or score <= lowest.score then
|
if not lowest.score or score <= lowest.score then
|
||||||
lowest.score = score
|
lowest.score = score
|
||||||
lowest.team = tname
|
lowest.team = tname
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function calc_scores()
|
local function calc_scores()
|
||||||
-- Update the cumulative score of all teams
|
-- Update the cumulative score of all teams
|
||||||
|
|
|
@ -75,7 +75,7 @@ minetest.register_chatcommand("team", {
|
||||||
string.match(create, "([%a%b_]-)")
|
string.match(create, "([%a%b_]-)")
|
||||||
and create ~= ""
|
and create ~= ""
|
||||||
and create ~= nil
|
and create ~= nil
|
||||||
and ctf.team({name=create, add_team=true})
|
and ctf.team({name=create, add_team=true, color=create, allow_joins=false})
|
||||||
) then
|
) then
|
||||||
return true, "Added team '"..create.."'"
|
return true, "Added team '"..create.."'"
|
||||||
else
|
else
|
||||||
|
|
|
@ -52,12 +52,6 @@ function ctf_classes.register_on_changed(func)
|
||||||
table.insert(registered_on_changed, func)
|
table.insert(registered_on_changed, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ctf_classes.set_skin(player, color, class)
|
|
||||||
player:set_properties({
|
|
||||||
textures = {"ctf_classes_skin_" .. class.name .. "_" .. (color or "blue") .. ".png"}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function ctf_classes.get(player)
|
function ctf_classes.get(player)
|
||||||
if type(player) == "string" then
|
if type(player) == "string" then
|
||||||
player = minetest.get_player_by_name(player)
|
player = minetest.get_player_by_name(player)
|
||||||
|
|
|
@ -48,9 +48,17 @@ minetest.register_chatcommand("class", {
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
ctf_colors.set_skin = function(player, color)
|
local old_set_skin = ctf_colors.set_skin
|
||||||
ctf_classes.set_skin(player, color, ctf_classes.get(player))
|
ctf_colors.set_skin = function(player, color, ...)
|
||||||
|
if color == "blue" or color == "red" then
|
||||||
|
player:set_properties({
|
||||||
|
textures = {"ctf_classes_skin_" .. ctf_classes.get(player).name .. "_" .. (color or "blue") .. ".png"}
|
||||||
|
})
|
||||||
|
elseif color then
|
||||||
|
old_set_skin(player, color, ...)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
ctf_classes.set_skin = ctf_colors.set_skin
|
||||||
|
|
||||||
ctf_classes.register_on_changed(function(player, old, new)
|
ctf_classes.register_on_changed(function(player, old, new)
|
||||||
if not old then
|
if not old then
|
||||||
|
|
|
@ -11,6 +11,9 @@ local function regen_update()
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
local class = get(player)
|
local class = get(player)
|
||||||
local tname = ctf.player(pname).team
|
local tname = ctf.player(pname).team
|
||||||
|
|
||||||
|
if medic_by_team[tname] == nil then return end
|
||||||
|
|
||||||
tnames[pname] = tname
|
tnames[pname] = tname
|
||||||
if class.properties.nearby_hpregen then
|
if class.properties.nearby_hpregen then
|
||||||
if tname then
|
if tname then
|
||||||
|
|
|
@ -55,11 +55,11 @@ function ctf_colors.update(player, name, tplayer)
|
||||||
local tcolor = ctf_colors.get_color(tplayer)
|
local tcolor = ctf_colors.get_color(tplayer)
|
||||||
|
|
||||||
if ctf.setting("colors.hudtint") then
|
if ctf.setting("colors.hudtint") then
|
||||||
if tcolor.text == "red" or tcolor.text == "blue" then
|
if tcolor.css then
|
||||||
player:hud_set_hotbar_image("ctf_colors_hotbar_" .. tcolor.text .. ".png")
|
player:hud_set_hotbar_image("gui_hotbar.png^[colorize:"..tcolor.css..":180")
|
||||||
player:hud_set_hotbar_selected_image("ctf_colors_hotbar_selected_" .. tcolor.text .. ".png")
|
player:hud_set_hotbar_selected_image("gui_hotbar_selected.png^[colorize:"..tcolor.css..":180")
|
||||||
else
|
else
|
||||||
ctf.error("ctf_colors", "Hint color not supported for " .. tcolor.text)
|
ctf.error("ctf_colors", "css color not found!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -237,8 +237,9 @@ if minetest.get_modpath("ctf") then
|
||||||
for _, player in pairs(minetest.get_connected_players()) do
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
if ctf_map.get_team_relative_z(player) < 0 and not ctf_map.can_cross(player) then
|
if ctf_map.get_team_relative_z(player) < 0 and not ctf_map.can_cross(player) then
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
if ctf.move_to_spawn(name) then
|
||||||
minetest.chat_send_player(name, "Match hasn't started yet!")
|
minetest.chat_send_player(name, "Match hasn't started yet!")
|
||||||
ctf.move_to_spawn(name)
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ ctf_flag.register_on_prepick_up(function(name, flag)
|
||||||
minetest.chat_send_player(name, "Match hasn't started yet!")
|
minetest.chat_send_player(name, "Match hasn't started yet!")
|
||||||
ctf.move_to_spawn(name)
|
ctf.move_to_spawn(name)
|
||||||
return false
|
return false
|
||||||
|
elseif not ctf.get_spawn(ctf.player(name).team) then
|
||||||
|
return false
|
||||||
else
|
else
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,7 +51,7 @@ end
|
||||||
local game_won = false
|
local game_won = false
|
||||||
function ctf_match.check_for_winner()
|
function ctf_match.check_for_winner()
|
||||||
local winner
|
local winner
|
||||||
for name, team in pairs(ctf.teams) do
|
for name, team in pairs({red = ctf.teams.red, blue = ctf.teams.blue}) do
|
||||||
if winner then
|
if winner then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
23
mods/ctf/ctf_otherteams/init.lua
Normal file
23
mods/ctf/ctf_otherteams/init.lua
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
minetest.register_on_respawnplayer(function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
|
||||||
|
if not ctf.get_spawn(ctf.player(name).team) then
|
||||||
|
local pos
|
||||||
|
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
local team = ctf.team("red")
|
||||||
|
if team and team.flags[1] then
|
||||||
|
pos = vector.new(team.flags[1])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local team = ctf.team("blue")
|
||||||
|
if team and team.flags[1] then
|
||||||
|
pos = vector.new(team.flags[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if pos then
|
||||||
|
player:set_pos(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
2
mods/ctf/ctf_otherteams/mod.conf
Normal file
2
mods/ctf/ctf_otherteams/mod.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
name = ctf_otherteams
|
||||||
|
depends = ctf
|
|
@ -210,7 +210,15 @@ function ctf_stats.is_pro(name)
|
||||||
return stats.score >= 10000 and kd >= 1.5
|
return stats.score >= 10000 and kd >= 1.5
|
||||||
end
|
end
|
||||||
|
|
||||||
ctf.register_on_join_team(function(name, tname)
|
ctf.register_on_join_team(function(name, tname, oldteam)
|
||||||
|
if not ctf_stats.current[tname] then
|
||||||
|
ctf_stats.current[tname] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if oldteam and ctf_stats.current[oldteam] then
|
||||||
|
ctf_stats.current[oldteam][name] = nil
|
||||||
|
end
|
||||||
|
|
||||||
ctf_stats.current[tname][name] = ctf_stats.current[tname][name] or {
|
ctf_stats.current[tname][name] = ctf_stats.current[tname][name] or {
|
||||||
kills = 0,
|
kills = 0,
|
||||||
kills_since_death = 0,
|
kills_since_death = 0,
|
||||||
|
@ -368,6 +376,8 @@ end
|
||||||
local function calculateKillReward(victim, killer)
|
local function calculateKillReward(victim, killer)
|
||||||
local vmain, victim_match = ctf_stats.player(victim)
|
local vmain, victim_match = ctf_stats.player(victim)
|
||||||
|
|
||||||
|
if not vmain or not victim_match then return 5 end
|
||||||
|
|
||||||
-- +5 for every kill they've made since last death in this match.
|
-- +5 for every kill they've made since last death in this match.
|
||||||
local reward = victim_match.kills_since_death * 5
|
local reward = victim_match.kills_since_death * 5
|
||||||
ctf.log("ctf_stats", "Player " .. victim .. " has made " .. reward ..
|
ctf.log("ctf_stats", "Player " .. victim .. " has made " .. reward ..
|
||||||
|
|
|
@ -153,11 +153,14 @@ function _doors.door_toggle(pos, node, clicker)
|
||||||
-- If team door, check clicker's team
|
-- If team door, check clicker's team
|
||||||
if node.name:find("doors:door_steel") then
|
if node.name:find("doors:door_steel") then
|
||||||
local tname = ctf.player(clicker:get_player_name()).team
|
local tname = ctf.player(clicker:get_player_name()).team
|
||||||
|
|
||||||
|
if tname == "red" or tname == "blue" then
|
||||||
local owner_team = meta:get_string("owner_team")
|
local owner_team = meta:get_string("owner_team")
|
||||||
if clicker and tname ~= owner_team then
|
if clicker and tname ~= owner_team then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- until Lua-5.2 we have no bitwise operators :(
|
-- until Lua-5.2 we have no bitwise operators :(
|
||||||
if state % 2 == 1 then
|
if state % 2 == 1 then
|
||||||
|
@ -303,6 +306,11 @@ function doors.register(name, def)
|
||||||
-- Get placer's team
|
-- Get placer's team
|
||||||
local tname = ctf.player(pn).team or ""
|
local tname = ctf.player(pn).team or ""
|
||||||
|
|
||||||
|
if tname ~= "red" and tname ~= "blue" then
|
||||||
|
minetest.chat_send_player(pn, "Your team can't place doors!")
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
-- Prevent door placement if within 40 nodes of enemy base
|
-- Prevent door placement if within 40 nodes of enemy base
|
||||||
local enemy_team = tname == "red" and "blue" or "red"
|
local enemy_team = tname == "red" and "blue" or "red"
|
||||||
local enemy_base = ctf_map.map.teams[enemy_team].pos
|
local enemy_base = ctf_map.map.teams[enemy_team].pos
|
||||||
|
|
Loading…
Reference in a new issue