2024-05-27 08:59:28 -07:00

193 lines
11 KiB
Lua

local bc = better_commands
local S = minetest.get_translator(minetest.get_current_modname())
better_commands.register_command("team", {
params = S("add|empty|join|leave|list|modify|remove ..."),
description = S("Controls teams"),
privs = {server = true},
func = function (name, param, context)
local split_param, err = better_commands.parse_params(param)
if err then return false, better_commands.error(err), 0 end
if not split_param[1] then return false, better_commands.error(S("Missing subcommand")), 0 end
local subcommand = split_param[1] and split_param[1][3]
if subcommand == "add" then
local team_name = split_param[2] and split_param[2][3]
if not team_name then return false, better_commands.error(S("Missing team name")), 0 end
if better_commands.teams.teams[team_name] then
return false, better_commands.error(S("Team @1 already exists", team_name)), 0
end
if team_name:find("[^%w_]") then
return false, better_commands.error(S("Invalid team name @1: Can only contain letters, numbers, and underscores", team_name)), 0
end
local display_name = split_param[3] and split_param[3][3]
if not display_name then display_name = team_name end
better_commands.teams.teams[team_name] = {name = team_name, display_name = display_name}
return true, S("Added team @1", team_name), 1
elseif subcommand == "empty" or subcommand == "remove" then
local team_name = split_param[2] and split_param[2][3]
if not team_name then return false, better_commands.error(S("Missing team name")), 0 end
if better_commands.teams.teams[team_name] then
local display_name = better_commands.format_team_name(team_name)
if subcommand == "remove" then
better_commands.teams.teams[team_name] = nil
end
for player_name, player_team in pairs(better_commands.teams.players) do
if player_team == team_name then
better_commands.teams.players[player_name] = nil
end
end
if subcommand == "remove" then
return true, S("Removed team [@1]", display_name), 1
end
return true, S("Removed all players from team [@1]", display_name), 1
else
return false, better_commands.error(S("Team @1 does not exist", team_name)), 0
end
elseif subcommand == "join" then
local team_name = split_param[2] and split_param[2][3]
if not team_name then return false, better_commands.error(S("Missing team name")), 0 end
if not better_commands.teams.teams[team_name] then
return false, better_commands.error(S("Team @1 does not exist", team_name)), 0
end
local selector = split_param[3]
if not selector then
if context.executor.is_player and context.executor:is_player() then
better_commands.teams.players[context.executor:get_player_name()] = team_name
return true, S("Joined team [@1]", better_commands.format_team_name(team_name)), 1
end
else
local count = 0
local last
local names, err = better_commands.get_scoreboard_names(selector, context)
if err or not names then return false, better_commands.error(err), 0 end
for name in pairs(names) do
if count < 1 then last = better_commands.format_name(name) end
count = count + 1
better_commands.teams.players[name] = team_name
end
if count < 1 then
return false, better_commands.error(S("No target entities found")), 0
elseif count == 1 then
return true, S("Added @1 to team [@2]", better_commands.format_name(last), better_commands.format_team_name(team_name)), 1
else
return true, S("Added @1 entities to [@2]", count, better_commands.format_team_name(team_name)), 1
end
end
elseif subcommand == "leave" then
local selector = split_param[2]
local count = 0
local last
if not selector then
if context.executor.is_player and context.executor:is_player() then
last = context.executor:get_player_name()
count = 1
better_commands.teams.players[last] = nil
else
return false, better_commands.error(S("Non-players cannot be on a team")), 0
end
else
local names, err = better_commands.get_scoreboard_names(selector, context)
if err or not names then return false, better_commands.error(err), 0 end
for _, name in ipairs(names) do
if better_commands.teams.players[name] then
count = count + 1
last = name
better_commands.teams.players[name] = nil
end
end
end
if count < 1 then
return false, better_commands.error(S("No target entities found")), 0
elseif count == 1 then
return true, S("Removed @1 from any team", better_commands.format_name(last)), 1
else
return true, S("Removed @1 from any team", count), 1
end
elseif subcommand == "list" then
local team_name = split_param[2] and split_param[2][3]
if not team_name then
local count = 0
local result = ""
local comma
for team, team_data in pairs(better_commands.teams.teams) do
count = count + 1
local color = team_data.color or "white"
color = better_commands.team_colors[color] or color
if comma then result = result..", " else comma = true end
result = result..string.format("[%s]", minetest.colorize(color, team_data.display_name or team))
end
if count > 0 then
return true, S("There are @1 team(s): @2", count, result), 1
else
return true, S("There are no teams"), 1
end
elseif better_commands.teams.teams[team_name] then
local count = 0
local result = ""
local comma
local display_name = better_commands.format_team_name(team_name)
for name, team in pairs(better_commands.teams.players) do
if team == team_name then
count = count + 1
local formatted_name = better_commands.format_name(name)
if comma then result = result..", " else comma = true end
result = minetest.colorize("#00ff00", minetest.strip_colors(formatted_name)) -- not sure why ACOVG makes it green
end
end
if count > 0 then
return true, S("Team [@1] has @2 member(s): @3", display_name, count, result), count
else
return true, S("There are no members on team [@1]", display_name), 1
end
else
return false, better_commands.error(S("Team [@1] does not exist", team_name)), 0
end
elseif subcommand == "modify" then
local team_name = split_param[2] and split_param[2][3]
if not team_name then return false, better_commands.error(S("Team name is required")), 0 end
local team_data = better_commands.teams.teams[team_name]
if not team_data then return false, better_commands.error(S("Unknown team '@1'", team_name)), 0 end
local key = split_param[3] and split_param[3][3]
if not key then return false, better_commands.error(S("Missing key")), 0 end
local value = split_param[4] and split_param[4][3]
if key == "color" then
if value then
if not better_commands.team_colors[value] then return false, better_commands.error(S("Invalid color: @1", value)), 0 end
team_data.color = value
return true, S("Set color of team [@1] to @2", better_commands.format_team_name(team_name), value), 1
else
team_data.color = nil
return true, S("Reset color of team [@1]", better_commands.format_team_name(team_name)), 1
end
elseif key == "displayName" then
if value then
team_data.display_name = value
return true, S("Set display name of team [@1] to @2", better_commands.format_team_name(team_name), value), 1
else
team_data.display_name = team_name
return true, S("Reset display name of team [@1]", better_commands.format_team_name(team_name)), 1
end
elseif key == "friendlyFire" then
if value == "true" then
team_data.pvp = true
elseif value == "false" then
team_data.pvp = false
else
return false, better_commands.error(S("Value must be 'true' or 'false', not @1", value)), 0
end
return true, S("Set friendly fire for team [@1] to @2", better_commands.format_team_name(team_name), value), 1
elseif key == "nameFormat" then
if not split_param[4] then
team_data.name_format = nil
return true, S("Reset name format for team [@1]", better_commands.format_team_name(team_name)), 1
end
local name_format = param:sub(split_param[4][1], -1)
team_data.name_format = name_format
return true, S("Set name format for team [@1] to @2", better_commands.format_team_name(team_name), value), 1
else
return false, better_commands.error(S("Value must be 'color', 'displayName', 'friendlyFire', or 'nameFormat'")), 0
end
end
return false, better_commands.error(S("Must be 'add', 'empty', 'join', 'leave', 'list', 'modify', or 'remove', not @1", subcommand)), 0
end
})