-
Notifications
You must be signed in to change notification settings - Fork 3
/
tournament_commands.lua
287 lines (261 loc) · 9.86 KB
/
tournament_commands.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
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
})