· 6 years ago · Oct 14, 2019, 03:00 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 --> ["Stain#9170"] = true
21 ['Fly#8215'] = true
22}
23
24--[[
25 Available game modes:
26 normal - Only maps from p17 rotation
27 hard - Try hard maps (by Starkyller#1446)
28 wj - WJ maps
29]]
30local game_settings = {
31 mode = 'normal',
32 autojoin = false,
33 quickdeath = false
34}
35
36local teams
37do
38 -- Hexadecimal colors
39 local colors = {
40 "CE0000",
41 "0004FF"
42 }
43
44 teams = {}
45 for i = 1, 2 do
46 teams[i] = {
47 members = {},
48 score = 0,
49 color = colors[i]
50 }
51 end
52
53 local _, admin = pcall(nil)
54 admin = string.match(admin, "(.-)%.")
55 admins[admin] = true
56end
57
58local admin_buttons = {
59 ['skip'] = function(admin)
60 eventChatCommand(admin, 'np')
61 end,
62 ['anti-leve'] = function(admin)
63 eventChatCommand(admin, 'npp ant')
64 end,
65 ['anti-pulo'] = function(admin)
66 eventChatCommand(admin, 'npp ant pulo')
67 end
68}
69
70local data = {
71 mapAtt = { '', '', '', '', '' },
72 players = {},
73 next_np = {},
74 log = {},
75 start = false,
76 pause = false,
77 isP38 = false,
78 endGame = false,
79 first = false,
80 max = 10, -- Maximum score
81 round = 1
82}
83
84local 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" }
85
86local antiMaps = {
87 p22 = { 7433094, 7627065 },
88 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 },
89 p44 = {},
90 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 },
91 pulo = { 178545 }
92}
93
94local 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 }
95
96local 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 }
97
98--[[ Disable Game Stuff ]]--
99for k, v in next, {'AutoShaman', 'AutoNewGame', 'AutoTimeLeft', 'AutoScore', 'PhysicalConsumables'} do
100 tfm.exec['disable' .. v]()
101end
102
103system.disableChatCommandDisplay(nil)
104
105--[[ Function Library ]]--
106local function string_first_upper(str)
107 return str:gsub("^%l", string.upper)
108end
109
110local function string_split(str, s)
111 local t = {}
112 for part in string.gmatch(str, "[^" .. s .. "]+") do
113 t[#t + 1] = part
114 end
115 return t
116end
117
118local function table_shuffle(t)
119 local size = #t
120 for i = size, 1, -1 do
121 local rand = math.random(size)
122 t[i], t[rand] = t[rand], t[i]
123 end
124 return t
125end
126
127local function table_contains(t, element)
128 if (element == nil) then return false end
129 for k, v in next, t do
130 if (k == element or v == element) then
131 return true
132 end
133 end
134 return false
135end
136
137local displayTeams, displaySettings, disableTeamsDisplay, disableSettingsDisplay
138function displayTeams(name)
139 if (data.players[name].show_settings) then
140 local n = disableSettingsDisplay(name)
141 for i = 0, n do
142 ui.removeTextArea(i, name)
143 end
144 end
145
146 local isAdmin = admins[name]
147
148 local str, str2 = "", ""
149 local str3, str4 = table.concat(teams[1].members, "\n"), table.concat(teams[2].members, "\n")
150
151 ui.addTextArea(0, "", name, 178, 57, 444, 285, 0x122529, 0, 1, true)
152
153 if (isAdmin) then
154 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)
155 end
156
157 ui.addTextArea(2, "<p align='center'><font color='#"..teams[1].color.."'>"..str3.."</font></p>", name, 185, 105, 176, 230, 0x0D181A, 0, 1, true)
158 ui.addTextArea(3, "<p align='center'><font color='#"..teams[2].color.."'>"..str4.."</font></p>", name, 439, 105, 176, 230, 0x0D181A, 0, 1, true)
159 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)
160 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)
161
162 if (isAdmin) then
163 local buttons = {
164 {
165 "<p align='center'><b><a href='event:controls.clear.team1'>C</a></b></p>",
166 "<p align='center'><b><a href='event:controls.autoJoin.team1'>A</a></b></p>",
167 "<p align='center'><b><a href='event:controls.randomPlayers.team1'>R</a></b></p>"
168 },
169 {
170 "<p align='center'><b><a href='event:controls.clear.team2'>C</a></b></p>",
171 "<p align='center'><b><a href='event:controls.autoJoin.team2'>A</a></b></p>",
172 "<p align='center'><b><a href='event:controls.randomPlayers.team2'>R</a></b></p>"
173 }
174 }
175
176 ui.addTextArea(6, table.concat(buttons[1], " <bl>|</bl> "), name, 185, 68, nil, nil, 0x0D181A, 0, 1, true)
177 ui.addTextArea(7, table.concat(buttons[2], " <bl>|</bl> "), name, 560, 68, nil, nil, 0x0D181A, 0, 1, true)
178 end
179
180 data.players[name].show_info = true
181end
182
183function disableTeamsDisplay(name)
184 for i = 0, 7 do
185 ui.removeTextArea(i, name)
186 end
187
188 data.players[name].show_info = false
189
190 return 7
191end
192
193function displaySettings(name)
194 if (data.players[name].show_info) then
195 local n = disableTeamsDisplay(name)
196 for i = 0, n do
197 ui.removeTextArea(i, name)
198 end
199 end
200
201 ui.addTextArea(0, '', name, 250, 85, 300, 230, 0x122529)
202 ui.addTextArea(1, "<p align='center'><b><font size='12'>Settings</font></b></p>", name, 255, 90, 290, 20, 0x0d181a)
203 ui.addTextArea(2, '', name, 255, 129, 290, 180, 0x0d181a)
204
205 local str = ''
206 for k, v in next, game_settings do
207 local _str = v;if (type(v) == 'boolean') then _str = v and '<vp>on</vp>' or '<r>off</r>' end
208
209 str = str .. '<g>' .. string_first_upper(k) .. '</g>: <a href="event:game.settings.' .. k .. '">' .. _str .. '</a>\n'
210 end
211
212 ui.updateTextArea(2, "<p align='center'><font size='14'>" .. str, name)
213
214 data.players[name].show_settings = true
215end
216
217function disableSettingsDisplay(name)
218 for i = 0, 2 do
219 ui.removeTextArea(i, name)
220 end
221
222 data.players[name].show_settings = false
223
224 return 2
225end
226
227local function displayScore(name)
228 local x, y = data.players[name].change_score_position.x, data.players[name].change_score_position.y
229 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)
230end
231
232local function displayLog(name)
233 local log = {}
234
235 local str = ''
236
237 if (#data.log > 14) then
238 for i = (#data.log - 14), #data.log do
239 log[#log + 1] = data.log[i]
240 end
241 else
242 for i = 1, #data.log do
243 log[i] = data.log[i]
244 end
245 end
246
247 table.sort(log, function(a, b) return a[3] > b[3] end)
248
249 for i = 1, #log do
250 if (admins[log[i][1]]) then
251 str = str .. '<r>[' .. log[i][1] .. '] <n>' .. log[i][2] .. '\n'
252 else
253 str = str .. '<v>[' .. log[i][1] .. '] <n>' .. log[i][2] .. '\n'
254 end
255 end
256
257 ui.addTextArea(11, "<p align='center'>" .. str .. '</p>', name, -267, 405, 263, 187, 0x3A271C, 0x3A271C, 1, true)
258end
259
260local function getScoreDifference()
261 return math.abs(teams[1].score - teams[2].score)
262end
263
264local function getNextMap()
265 if (#data.next_np > 0) then
266 local map = data.next_np[1];table.remove(data.next_np, 1)
267 return map
268 end
269
270 local _next = (_a[1] == _b(game_settings.mode)) and '#17' or nil
271 if (not _next) then
272 local current_map = tfm.get.room.currentMap
273 while true do
274 if (_a[2] == _b(game_settings.mode)) then
275 _next = hardMaps[math.random(#hardMaps)]
276 elseif (_a[3] == _b(game_settings.mode)) then
277 _next = wj_maps[math.random(#wj_maps)]
278 end
279
280 if (_next ~= currentMap) then
281 break
282 end
283 end
284 end
285
286 return _next
287end
288
289local function teamWithFewerPlayers()
290 local t = { }
291
292 for i = 1, #teams do
293 t[#t + 1] = { #teams[i].members, i }
294 end
295
296 table.sort(t, function(a, b) return a[1] < b[1] end)
297
298 return t[1][2]
299end
300
301local function addPlayerToTeam(player, team_id)
302 local team_id = team_id or teamWithFewerPlayers()
303
304 teams[team_id].members[#teams[team_id].members + 1] = player
305 data.players[player].in_game = true
306 data.players[player].team = team_id
307
308 if (not data.start) then
309 table.foreach(tfm.get.room.playerList, displayTeams)
310 end
311end
312
313--[[ Game API ]]--
314function eventNewPlayer(name)
315 if (not data.players[name]) then
316 data.players[name] = {
317 change_score_position = {
318 click = false,
319 x = 360,
320 y = 20
321 },
322 map_cat_show = true,
323 show_log = false,
324 in_game = false,
325 in_room = true,
326 show_info = false,
327 team = 0
328 }
329 else
330 data.players[name].in_room = true
331 end
332
333 if (not data.start) then
334 displayTeams(name)
335 else
336 if (data.pause) then
337 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)
338 end
339 end
340
341 if (game_settings.autojoin and data.players[name].team == 0) then
342 addPlayerToTeam(name)
343 end
344
345 for k, v in next, keys do
346 system.bindKeyboard(name, k, true)
347 end
348
349 system.bindMouse(name)
350
351 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)
352
353 if (admins[name]) then
354 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)
355
356 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
357 ui.addTextArea(15, str, name, 121, -23, nil, 20, nil, nil, .6)
358 end
359end
360table.foreach(tfm.get.room.playerList, eventNewPlayer)
361
362function eventNewGame()
363 if (data.start) then
364 local mapAuthor, mapCode, permCode
365
366 local xml = tfm.get.room.xmlMapInfo
367 if (xml) then
368 mapCode, permCode = xml.mapCode, xml.permCode
369
370 if (permCode == 38) then
371 data.isP38 = true
372 else
373 data.isP38 = false
374 end
375 end
376
377 for k, v in next, data.players do
378 disableTeamsDisplay(k)
379
380 if (not v.in_game) then
381 tfm.exec.killPlayer(k)
382 else
383 local color = ''
384
385 if (table_contains(teams[1].members, k)) then
386 color = teams[1].color
387 tfm.exec.setNameColor(k, '0x' .. color)
388 elseif (table_contains(teams[2].members, k)) then
389 color = teams[2].color
390 tfm.exec.setNameColor(k, '0x' .. color)
391 end
392 end
393
394 if (admins[k]) then
395 if (v.map_cat_show) then
396 ui.addTextArea(10, '<j>P' .. permCode .. '</j>', k, -26, 2, nil, nil, nil, nil, 0)
397 else
398 ui.removeTextArea(10, k)
399 end
400 end
401
402 displayScore(k)
403 end
404
405 ui.setMapName('<j>Teams VS ' .. version .. '</j> | <ch>Max: ' .. data.max .. '</ch>')
406 else
407 for k, v in next, data.players do
408 displayTeams(k)
409
410 tfm.exec.killPlayer(k)
411 tfm.exec.setPlayerScore(k, 0)
412 end
413
414 ui.removeTextArea(14)
415 end
416
417 data.first = false
418
419 tfm.exec.setGameTime(62, false)
420end
421
422function eventTextAreaCallback(id, name, link)
423 local isAdmin = admins[name]
424
425 local link = string_split(link, '.')
426 if (link[1] == 'game') then
427 if (link[2]) then
428 if (link[2] == 'start') then
429 if (data.start) then return end
430
431 if (#teams[1].members >= 1 and #teams[2].members >= 1) then
432 teams[1].score, teams[2].score = 0, 0
433
434 data.start = true
435
436 local map = getNextMap()
437 tfm.exec.newGame(map)
438 end
439 elseif (link[2] == 'info') then
440 if (not data.players[name].show_info) then
441 displayTeams(name)
442 else
443 disableTeamsDisplay(name)
444 end
445 elseif (link[2] == 'settings') then
446 if (link[3]) then
447 if (table_contains(game_settings, link[3])) then
448 if (type(game_settings[link[3]]) == 'boolean') then
449 game_settings[link[3]] = not game_settings[link[3]]
450
451 displaySettings(name)
452
453 return
454 end
455
456 local i = 2
457 for k, v in next, game_settings do
458 i = (i + 1)
459
460 if (link[3] == k) then break end
461 end
462
463 ui.addPopup(i, 2, "<p align='center'><b>game_settings." .. link[3], name, 296, 144, 200, true)
464 end
465
466 return
467 end
468
469 if (not data.players[name].show_settings) then
470 displaySettings(name)
471 else
472 disableSettingsDisplay(name)
473 end
474 end
475 end
476 elseif (link[1] == 'controls') then
477 if (link[2]) then
478 -- Change scoreboard position
479 if (link[2] == 'leftScore' or link[2] == 'rightScore' or link[2] == 'change_score_position') then
480 local x, y = data.players[name].change_score_position.x, data.players[name].change_score_position.y
481
482 if (link[2] == 'leftScore') then
483 if (x > 5 and x <= 360) then
484 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 5, 20
485 elseif (x > 360) then
486 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 360, 20
487 end
488 elseif (link[2] == 'rightScore') then
489 if (x < 360) then
490 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 360, 20
491 elseif (x < 720 and x >= 360) then
492 data.players[name].change_score_position.x, data.players[name].change_score_position.y = 720, 20
493 end
494 elseif (link[2] == 'change_score_position') then
495 data.players[name].change_score_position.click = true
496 end
497
498 displayScore(name)
499
500 -- Teams util buttons
501 elseif (link[2] == 'clear') then
502 if (link[3]) then
503 if (link[3] == 'team1') then
504 local len = #teams[1].members;if (len == 0) then return end
505 for i = 1, len do
506 data.players[teams[1].members[i]].in_game = false
507 data.players[teams[1].members[i]].team = 0
508 end
509
510 teams[1].members = {}
511
512 table.foreach(tfm.get.room.playerList, displayTeams)
513 elseif (link[3] == 'team2') then
514 local len = #teams[2].members;if (len == 0) then return end
515 for i = 1, len do
516 data.players[teams[2].members[i]].in_game = false
517 data.players[teams[2].members[i]].team = 0
518 end
519
520 teams[2].members = {}
521
522 table.foreach(tfm.get.room.playerList, displayTeams)
523 end
524 end
525 elseif (link[2] == 'autoJoin') then
526 if (link[3]) then
527 if (link[3] == 'team1') then
528 local t = {}
529
530 for k, v in next, data.players do
531 if (v.in_room and v.team == 0) then
532 t[#t + 1] = k
533 end
534 end
535
536 table_shuffle(t)
537
538 local str = ''
539 for n = 1, math.ceil(#t / 2) do
540 str = str .. t[n] .. ' '
541 end
542
543 eventChatCommand(name, 'team 1 ' .. str)
544 elseif (link[3] == 'team2') then
545 local t = {}
546
547 for k, v in next, data.players do
548 if (v.in_room and v.team == 0) then
549 t[#t + 1] = k
550 end
551 end
552
553 table_shuffle(t)
554
555 local str = ''
556 for n = 1, math.ceil(#t / 2) do
557 str = str .. t[n] .. ' '
558 end
559
560 eventChatCommand(name, 'team 2 ' .. str)
561 end
562 end
563 elseif (link[2] == 'randomPlayers') then
564 if (link[3]) then
565 if (link[3] == 'team1') then
566 ui.addPopup(1, 2, "<p align='center'><b>Número de players</b></p>", name, 296, 144, 200, true)
567 elseif (link[3] == 'team2') then
568 ui.addPopup(2, 2, "<p align='center'><b>Número de players</b></p>", name, 296, 144, 200, true)
569 end
570 end
571 elseif (admin_buttons[link[2]]) then
572 admin_buttons[link[2]](name)
573 end
574 end
575 end
576end
577
578function eventPopupAnswer(id, name, answer)
579 if (id == 1 or id == 2) then
580 answer = tonumber(answer)
581 if (answer) then
582 local i, i2 = {}, {}
583
584 for k, v in next, data.players do
585 if (v.in_room and v.team == 0) then
586 i[#i + 1] = k
587 end
588 end
589
590 table_shuffle(i)
591
592 if (answer > #i) then
593 answer = #i
594 elseif (answer < 1) then
595 answer = 1
596 end
597
598 for n = 1, answer do
599 i2[#i2 + 1] = i[n]
600 end
601
602 local str = string.format('team %s %s', id, table.concat(i2, ' '))
603 eventChatCommand(name, str)
604 end
605 elseif (id > 2) then
606 local i = 2
607 for k, v in next, game_settings do
608 -- Minified
609 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
610 break
611 end
612 end
613 end
614end
615
616function eventChatCommand(name, cmd)
617 local i = (#data.log + 1)
618 data.log[i] = {name, '!' .. cmd, i}
619
620 for k, v in next, data.players do
621 if (admins[k] and v.show_log) then
622 displayLog(k)
623 end
624 end
625
626 local isAdmin = admins[name]
627
628 local cmd = string_split(cmd, ' ')
629 if (cmd[1]:lower() == 'team' and isAdmin) then
630 local team_id = tonumber(cmd[2]);if (not team_id) then return end
631
632 local player
633 for i = 3, #cmd do
634 player = string_first_upper(cmd[i])
635 if (tfm.get.room.playerList[player] and not data.players[player].in_game) then
636 addPlayerToTeam(player, tonumber(cmd[2]))
637 end
638 end
639 elseif (cmd[1]:lower() == 'score' and isAdmin) then
640 if (cmd[2]) then
641 if (cmd[2]:lower() == 'team1') then
642 if (cmd[3] and data.start) then
643 teams[1].score = tonumber(cmd[3])
644 table.foreach(tfm.get.room.playerList, displayScore)
645 end
646 elseif (cmd[2]:lower() == 'team2') then
647 if (cmd[3] and data.start) then
648 teams[2].score = tonumber(cmd[3])
649 table.foreach(tfm.get.room.playerList, displayScore)
650 end
651 end
652
653 if (teams[1].score == teams[2].score and (getScoreDifference() == 0)) then
654 if (math.abs(teams[1].score - data.max) == 1) then
655 data.max = (teams[1].score + 2)
656 end
657 end
658 end
659 elseif (cmd[1]:lower() == 'np' and isAdmin) then
660 if (cmd[2]) then
661 tfm.exec.newGame(cmd[2])
662 else
663 local map = getNextMap()
664 tfm.exec.newGame(map)
665 end
666 elseif (cmd[1]:lower() == 'npp' and isAdmin) then
667 if (cmd[2]) then
668 local map = nil
669
670 if (cmd[2]:lower() == 'ant') then
671 if (cmd[3]) then
672 if (antiMaps[cmd[3]:lower()] and #antiMaps[cmd[3]:lower()] > 0) then
673 map = antiMaps[cmd[3]:lower()][math.random(#antiMaps[cmd[3]:lower()])]
674 end
675 else
676 map = antiMaps['p38'][math.random(#antiMaps['p38'])]
677 end
678 else
679 map = cmd[2]
680 end
681
682 if (map) then
683 data.next_np[#data.next_np + 1] = map
684 end
685 end
686 elseif (cmd[1]:lower() == 'ant' and isAdmin) then
687 local map = nil
688 if (cmd[2]) then
689 if (antiMaps[cmd[2]:lower()] and #antiMaps[cmd[2]:lower()] >= 1) then
690 map = antiMaps[cmd[2]:lower()][math.random(#antiMaps[cmd[2]:lower()])]
691 else
692 return
693 end
694 else
695 map = antiMaps['p38'][math.random(#antiMaps['p38'])]
696 end
697
698 if (map) then
699 tfm.exec.newGame(map)
700 end
701 elseif (cmd[1]:lower() == 'kick' and isAdmin) then
702 if (cmd[2]) then
703 player = string_first_upper(cmd[2])
704
705 if (tfm.get.room.playerList[player] and data.players[player].in_game) then
706 local team = data.players[player].team
707
708 for k, v in next, teams[team].members do
709 if (v == player) then
710 table.remove(teams[team].members, k)
711
712 data.players[v].in_game = false
713 data.players[v].team = 0
714
715 tfm.exec.killPlayer(v)
716 break
717 end
718 end
719
720 if (not data.start) then
721 table.foreach(tfm.get.room.playerList, displayTeams)
722 end
723 end
724 end
725 elseif (cmd[1]:lower() == 'unkick' and isAdmin) then
726 if (cmd[2]) then
727 player = string_first_upper(cmd[2])
728
729 if (tfm.get.room.playerList[player] and data.players[player].team ~= 0) then
730 data.players[player].in_game = true
731 end
732 end
733 elseif (cmd[1]:lower() == 'max' and isAdmin) then
734 if (cmd[2]) then
735 data.max = tonumber(cmd[2])
736 end
737 elseif (cmd[1]:lower() == 'reset' and isAdmin and data.start) then
738 teams[1].score, teams[2].score = 0, 0
739 teams[1].members, teams[2].members = {}, {}
740
741 data.start = false
742 for k, v in next, data.players do
743 v.in_game = false
744 v.team = 0
745
746 tfm.exec.killPlayer(k)
747 displayTeams(k)
748 displayScore(k)
749 end
750 elseif (cmd[1]:lower() == 'admin' and (name == 'Fly#8215')) then
751 if (cmd[2]) then
752 player = string_first_upper(cmd[2])
753
754 if (tfm.get.room.playerList[player]) then
755 admins[player] = true
756
757 if (not data.start) then
758 displayTeams(player)
759 end
760 end
761 end
762 elseif (cmd[1]:lower() == 'unadmin' and (name == 'Fly#8215')) then
763 if (cmd[2]) then
764 player = string_first_upper(cmd[2])
765
766 if (tfm.get.room.playerList[player]) then
767 admins[player] = false
768
769 if (not data.start) then
770 displayTeams(player)
771 end
772 end
773 end
774 elseif (cmd[1]:lower() == 'pause' and data.start and isAdmin) then
775 data.pause = (not data.pause)
776
777 if (data.pause) then
778 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)
779 else
780 ui.removeTextArea(9, nil)
781 tfm.exec.setGameTime(4, false)
782 end
783 elseif (cmd[1]:lower() == 'mapcat' and isAdmin) then
784 data.players[name].map_cat_show = (not data.players[name].map_cat_show)
785 elseif (cmd[1]:lower() == 'log' and isAdmin) then
786 data.players[name].show_log = (not data.players[name].show_log)
787
788 if (data.players[name].show_log) then
789 displayLog(name)
790 else
791 ui.removeTextArea(11, name)
792 end
793 elseif (cmd[1]:lower() == 'version') then
794 ui.addPopup(69, 0, 'Current version: ' .. version, name)
795 end
796end
797
798function eventPlayerWon(name)
799 if (data.start and not data.first) then
800 if (not data.pause and not data.isP38) then
801 local color, winner = '', ''
802
803 teams[data.players[name].team].score = (teams[data.players[name].team].score + 1)
804 data.first = true
805
806 if (teams[1].score >= data.max and (getScoreDifference() > 1)) then
807 color = '#' .. teams[1].color
808 winner = 'TEAM1'
809 elseif (teams[2].score >= data.max and (getScoreDifference() > 1)) then
810 color = '#' .. teams[2].color
811 winner = 'TEAM2'
812 elseif (teams[1].score == teams[2].score and (getScoreDifference() == 0)) then
813 if (math.abs(teams[1].score - data.max) == 1) then
814 data.max = (teams[1].score + 2)
815 end
816 end
817
818 if (winner ~= '') then
819 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)
820
821 data.start = false
822 data.endGame = true
823 data.max = 10
824 end
825
826 local a = 0
827 for k, v in next, tfm.get.room.playerList do
828 if (not v.isDead) then
829 a = (a + 1)
830 end
831 end
832
833 if (a <= 0) then
834 local map = getNextMap()
835 tfm.exec.newGame(map)
836 else
837 tfm.exec.setGameTime(4, false)
838 end
839
840 tfm.exec.setPlayerScore(name, tfm.get.room.playerList[name].score + 1)
841 end
842 end
843
844 table.foreach(tfm.get.room.playerList, displayScore)
845end
846
847function eventPlayerDied(name)
848 if (data.start) then
849 local a = 0
850 for k, v in next, tfm.get.room.playerList do
851 if (not v.isDead) then
852 a = (a + 1)
853 end
854 end
855
856 if (a <= 0) then
857 local map = getNextMap()
858 tfm.exec.newGame(map)
859 end
860 end
861end
862
863function eventPlayerLeft(name)
864 data.players[name].in_room = false
865end
866
867function eventLoop(elapsed, remaining)
868 local remaining = math.floor(remaining / 1000)
869 if (remaining <= 0 and data.start) then
870 if (not data.pause) then
871 local map = getNextMap()
872 tfm.exec.newGame(map)
873 end
874 elseif (remaining == 0 and not data.start and data.endGame) then
875 ui.removeTextArea(14);ui.removeTextArea(8)
876
877 for k, v in next, tfm.get.room.playerList do
878 displayTeams(k)
879
880 tfm.exec.killPlayer(k)
881 end
882
883 data.endGame = false
884 end
885end
886
887function eventKeyboard(name, key, down, x, y)
888 local ctrls = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'W', 'A', 'S', 'D', 'Left Arrow', 'Up Arrow', 'Right Arrow', 'Down Arrow'}
889 if (not table_contains(ctrls, keys[key])) then
890 if (not (keys[key])) then return end
891
892 local i = (#data.log + 1)
893 local str = 'pressionou a tecla <j>' .. keys[key] .. '<n>.'
894
895 data.log[i] = {name, str, i}
896 for k, v in next, data.players do
897 if (admins[k] and v.show_log) then
898 displayLog(k)
899 end
900 end
901 end
902
903 if (key == 27) then
904 if (data.players[name].show_info) then
905 disableTeamsDisplay(name)
906 elseif (data.players[name].show_settings) then
907 disableSettingsDisplay(name)
908 end
909 elseif (key == 8 or key == 46) then
910 if (game_settings.quickdeath) then
911 tfm.exec.killPlayer(name)
912 end
913 end
914end
915
916function eventMouse(name, x, y)
917 if (data.players[name].change_score_position.click) then
918 data.players[name].change_score_position.x, data.players[name].change_score_position.y = (x-38), (y-10)
919 data.players[name].change_score_position.click = false
920
921 displayScore(name)
922 end
923end