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)
|
||||
end
|
||||
|
||||
if not team then return end
|
||||
|
||||
for pname, _ in pairs(team.players) do
|
||||
minetest.chat_send_player(pname, msg)
|
||||
end
|
||||
|
@ -199,6 +201,7 @@ function ctf.join(name, team, force, by)
|
|||
end
|
||||
end
|
||||
|
||||
local prevteam = player.team
|
||||
player.team = team
|
||||
team_data.players[player.name] = player
|
||||
ctf.player_last_team[name] = team
|
||||
|
@ -219,7 +222,7 @@ function ctf.join(name, team, force, by)
|
|||
minetest.log("action", name .. " joined team " .. team)
|
||||
|
||||
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
|
||||
return true
|
||||
end
|
||||
|
@ -421,6 +424,7 @@ minetest.register_on_joinplayer(function(player)
|
|||
|
||||
local name = player:get_player_name()
|
||||
if ctf.team(ctf.player(name).team) then
|
||||
minetest.log("action", name.." already in team so not allocating")
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -52,12 +52,14 @@ local function update_lowest()
|
|||
-- Update lowest.score and lowest.team
|
||||
lowest = {}
|
||||
for tname, score in pairs(scores) do
|
||||
if tname == "red" or tname == "blue" then
|
||||
if not lowest.score or score <= lowest.score then
|
||||
lowest.score = score
|
||||
lowest.team = tname
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function calc_scores()
|
||||
-- Update the cumulative score of all teams
|
||||
|
|
|
@ -75,7 +75,7 @@ minetest.register_chatcommand("team", {
|
|||
string.match(create, "([%a%b_]-)")
|
||||
and create ~= ""
|
||||
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
|
||||
return true, "Added team '"..create.."'"
|
||||
else
|
||||
|
|
|
@ -52,12 +52,6 @@ function ctf_classes.register_on_changed(func)
|
|||
table.insert(registered_on_changed, func)
|
||||
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)
|
||||
if type(player) == "string" then
|
||||
player = minetest.get_player_by_name(player)
|
||||
|
|
|
@ -48,9 +48,17 @@ minetest.register_chatcommand("class", {
|
|||
end
|
||||
})
|
||||
|
||||
ctf_colors.set_skin = function(player, color)
|
||||
ctf_classes.set_skin(player, color, ctf_classes.get(player))
|
||||
local old_set_skin = ctf_colors.set_skin
|
||||
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
|
||||
ctf_classes.set_skin = ctf_colors.set_skin
|
||||
|
||||
ctf_classes.register_on_changed(function(player, old, new)
|
||||
if not old then
|
||||
|
|
|
@ -11,6 +11,9 @@ local function regen_update()
|
|||
local pname = player:get_player_name()
|
||||
local class = get(player)
|
||||
local tname = ctf.player(pname).team
|
||||
|
||||
if medic_by_team[tname] == nil then return end
|
||||
|
||||
tnames[pname] = tname
|
||||
if class.properties.nearby_hpregen then
|
||||
if tname then
|
||||
|
|
|
@ -55,11 +55,11 @@ function ctf_colors.update(player, name, tplayer)
|
|||
local tcolor = ctf_colors.get_color(tplayer)
|
||||
|
||||
if ctf.setting("colors.hudtint") then
|
||||
if tcolor.text == "red" or tcolor.text == "blue" then
|
||||
player:hud_set_hotbar_image("ctf_colors_hotbar_" .. tcolor.text .. ".png")
|
||||
player:hud_set_hotbar_selected_image("ctf_colors_hotbar_selected_" .. tcolor.text .. ".png")
|
||||
if tcolor.css then
|
||||
player:hud_set_hotbar_image("gui_hotbar.png^[colorize:"..tcolor.css..":180")
|
||||
player:hud_set_hotbar_selected_image("gui_hotbar_selected.png^[colorize:"..tcolor.css..":180")
|
||||
else
|
||||
ctf.error("ctf_colors", "Hint color not supported for " .. tcolor.text)
|
||||
ctf.error("ctf_colors", "css color not found!")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -237,8 +237,9 @@ if minetest.get_modpath("ctf") then
|
|||
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
|
||||
local name = player:get_player_name()
|
||||
if ctf.move_to_spawn(name) then
|
||||
minetest.chat_send_player(name, "Match hasn't started yet!")
|
||||
ctf.move_to_spawn(name)
|
||||
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!")
|
||||
ctf.move_to_spawn(name)
|
||||
return false
|
||||
elseif not ctf.get_spawn(ctf.player(name).team) then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -51,7 +51,7 @@ end
|
|||
local game_won = false
|
||||
function ctf_match.check_for_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
|
||||
return
|
||||
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
|
||||
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 {
|
||||
kills = 0,
|
||||
kills_since_death = 0,
|
||||
|
@ -368,6 +376,8 @@ end
|
|||
local function calculateKillReward(victim, killer)
|
||||
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.
|
||||
local reward = victim_match.kills_since_death * 5
|
||||
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 node.name:find("doors:door_steel") then
|
||||
local tname = ctf.player(clicker:get_player_name()).team
|
||||
|
||||
if tname == "red" or tname == "blue" then
|
||||
local owner_team = meta:get_string("owner_team")
|
||||
if clicker and tname ~= owner_team then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- until Lua-5.2 we have no bitwise operators :(
|
||||
if state % 2 == 1 then
|
||||
|
@ -303,6 +306,11 @@ function doors.register(name, def)
|
|||
-- Get placer's team
|
||||
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
|
||||
local enemy_team = tname == "red" and "blue" or "red"
|
||||
local enemy_base = ctf_map.map.teams[enemy_team].pos
|
||||
|
|
Loading…
Reference in a new issue