· 6 years ago · Apr 07, 2020, 12:04 AM
1--[[
2 Developed by -> Fly#8215
3 Last update -> 13.10.2019
4 Current version -> 2.8.7
5
6 !!! UPDATE !!!
7 * Added quick death setting. When turned on, the player who press DEL or BACKSPACE key will be killed instantly.
8 * Now the player who starts the script will be set into the admin list automatically.
9 * Bugs fixed!
10]]
11
12--[[ Script Data ]]--
13-- Minified [DON'T CHANGE IT]
14local _a={'110\\111\\114\\109\\97\\108','104\\97\\114\\100','119\\106'}local function _b(c)local d=''for e=1,#c do d=d..string.byte(string.sub(c,e,e))..(e<#c and'\\'or'')end;return d end;local function _f(c)local g=''string.gsub(c,'[^\]+',function(h)g=g..string.char(h)end)return g end
15
16local version = '2.8.6'
17
18-- Admins list
19local admins = {
20 -- Format --> ["Player#tag"] = true
21 ['Starkyller#1446'] = true,
22 ['Fly#8215'] = true
23}
24
25--[[
26 Available game modes:
27 normal - Only maps from p17 rotation
28 hard - Try hard maps (by Starkyller#1446)
29 wj - WJ maps
30]]
31local game_settings = {
32 mode = 'normal',
33 autojoin = false,
34 quickdeath = false
35}
36
37local teams
38do
39 -- Hexadecimal colors
40 local colors = {
41 "CE0000",
42 "0004FF"
43 }
44
45 teams = {}
46 for i = 1, 2 do
47 teams[i] = {
48 members = {},
49 score = 0,
50 color = colors[i]
51 }
52 end
53
54 local _, admin = pcall(nil)
55 admin = string.match(admin, "(.-)%.")
56 admins[admin] = true
57end
58
59local admin_buttons = {
60 ['skip'] = function(admin)
61 eventChatCommand(admin, 'np')
62 end,
63 ['anti-leve'] = function(admin)
64 eventChatCommand(admin, 'npp ant')
65 end,
66 ['anti-pulo'] = function(admin)
67 eventChatCommand(admin, 'npp ant pulo')
68 end
69}
70
71local data = {
72 mapAtt = { '', '', '', '', '' },
73 players = {},
74 next_np = {},
75 log = {},
76 start = false,
77 pause = false,
78 isP38 = false,
79 endGame = false,
80 first = false,
81 max = 20, -- Maximum score
82 round = 1
83}
84
85local keys = { [8] = "Backspace", [9] = "Tab", [13] = "Enter", [16] = "Shift", [17] = "Control", [18] = "Alt", [19] = "Pause", [20] = "Caps Lock", [27] = "Escape", [32] = "Spacebar", [33] = "Page Up", [34] = "Page Down", [35] = "End", [36] = "Home", [37] = "Left Arrow", [38] = "Up Arrow", [39] = "Right Arrow", [40] = "Down Arrow", [45] = "Insert", [46] = "Delete", [48] = "0", [49] = "1", [50] = "2", [51] = "3", [52] = "4", [53] = "5", [54] = "6", [55] = "7", [56] = "8", [57] = "9", [65] = "A", [66] = "B", [67] = "C", [68] = "D", [69] = "E", [70] = "F", [71] = "G", [72] = "H", [73] = "I", [74] = "K", [75] = "J", [76] = "L", [77] = "M", [78] = "N", [79] = "O", [80] = "P", [81] = "Q", [82] = "R", [83] = "S", [84] = "T", [85] = "U", [86] = "V", [87] = "W", [88] = "X", [89] = "Y", [90] = "Z", [91] = "Windows (Left)", [92] = "Windows (Right)", [93] = "Application Key", [97] = "1 (Numbpad)", [98] = "2 (Numbpad)", [99] = "3 (Numbpad)", [100] = "4 (Numbpad)", [101] = "5 (Numbpad)", [102] = "6 (Numbpad)", [103] = "7 (Numbpad)", [104] = "8 (Numbpad)", [105] = "9 (Numbpad)", [106] = "* Asterix (Numbpad)", [107] = "+ Plus (Numbpad)", [109] = "- Minus (Numbpad)", [110] = "\\ Forward Slash (Numbpad)", [112] = "F1", [113] = "F2", [114] = "F3", [115] = "F4", [116] = "F5", [117] = "F6", [118] = "F7", [119] = "F8", [120] = "F9", [121] = "F10", [122] = "F11", [123] = "F12", [144] = "Numlock", [145] = "Scroll Lock", [186] = "; Semicolon", [187] = "= Equals", [188] = ", Comma", [189] = "- Hyphen", [190] = ". Period", [191] = "/ Forward Slash", [192] = "` Apostrophe", [219] = "[ Left Square Bracket", [220] = "\\ Backslash", [221] = "] Right Square Bracket" }
86
87local antiMaps = {
88 p22 = { 7433094, 7627065 },
89 p38 = { 457253, 6640740, 6640807, 6640857, 6641096, 6641104, 6641109, 6641134, 6641137, 6641138, 6641145, 6640737, 6640748, 6640758, 6640803, 6640808, 6640811, 6640816, 6640823, 6640833, 6640846, 6640852, 6640854, 6640858, 6640859, 6640860, 6640866, 6640869, 6640884, 6641058, 6641064, 6641067, 6641069, 6641077, 6641079, 6641088, 6641090, 6641101, 6641132, 6640881, 6641075, 6641087, 6641110, 6641111, 6641121, 6641144, 6641097, 6641115, 6641141, 6641143, 6640755, 6640828, 6640889, 6641063, 6641094, 6641108, 6641124, 6641128, 6641130, 6641139, 6641147, 6640760, 6640837, 6640851, 6641059, 6641062, 6641083 },
90 p44 = {},
91 agil = { 212542, 308992, 31420, 315801, 323085, 344865, 345257, 352381, 356982, 357328, 367520, 386029, 391831, 419374, 429822, 470727, 507325, 508796, 606723, 664949, 1654841, 1724289, 1951856, 1964752, 2070768, 2134537, 2141379, 2369254, 3575108, 3821104, 4815404, 5032745, 5590554, 5805021, 5813480, 6665146 },
92 pulo = { 178545 }
93}
94
95local hardMaps = { 7601909, 7601911, 7601913, 7601914, 7601915, 7601917, 7601919, 7601920, 7602019, 7602026, 7602022, 7602027, 7602029, 7602031, 7602033, 7602034, 7602039, 7602042, 7602053, 7602056, 7602067, 7602078, 7602082, 7602084, 7602085, 7602089, 7602092, 7602094, 7602097, 7602372, 7602373, 7602374, 7602375, 7602377, 7602378, 7602379, 7602380, 7602383, 7602384, 7602385, 7602386, 7602387, 7602389, 7602390, 7602392, 7602393, 7615151, 7615152, 7615154, 7615155, 7615157, 7615158, 7615159, 7615160, 7615162, 7615164, 7615165, 7615166, 7615167, 7615169, 7615170, 7615264, 7615266, 7615270, 7615272, 7615275, 7615327, 7615332, 7615333, 7615335, 7615338, 7615342, 7615343, 7615346, 7615347, 7615351, 7615355, 7615358, 7615360, 7615413, 7645917, 7645918, 7645921, 7645922, 7645923, 7645927, 7645939, 7645941, 7645946, 7645951 }
96
97local wj_maps = { 324428, 3788529, 6119572, 6119641, 6119642, 6119643, 6119655, 6120650, 6133176, 6146352, 6274154, 6313036, 6641061, 6641085, 7465241, 7485501, 7095618, 6799629, 6755943, 7627933, 7628267, 7628262, 7628264, 7627928, 7627934, 7627939, 7630265, 7630264, 7627957, 7627955, 7627953, 7628299, 7608227, 7608225, 7608215, 7601758, 6809280, 6809273, 6798504, 6798488, 6785385 }
98
99--[[ Disable Game Stuff ]]--
100for k, v in next, {'AutoShaman', 'AutoNewGame', 'AutoTimeLeft', 'AutoScore', 'PhysicalConsumables'} do
101 tfm.exec['disable' .. v]()
102end
103
104system.disableChatCommandDisplay(nil)
105
106--[[ Function Library ]]--
107local function string_first_upper(str)
108 return str:gsub("^%l", string.upper)
109end
110
111local function string_split(str, s)
112 local t = {}
113 for part in string.gmatch(str, "[^" .. s .. "]+") do
114 t[#t + 1] = part
115 end
116 return t
117end
118
119local function table_shuffle(t)
120 local size = #t
121 for i = size, 1, -1 do
122 local rand = math.random(size)
123 t[i], t[rand] = t[rand], t[i]
124 end
125 return t
126end
127
128local function table_contains(t, element)
129 if (element == nil) then return false end
130 for k, v in next, t do
131 if (k == element or v == element) then
132 return true
133 end
134 end
135 return false
136end
137
138local displayTeams, displaySettings, disableTeamsDisplay, disableSettingsDisplay
139function displayTeams(name)
140 if (data.players[name].show_settings) then
141 local n = disableSettingsDisplay(name)
142 for i = 0, n do
143 ui.removeTextArea(i, name)
144 end
145 end
146
147 local isAdmin = admins[name]
148
149 local str, str2 = "", ""
150 local str3, str4 = table.concat(teams[1].members, "\n"), table.concat(teams[2].members, "\n")
151
152 ui.addTextArea(0, "", name, 178, 57, 444, 285, 0x122529, 0, 1, true)
153
154 if (isAdmin) then
155 ui.addTextArea(1, "<p align='center'><font size='13'><b><r><a href='event:game.start'>START</a></r></b></font></p>", name, 324, 193, 150, 22, 0x0D181A, 0, 1, true)
156 end
157
158 ui.addTextArea(2, "<p align='center'><font color='#"..teams[1].color.."'>"..str3.."</font></p>", name, 185, 105, 176, 230, 0x0D181A, 0, 1, true)
159 ui.addTextArea(3, "<p align='center'><font color='#"..teams[2].color.."'>"..str4.."</font></p>", name, 439, 105, 176, 230, 0x0D181A, 0, 1, true)
160 ui.addTextArea(4, "<p align='center'><b><font color='#"..teams[1].color.."'>Team 1</font></b></p>", name, 185, 66, 176, 20, 0x0D181A, 0, 1, true)
161 ui.addTextArea(5, "<p align='center'><b><font color='#"..teams[2].color.."'>Team 2</font></b></p>", name, 439, 66, 176, 20, 0x0D181A, 0, 1, true)
162
163 if (isAdmin) then
164 local buttons = {
165 {
166 "<p align='center'><b><a href='event:controls.clear.team1'>C</a></b></p>",
167 "<p align='center'><b><a href='event:controls.autoJoin.team1'>A</a></b></p>",
168 "<p align='center'><b><a href='event:controls.randomPlayers.team1'>R</a></b></p>"
169 },
170 {
171 "<p align='center'><b><a href='event:controls.clear.team2'>C</a></b></p>",
172 "<p align='center'><b><a href='event:controls.autoJoin.team2'>A</a></b></p>",
173 "<p align='center'><b><a href='event:controls.randomPlayers.team2'>R</a></b></p>"
174 }
175 }
176
177 ui.addTextArea(6, table.concat(buttons[1], " <bl>|</bl> "), name, 185, 68, nil, nil, 0x0D181A, 0, 1, true)
178 ui.addTextArea(7, table.concat(buttons[2], " <bl>|</bl> "), name, 560, 68, nil, nil, 0x0D181A, 0, 1, true)
179 end
180
181 data.players[name].show_info = true
182end
183
184function disableTeamsDisplay(name)
185 for i = 0, 7 do
186 ui.removeTextArea(i, name)
187 end
188
189 data.players[name].show_info = false
190
191 return 7
192end
193
194function displaySettings(name)
195 if (data.players[name].show_info) then
196 local n = disableTeamsDisplay(name)
197 for i = 0, n do
198 ui.removeTextArea(i, name)
199 end
200 end
201
202 ui.addTextArea(0, '', name, 250, 85, 300, 230, 0x122529)
203 ui.addTextArea(1, "<p align='center'><b><font size='12'>Settings</font></b></p>", name, 255, 90, 290, 20, 0x0d181a)
204 ui.addTextArea(2, '', name, 255, 129, 290, 180, 0x0d181a)
205
206 local str = ''
207 for k, v in next, game_settings do
208 local _str = v;if (type(v) == 'boolean') then _str = v and '<vp>on</vp>' or '<r>off</r>' end
209
210 str = str .. '<g>' .. string_first_upper(k) .. '</g>: <a href="event:game.settings.' .. k .. '">' .. _str .. '</a>\n'
211 end
212
213 ui.updateTextArea(2, "<p align='center'><font size='14'>" .. str, name)
214
215 data.players[name].show_settings = true
216end
217
218function disableSettingsDisplay(name)
219 for i = 0, 2 do
220 ui.removeTextArea(i, name)
221 end
222
223 data.players[name].show_settings = false
224
225 return 2
226end
227
228local function displayScore(name)
229 local x, y = data.players[name].change_score_position.x, data.players[name].change_score_position.y
230 ui.addTextArea(14, string.format("<p align='center'><font size='16'><a href='event:controls.leftScore'>«</a></font><font size='23'><font color='#%s'>%s<N> <a href='event:controls.change_score_position'>x</a> <font color='#%s'>%s</font></N></font></font><font size='16'><a href='event:controls.rightScore'>»</a></font></p>", teams[1].color, teams[1].score, teams[2].color, teams[2].score), name, x, y, nil, 0, 0, 0, 0, true)
231end
232
233local function displayLog(name)
234 local log = {}
235
236 local str = ''
237
238 if (#data.log > 14) then
239 for i = (#data.log - 14), #data.log do
240 log[#log + 1] = data.log[i]
241 end
242 else
243 for i = 1, #data.log do
244 log[i] = data.log[i]
245 end
246 end
247
248 table.sort(log, function(a, b) return a[3] > b[3] end)
249
250 for i = 1, #log do
251 if (admins[log[i][1]]) then
252 str = str .. '<r>[' .. log[i][1] .. '] <n>' .. log[i][2] .. '\n'
253 else
254 str = str .. '<v>[' .. log[i][1] .. '] <n>' .. log[i][2] .. '\n'
255 end
256 end
257
258 ui.addTextArea(11, "<p align='center'>" .. str .. '</p>', name, -267, 405, 263, 187, 0x3A271C, 0x3A271C, 1, true)
259end
260
261local function getScoreDifference()
262 return math.abs(teams[1].score - teams[2].score)
263end
264
265local function getNextMap()
266 if (#data.next_np > 0) then
267 local map = data.next_np[1];table.remove(data.next_np, 1)
268 return map
269 end
270
271 local _next = (_a[1] == _b(game_settings.mode)) and '#17' or nil
272 if (not _next) then
273 local current_map = tfm.get.room.currentMap
274 while true do
275 if (_a[2] == _b(game_settings.mode)) then
276 _next = hardMaps[math.random(#hardMaps)]
277 elseif (_a[3] == _b(game_settings.mode)) then
278 _next = wj_maps[math.random(#wj_maps)]
279 end
280
281 if (_next ~= currentMap) then
282 break
283 end
284 end
285 end
286
287 return _next
288end
289
290local function teamWithFewerPlayers()
291 local t = { }
292
293 for i = 1, #teams do
294 t[#t + 1] = { #teams[i].members, i }
295 end
296
297 table.sort(t, function(a, b) return a[1] < b[1] end)
298
299 return t[1][2]
300end
301
302local function addPlayerToTeam(player, team_id)
303 local team_id = team_id or teamWithFewerPlayers()
304
305 teams[team_id].members[#teams[team_id].members + 1] = player
306 data.players[player].in_game = true
307 data.players[player].team = team_id
308
309 if (not data.start) then
310 table.foreach(tfm.get.room.playerList, displayTeams)
311 end
312end
313
314--[[ Game API ]]--
315function eventNewPlayer(name)
316 if (not data.players[name]) then
317 data.players[name] = {
318 change_score_position = {
319 click = false,
320 x = 360,
321 y = 20
322 },
323 map_cat_show = true,
324 show_log = false,
325 in_game = false,
326 in_room = true,
327 show_info = false,
328 team = 0
329 }
330 else
331 data.players[name].in_room = true
332 end
333
334 if (not data.start) then
335 displayTeams(name)
336 else
337 if (data.pause) then
338 ui.addTextArea(9, "<p align='center'><font size='60' color='#FFFFFF'>▸ P A U S E D ◂</font></p>", name, 0, 200, 800, nil, 0, 0, 0)
339 end
340 end
341
342 if (game_settings.autojoin and data.players[name].team == 0) then
343 addPlayerToTeam(name)
344 end
345
346 for k, v in next, keys do
347 system.bindKeyboard(name, k, true)
348 end
349
350 system.bindMouse(name)
351
352 ui.addTextArea(12, "<p align='center'><b><i><font size='12'><a href='event:game.info'>i</a></font></i></b></p>", name, 5, -23, 16, 20, nil, nil, .6)
353
354 if (admins[name]) then
355 ui.addTextArea(13, "<p align='center'><b><font size='12'><a href='event:game.settings'>Settings</a></font></b></p>", name, 31, -23, 80, 20, nil, nil, .6)
356
357 local str = "<font size='12'>";for k in next, admin_buttons do str = str .. string.format("<a href='event:controls.%s'>%s</a>", k, string_first_upper(k)) .. ' <j>|</j> ' end
358 ui.addTextArea(15, str, name, 121, -23, nil, 20, nil, nil, .6)
359 end
360end
361table.foreach(tfm.get.room.playerList, eventNewPlayer)
362
363function eventNewGame()
364 if (data.start) then
365 local mapAuthor, mapCode, permCode
366
367 local xml = tfm.get.room.xmlMapInfo
368 if (xml) then
369 mapCode, permCode = xml.mapCode, xml.permCode
370
371 if (permCode == 38) then
372 data.isP38 = true
373 else
374 data.isP38 = false
375 end
376 end
377
378 for k, v in next, data.players do
379 disableTeamsDisplay(k)
380
381 if (not v.in_game) then
382 tfm.exec.killPlayer(k)
383 else
384 local color = ''
385
386 if (table_contains(teams[1].members, k)) then
387 color = teams[1].color
388 tfm.exec.setNameColor(k, '0x' .. color)
389 elseif (table_contains(teams[2].members, k)) then
390 color = teams[2].color
391 tfm.exec.setNameColor(k, '0x' .. color)
392 end
393 end
394
395 if (admins[k]) then
396 if (v.map_cat_show) then
397 ui.addTextArea(10, '<j>P' .. permCode .. '</j>', k, -26, 2, nil, nil, nil, nil, 0)
398 else
399 ui.removeTextArea(10, k)
400 end
401 end
402
403 displayScore(k)
404 end
405
406 ui.setMapName('<j>Teams VS ' .. version .. '</j> | <ch>Max: ' .. data.max .. '</ch>')
407 else
408 for k, v in next, data.players do
409 displayTeams(k)
410
411 tfm.exec.killPlayer(k)
412 tfm.exec.setPlayerScore(k, 0)
413 end
414
415 ui.removeTextArea(14)
416 end
417
418 data.first = false
419
420 tfm.exec.setGameTime(62, false)
421end
422
423function eventTextAreaCallback(id, name, link)
424 local isAdmin = admins[name]
425
426 local link = string_split(link, '.')
427 if (link[1] == 'game') then
428 if (link[2]) then
429 if (link[2] == 'start') then
430 if (data.start) then return end
431
432 if (#teams[1].members >= 1 and #teams[2].members >= 1) then
433 teams[1].score, teams[2].score = 0, 0
434
435 data.start = true
436
437 local map = getNextMap()
438 tfm.exec.newGame(map)
439 end
440 elseif (link[2] == 'info') then
441 if (not data.players[name].show_info) then
442 displayTeams(name)
443 else
444 disableTeamsDisplay(name)
445 end
446 elseif (link[2] == 'settings') then
447 if (link[3]) then
448 if (table_contains(game_settings, link[3])) then
449 if (type(game_settings[link[3]]) == 'boolean') then
450 game_settings[link[3]] = not game_settings[link[3]]
451
452 displaySettings(name)
453
454 return
455 end
456
457 local i = 2
458 for k, v in next, game_settings do
459 i = (i + 1)
460
461 if (link[3] == k) then break end
462 end
463
464 ui.addPopup(i, 2, "<p align='center'><b>game_settings." .. link[3], name, 296, 144, 200, true)
465 end
466
467 return
468 end
469
470 if (not data.players[name].show_settings) then
471 displaySettings(name)
472 else
473 disableSettingsDisplay(name)
474 end
475 end
476 end
477 elseif (link[1] == 'controls') then
478 if (link[2]) then
479 -- Change scoreboard position
480 if (link[2] == 'leftScore' or link[2] == 'rightScore' or link[2] == 'change_score_position') then
481 local x, y = data.players[name].change_score_position.x, data.players[name].change_score_position.y
482
483 if (link[2] == 'leftScore') then
484 if (x > 5 and x <= 360) then
485 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 5, 20
486 elseif (x > 360) then
487 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 360, 20
488 end
489 elseif (link[2] == 'rightScore') then
490 if (x < 360) then
491 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 360, 20
492 elseif (x < 720 and x >= 360) then
493 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 720, 20
494 end
495 elseif (link[2] == 'change_score_position') then
496 data.players[name].change_score_position.click = true
497 end
498
499 displayScore(name)
500
501 -- Teams util buttons
502 elseif (link[2] == 'clear') then
503 if (link[3]) then
504 if (link[3] == 'team1') then
505 local len = #teams[1].members;if (len == 0) then return end
506 for i = 1, len do
507 data.players[teams[1].members[i]].in_game = false
508 data.players[teams[1].members[i]].team = 0
509 end
510
511 teams[1].members = {}
512
513 table.foreach(tfm.get.room.playerList, displayTeams)
514 elseif (link[3] == 'team2') then
515 local len = #teams[2].members;if (len == 0) then return end
516 for i = 1, len do
517 data.players[teams[2].members[i]].in_game = false
518 data.players[teams[2].members[i]].team = 0
519 end
520
521 teams[2].members = {}
522
523 table.foreach(tfm.get.room.playerList, displayTeams)
524 end
525 end
526 elseif (link[2] == 'autoJoin') then
527 if (link[3]) then
528 if (link[3] == 'team1') then
529 local t = {}
530
531 for k, v in next, data.players do
532 if (v.in_room and v.team == 0) then
533 t[#t + 1] = k
534 end
535 end
536
537 table_shuffle(t)
538
539 local str = ''
540 for n = 1, math.ceil(#t / 2) do
541 str = str .. t[n] .. ' '
542 end
543
544 eventChatCommand(name, 'team 1 ' .. str)
545 elseif (link[3] == 'team2') then
546 local t = {}
547
548 for k, v in next, data.players do
549 if (v.in_room and v.team == 0) then
550 t[#t + 1] = k
551 end
552 end
553
554 table_shuffle(t)
555
556 local str = ''
557 for n = 1, math.ceil(#t / 2) do
558 str = str .. t[n] .. ' '
559 end
560
561 eventChatCommand(name, 'team 2 ' .. str)
562 end
563 end
564 elseif (link[2] == 'randomPlayers') then
565 if (link[3]) then
566 if (link[3] == 'team1') then
567 ui.addPopup(1, 2, "<p align='center'><b>Número de players</b></p>", name, 296, 144, 200, true)
568 elseif (link[3] == 'team2') then
569 ui.addPopup(2, 2, "<p align='center'><b>Número de players</b></p>", name, 296, 144, 200, true)
570 end
571 end
572 elseif (admin_buttons[link[2]]) then
573 admin_buttons[link[2]](name)
574 end
575 end
576 end
577end
578
579function eventPopupAnswer(id, name, answer)
580 if (id == 1 or id == 2) then
581 answer = tonumber(answer)
582 if (answer) then
583 local i, i2 = {}, {}
584
585 for k, v in next, data.players do
586 if (v.in_room and v.team == 0) then
587 i[#i + 1] = k
588 end
589 end
590
591 table_shuffle(i)
592
593 if (answer > #i) then
594 answer = #i
595 elseif (answer < 1) then
596 answer = 1
597 end
598
599 for n = 1, answer do
600 i2[#i2 + 1] = i[n]
601 end
602
603 local str = string.format('team %s %s', id, table.concat(i2, ' '))
604 eventChatCommand(name, str)
605 end
606 elseif (id > 2) then
607 local i = 2
608 for k, v in next, game_settings do
609 -- Minified
610 i=i+1;if i==id then local a=type(v)if a=='string'then local b=_b(answer)if not table_contains(_a,b)then return end end;local c=_G['to'..a](answer)if c then game_settings[k]=c;displaySettings(name)end
611 break
612 end
613 end
614 end
615end
616
617function eventChatCommand(name, cmd)
618 local i = (#data.log + 1)
619 data.log[i] = {name, '!' .. cmd, i}
620
621 for k, v in next, data.players do
622 if (admins[k] and v.show_log) then
623 displayLog(k)
624 end
625 end
626
627 local isAdmin = admins[name]
628
629 local cmd = string_split(cmd, ' ')
630 if (cmd[1]:lower() == 'team' and isAdmin) then
631 local team_id = tonumber(cmd[2]);if (not team_id) then return end
632
633 local player
634 for i = 3, #cmd do
635 player = string_first_upper(cmd[i])
636 if (tfm.get.room.playerList[player] and not data.players[player].in_game) then
637 addPlayerToTeam(player, tonumber(cmd[2]))
638 end
639 end
640 elseif (cmd[1]:lower() == 'score' and isAdmin) then
641 if (cmd[2]) then
642 if (cmd[2]:lower() == 'team1') then
643 if (cmd[3] and data.start) then
644 teams[1].score = tonumber(cmd[3])
645 table.foreach(tfm.get.room.playerList, displayScore)
646 end
647 elseif (cmd[2]:lower() == 'team2') then
648 if (cmd[3] and data.start) then
649 teams[2].score = tonumber(cmd[3])
650 table.foreach(tfm.get.room.playerList, displayScore)
651 end
652 end
653
654 if (teams[1].score == teams[2].score and (getScoreDifference() == 0)) then
655 if (math.abs(teams[1].score - data.max) == 1) then
656 data.max = (teams[1].score + 2)
657 end
658 end
659 end
660 elseif (cmd[1]:lower() == 'np' and isAdmin) then
661 if (cmd[2]) then
662 tfm.exec.newGame(cmd[2])
663 else
664 local map = getNextMap()
665 tfm.exec.newGame(map)
666 end
667 elseif (cmd[1]:lower() == 'npp' and isAdmin) then
668 if (cmd[2]) then
669 local map = nil
670
671 if (cmd[2]:lower() == 'ant') then
672 if (cmd[3]) then
673 if (antiMaps[cmd[3]:lower()] and #antiMaps[cmd[3]:lower()] > 0) then
674 map = antiMaps[cmd[3]:lower()][math.random(#antiMaps[cmd[3]:lower()])]
675 end
676 else
677 map = antiMaps['p38'][math.random(#antiMaps['p38'])]
678 end
679 else
680 map = cmd[2]
681 end
682
683 if (map) then
684 data.next_np[#data.next_np + 1] = map
685 end
686 end
687 elseif (cmd[1]:lower() == 'ant' and isAdmin) then
688 local map = nil
689 if (cmd[2]) then
690 if (antiMaps[cmd[2]:lower()] and #antiMaps[cmd[2]:lower()] >= 1) then
691 map = antiMaps[cmd[2]:lower()][math.random(#antiMaps[cmd[2]:lower()])]
692 else
693 return
694 end
695 else
696 map = antiMaps['p38'][math.random(#antiMaps['p38'])]
697 end
698
699 if (map) then
700 tfm.exec.newGame(map)
701 end
702 elseif (cmd[1]:lower() == 'kick' and isAdmin) then
703 if (cmd[2]) then
704 player = string_first_upper(cmd[2])
705
706 if (tfm.get.room.playerList[player] and data.players[player].in_game) then
707 local team = data.players[player].team
708
709 for k, v in next, teams[team].members do
710 if (v == player) then
711 table.remove(teams[team].members, k)
712
713 data.players[v].in_game = false
714 data.players[v].team = 0
715
716 tfm.exec.killPlayer(v)
717 break
718 end
719 end
720
721 if (not data.start) then
722 table.foreach(tfm.get.room.playerList, displayTeams)
723 end
724 end
725 end
726 elseif (cmd[1]:lower() == 'unkick' and isAdmin) then
727 if (cmd[2]) then
728 player = string_first_upper(cmd[2])
729
730 if (tfm.get.room.playerList[player] and data.players[player].team ~= 0) then
731 data.players[player].in_game = true
732 end
733 end
734 elseif (cmd[1]:lower() == 'max' and isAdmin) then
735 if (cmd[2]) then
736 data.max = tonumber(cmd[2])
737 end
738 elseif (cmd[1]:lower() == 'reset' and isAdmin and data.start) then
739 teams[1].score, teams[2].score = 0, 0
740 teams[1].members, teams[2].members = {}, {}
741
742 data.start = false
743 for k, v in next, data.players do
744 v.in_game = false
745 v.team = 0
746
747 tfm.exec.killPlayer(k)
748 displayTeams(k)
749 displayScore(k)
750 end
751 elseif (cmd[1]:lower() == 'admin' and (name == 'Fly#8215')) then
752 if (cmd[2]) then
753 player = string_first_upper(cmd[2])
754
755 if (tfm.get.room.playerList[player]) then
756 admins[player] = true
757
758 if (not data.start) then
759 displayTeams(player)
760 end
761 end
762 end
763 elseif (cmd[1]:lower() == 'unadmin' and (name == 'Fly#8215')) then
764 if (cmd[2]) then
765 player = string_first_upper(cmd[2])
766
767 if (tfm.get.room.playerList[player]) then
768 admins[player] = false
769
770 if (not data.start) then
771 displayTeams(player)
772 end
773 end
774 end
775 elseif (cmd[1]:lower() == 'pause' and data.start and isAdmin) then
776 data.pause = (not data.pause)
777
778 if (data.pause) then
779 ui.addTextArea(9, "<p align='center'><font size='60' color='#FFFFFF'>P A U S E D</font></p>", nil, 5, 200, 800, nil, 0, 0, 0, true)
780 else
781 ui.removeTextArea(9, nil)
782 tfm.exec.setGameTime(4, false)
783 end
784 elseif (cmd[1]:lower() == 'mapcat' and isAdmin) then
785 data.players[name].map_cat_show = (not data.players[name].map_cat_show)
786 elseif (cmd[1]:lower() == 'log' and isAdmin) then
787 data.players[name].show_log = (not data.players[name].show_log)
788
789 if (data.players[name].show_log) then
790 displayLog(name)
791 else
792 ui.removeTextArea(11, name)
793 end
794 elseif (cmd[1]:lower() == 'version') then
795 ui.addPopup(69, 0, 'Current version: ' .. version, name)
796 end
797end
798
799function eventPlayerWon(name)
800 if (data.start and not data.first) then
801 if (not data.pause and not data.isP38) then
802 local color, winner = '', ''
803
804 teams[data.players[name].team].score = (teams[data.players[name].team].score + 1)
805 data.first = true
806
807 if (teams[1].score >= data.max and (getScoreDifference() > 1)) then
808 color = '#' .. teams[1].color
809 winner = 'TEAM1'
810 elseif (teams[2].score >= data.max and (getScoreDifference() > 1)) then
811 color = '#' .. teams[2].color
812 winner = 'TEAM2'
813 elseif (teams[1].score == teams[2].score and (getScoreDifference() == 0)) then
814 if (math.abs(teams[1].score - data.max) == 1) then
815 data.max = (teams[1].score + 2)
816 end
817 end
818
819 if (winner ~= '') then
820 ui.addTextArea(8, string.format("<p align='center'><font size='37'><font color='%s'>%s IS THE TEAM WINNER. GG!</font></font></p>", color, winner), nil, 5, 170, 800, nil, 0, 0, 0, true)
821
822 data.start = false
823 data.endGame = true
824 data.max = 10
825 end
826
827 local a = 0
828 for k, v in next, tfm.get.room.playerList do
829 if (not v.isDead) then
830 a = (a + 1)
831 end
832 end
833
834 if (a <= 0) then
835 local map = getNextMap()
836 tfm.exec.newGame(map)
837 else
838 tfm.exec.setGameTime(4, false)
839 end
840
841 tfm.exec.setPlayerScore(name, tfm.get.room.playerList[name].score + 1)
842 end
843 end
844
845 table.foreach(tfm.get.room.playerList, displayScore)
846end
847
848function eventPlayerDied(name)
849 if (data.start) then
850 local a = 0
851 for k, v in next, tfm.get.room.playerList do
852 if (not v.isDead) then
853 a = (a + 1)
854 end
855 end
856
857 if (a <= 0) then
858 local map = getNextMap()
859 tfm.exec.newGame(map)
860 end
861 end
862end
863
864function eventPlayerLeft(name)
865 data.players[name].in_room = false
866end
867
868function eventLoop(elapsed, remaining)
869 local remaining = math.floor(remaining / 1000)
870 if (remaining <= 0 and data.start) then
871 if (not data.pause) then
872 local map = getNextMap()
873 tfm.exec.newGame(map)
874 end
875 elseif (remaining == 0 and not data.start and data.endGame) then
876 ui.removeTextArea(14);ui.removeTextArea(8)
877
878 for k, v in next, tfm.get.room.playerList do
879 displayTeams(k)
880
881 tfm.exec.killPlayer(k)
882 end
883
884 data.endGame = false
885 end
886end
887
888function eventKeyboard(name, key, down, x, y)
889 local ctrls = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'W', 'A', 'S', 'D', 'Left Arrow', 'Up Arrow', 'Right Arrow', 'Down Arrow'}
890 if (not table_contains(ctrls, keys[key])) then
891 if (not (keys[key])) then return end
892
893 local i = (#data.log + 1)
894 local str = 'pressionou a tecla <j>' .. keys[key] .. '<n>.'
895
896 data.log[i] = {name, str, i}
897 for k, v in next, data.players do
898 if (admins[k] and v.show_log) then
899 displayLog(k)
900 end
901 end
902 end
903
904 if (key == 27) then
905 if (data.players[name].show_info) then
906 disableTeamsDisplay(name)
907 elseif (data.players[name].show_settings) then
908 disableSettingsDisplay(name)
909 end
910 elseif (key == 8 or key == 46) then
911 if (game_settings.quickdeath) then
912 tfm.exec.killPlayer(name)
913 end
914 end
915end
916
917function eventMouse(name, x, y)
918 if (data.players[name].change_score_position.click) then
919 data.players[name].change_score_position.x, data.players[name].change_score_position.y = (x-38), (y-10)
920 data.players[name].change_score_position.click = false
921
922 displayScore(name)
923 end
924end