pvpplus/tournament_commands.lua

288 lines
9.9 KiB
Lua

local tournament_starting_time = tonumber(minetest.settings:get("pvpplus.tournament_starting_time")) or 60 -- seconds
local tournament = pvpplus.tournament -- Shortcut reference
minetest.register_privilege("tournament_mod", "PvP Tournament Moderator")
local function check_permission(name)
if minetest.get_player_privs(name).tournament_mod then
return true
end
if (tournament.starting_infos.starter or "") == name then
return true
end
return false
end
minetest.register_chatcommand("start_global_tournament", {
params = "",
description = "Start a PvP tournament engaging every connected players and starting immediately",
privs = {interact = true, tournament_mod = true},
func = function(name, param)
-- Fill start infos
tournament.starting_infos.starter = name
tournament.starting_infos.open_time = nil
tournament.starting_infos.start_time = os.time()
return pvpplus.start_global_tournament(name)
end
})
minetest.register_chatcommand("stop_tournament", {
params = "",
description = "Stops the current PvP tournament",
privs = {interact = true},
func = function(name, param)
if not pvpplus.is_running_tournament() then
return false, "There is no currently running tournament."
end
if not check_permission(name) then
return false, "You have no permission to stop this tournament."
end
pvpplus.stop_tournament()
return true
end
})
minetest.register_chatcommand("remove_from_tournament", {
params = "<name>",
description = "Removes a player from a PvP tournament",
privs = {interact = true},
func = function(name, param)
if not pvpplus.is_playing_tournament(name) then
return false, "Player " .. name .. " is not currently playing a tournament."
end
if not check_permission(name) then
return false, "You have no permission to remove a player from this tournament."
end
if not minetest.get_player_by_name(param) then
return false, "Player does not exist. Please refer to usage: /help remove_from_tournament"
end
minetest.chat_send_player(param, "You have been removed from the tournament by " .. name)
pvpplus.remove_from_tournament(param)
end
})
minetest.register_chatcommand("add_to_tournament", {
params = "<name>",
description = "Adds a player to the current tournament",
privs = {interact = true, tournament_mod = true},
func = function(name, param)
if not minetest.get_player_by_name(param) then
return false, "Player does not exist. Please refer to usage: /help add_from_tournament"
end
if pvpplus.is_playing_tournament(player) then
return false, "Player is already playing a tournament."
end
if not pvpplus.is_running_tournament() then
return false, "There is no currently running tournament."
end
minetest.chat_send_player(param, "You have been added to the current tournament by " .. name)
pvpplus.add_to_tournament(param)
end
})
minetest.register_chatcommand("leave_tournament", {
params = "",
description = "Leaves a PvP tournament",
privs = {interact = true},
func = function(name, param)
if not pvpplus.is_playing_tournament(name) then
return false, "You are not playing a tournament."
end
pvpplus.remove_from_tournament(name)
end
})
minetest.register_chatcommand("engage", {
params = "",
description = "Engages for the next PvP tournament",
privs = {interact = true},
func = function(name, param)
if pvpplus.is_playing_tournament(name) then
return false, "You are already playing a tournament."
end
if not pvpplus.is_engaging_players() then
return false, "There is no opened tournament. Type /tournament!"
end
pvpplus.engage_player(name)
minetest.chat_send_all("Player "..name.." engaged himself/herself for the PvP tournament!")
end
})
minetest.register_chatcommand("tournament_info", {
params = "",
description = "Prints tournament informations",
privs = {},
func = function(name, param)
if pvpplus.is_engaging_players() then
local str = "There is an open tournament which is not yet started (you can engage for this tournament by typing /engage).\n" ..
"The tournament was open by: " .. tournament.starting_infos.starter ..
"\nThe tournament will start in: " .. os.difftime(tournament.starting_infos.start_time, os.time()) .. " seconds\n" ..
"The tournament is open since: " .. os.date("%c", tournament.starting_infos.open_time) ..
(tournament.engagement_position and "\nEngaged players will be teleported before the tournament starts.\n" or "\nEngaged players won't be teleported.\n") ..
(tournament.damage_motionless and "Motionless players will be automatically damaged." or "Motionless players won't be damaged.") ..
"\nCurrently engaged players are: "
for player, _ in pairs(tournament.engaged_players) do
str = str .. player .. ", "
end
str = str:sub(0, -3)
return true, str
elseif pvpplus.is_running_tournament() then
local str = "There is a currrently running tournament.\n" ..
"The tournament was open by: " .. tournament.starting_infos.starter ..
"\nThe tournament is running since: " .. os.date("%c", tournament.starting_infos.start_time) ..
(tournament.damage_motionless and "\nMotionless players are automatically damaged." or "\nMotionless players are not damaged.") ..
"\nInitially engaged players were: "
for player, _ in pairs(tournament.starting_infos.initially_engaged_players) do
str = str .. player .. ", "
end
str = str:sub(0, -3)
str = str .. "\nRemaining players are: "
for player, _ in pairs(tournament.players) do
str = str .. player .. ", "
end
str = str:sub(0, -3)
return true, str
else
return true, "There is no currently running tournament. You can start a new tournament by using /tournament (see /help tournament)."
end
end
})
minetest.register_chatcommand("tournament_music_toggle", {
params = "",
description = "Toggles the music loop",
privs = {},
func = function(name, param)
if not pvpplus.is_playing_tournament(name) then
return false, "You are not currently playing a tournament. If you're hearing the tournament music, then it's a bug, please contact a moderator."
end
if tournament.sound_handles[name] then
minetest.sound_stop(tournament.sound_handles[name])
tournament.sound_handles[name] = nil
return true, "Stopped music loop."
else
tournament.sound_handles[name] = minetest.sound_play("pvpplus_tournament_loop", {
to_player = name,
gain = 1.0,
loop = true,
})
return true, "Started music loop."
end
end
})
--- /tournament command ---
-- value: {[bool: whether the parameter requires the tournament_mod privilege], [string: type of the wanted value (number or string), nil if no value]}
local param_list = {
noteleport = {false, nil},
start_delay = {false, "number"},
broadcast = {true, nil},
damage_motionless = {false, nil},
}
local function parse_params(param, name)
local params = param:split(" ")
local param_table = {}
for _, param in ipairs(params) do
local opt, val = param:match("(.+)=(.*)")
if opt then
param = opt
end
-- Validity checks...
if not param_list[param] then
return false, "Invalid option: " .. param
end
if param_list[param][1] and not minetest.get_player_privs(name).tournament_mod then
return false, "Option " .. param .. " requires the tournament_mod privilege."
end
if val and not param_list[param][2] then
return false, "Option " .. param .. " should not be used with a value."
end
if not val and param_list[param][2] then
return false, "Option " .. param .. " expects a value (e.g. option=value)."
end
if param_list[param][2] == "number" and tonumber(val) == nil then
return false, "Option " .. param .. " expects a number as value."
end
if val then
if param_list[param][2] == "number" then
param_table[param] = tonumber(val)
else -- string
param_table[param] = val
end
else
param_table[param] = true
end
end
return true, param_table
end
minetest.register_chatcommand("tournament", {
params = "[noteleport] [broadcast] [start_delay=<seconds>]",
description = "Creates a new tournament, optionally teleporting players to your current position 10 seconds before the tournament starts.",
privs = {interact = true},
func = function(name, param)
local params
do
local ok, res = parse_params(param, name)
if ok == false then
return false, res
end
params = res
end
local starting_time = params.start_delay or tournament_starting_time
if starting_time < 10 or starting_time > 600 then
return false, "Please set a start delay between 10s and 600s."
end
local teleport = params.noteleport ~= true
tournament.broadcast_messages = params.broadcast or false
tournament.damage_motionless = params.damage_motionless or false
-- Fill start infos
tournament.starting_infos.starter = name
tournament.starting_infos.open_time = os.time()
tournament.starting_infos.start_time = os.time() + starting_time
-- Allow engaging
local e, m = pvpplus.allow_engaging(name, teleport)
if e == false then
return false, m
end
-- Engage starter
pvpplus.engage_player(name)
-- Chat messages
local chat_send = (params.broadcast and minetest.chat_send_all) or pvpplus.chat_send_tournament
minetest.chat_send_all("The tournament will begin in " .. tostring(starting_time).."s.") -- First chat message is always broadcasted
minetest.after(starting_time - 10, function()
pvpplus.chat_send_tournament("The tournament will begin in 10s! Engage yourself by typing /engage!", true)
pvpplus.teleport_engaged_players()
end)
minetest.after(starting_time - 5, function()
pvpplus.chat_send_tournament("The tournament will begin in 5s!", true)
end)
for i = 1, 4 do
minetest.after(starting_time - i, function()
pvpplus.chat_send_tournament(tostring(i).."!", true)
end)
end
-- Start tournament
minetest.after(starting_time, function(name)
local ok, e = pvpplus.start_tournament()
if ok == false and e then
minetest.chat_send_player(name, e)
end
end, name)
end
})