Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
63 kB
1
Indexable
Never
--[[
    Developed by -> Renangostoso#0000
    Last update -> 11.10.2020

    !!! New Update !!!
    * Bug fixes

    * By default, Auto-Join and Anti-Macro settings are enabled

    * New maps in rotation:
        ** Try-hard (burlas)
        ** P1
    * New game mode:
        ** mix

    * Some name changes:
        ** Name of P17 rotation mode is now -> racing

    -- Settings --
        - Anti-Macro -> System to detect excessive key presses
        - Auto-Join
        - Mode -> Game mode. Available ones: racing, hard, wj
        - No-Souris -> Forbids guest accounts to join the game.
            It also includes accounts that have less than 5 days of register time.
        - Quick-Death -> Enable death (/mort) through BACKSPACE/DELETE keys

    -- Commands List --
        -- Admins --
            - !team [id] [Player] -> Add Player into a team which has a specified id
                e.g., `!team 1 Player#0000`
            - !teamscore/!team_score [id] [number] -> Set score of a specified team
                e.g., `!teamscore 1 20`
            - !max/!score [number] -> Set score limit
            - !mapcat/!map_cat -> Enable or disable the display of map's category
            - !anti [agil/p22/p38/pulo] -> Run a random map from the anti-cheat list of a specified category.
                p38 is the default category
            - !map/!np [code] -> Run a new map
            - !npp/!nextmap/!next_map [code] -> Insert a specified map into game's list of next maps
            - !clearnpp/!clearnextmaps/!clear_next_maps -> Clear the list of next maps (those set with !npp command)
            - !kick/!remove/!ban [Player] -> Dismisse Player from game
            - !pause -> Pause/Resume the game
            - !reset -> Reset the game
        -- Public --
            - !version -> Display script version
]]

local math_abs    = math.abs
local math_ceil   = math.ceil
local math_floor  = math.floor
local math_random = math.random

local os_time  = os.time

local string_byte   = string.byte
local string_char   = string.char
local string_find   = string.find
local string_format = string.format
local string_gmatch = string.gmatch
local string_gsub   = string.gsub
local string_lower  = string.lower
local string_match  = string.match
local string_sub    = string.sub
local string_upper  = string.upper

local table_concat = table.concat
local table_remove = table.remove
local table_sort   = table.sort

local get_next_map, next_map, set_next_map

--[[
    System to avoid guest accounts. By: Bolodefchoco
    https://github.com/a801-luadev/useful-stuff/blob/master/killAllGuests.lua
]]
local check_player, kill_all_guests
do
    local guests, free = { }, { }

    local fiveDays = 1000 * 60 * 60 * 24 * 5 -- ms * s * m * h * d

    local killPlayer = tfm.exec.killPlayer

    local is_guest = function(playerName, playerData)
        return
            string_sub(playerName, 1, 1) == '*' or
            (os_time() - playerData.registrationDate) < fiveDays
    end

    check_player = function(playerName)
        if guests[playerName] or free[playerName] then
            return free[playerName] -- False if guest. True otherwise.
        end

        if is_guest(playerName, tfm.get.room.playerList[playerName]) then
            guests[playerName] = true
            return false
        else
            free[playerName] = true
            return true
        end
    end

    kill_all_guests = function()
        for playerName in next, guests do
            killPlayer(playerName)
        end
    end
end

--[[ Data ]]--
-- Minified
local _a={'114\\97\\99\\105\\110\\103','104\\97\\114\\100','119\\106','112\\49','109\\105\\120'}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;function ui_addTextArea(a,b,...)if a~=12 then return ui.addTextArea(a,b,...)end;if not string_find(b,'Renan')then b='<p align="center"><j>Made by:</j> Renan'end;ui.addTextArea(a,b,...)end
local version = '3.1.2'

-- Admins list
local admins              = {
    -- Format --> ["Player#tag"] = true
    ['Renangostoso#0000'] = true,
    ['Starkyller#1446']   = true,
    ['Tuggox#4348']       = true
}

--[[
    Available game modes:
        racing - P17 official rotation
        hard   - Try hard (burlas) maps
        mix    - Mixed up maps (P1 & P17)
        p1     - P1 random rotation
        wj     - WJ maps
]]
local game_settings = {
    mode            = 'racing',

    anti_macro      = true,
    auto_join       = true,
    no_souris       = false,
    quick_death     = false
}

local teams
do
    -- Hexadecimal colors
    local colors = {
        'CE0000',
        '0004FF'
    }

    local border_colors = {
        'CE0000',
        '0004FF'
    }

    teams = { }
    for i = 1, 2 do
        teams[i]         = {
            members      = { },

            score        = 0,

            border_color = border_colors[i],
            color        = colors[i]
        }
    end

    local _, admin = pcall(nil)
    admin = string_match(admin, '(.-)%.')
    admins[admin] = true
end

local np_list = { }
local players = { }

local admin_buttons = {
    {
        'Anti-Leve',
        function()
            set_next_map('anti')
        end
    },
    {
        'Anti-Pulo',
        function()
            set_next_map('anti', 'pulo')
        end
    },
    {
        'Clear Next Maps',
        function()
            np_list = { }
        end
    },
    {
        'Restart Map',
        function()
            tfm.exec.newGame(tfm.get.room.currentMap)
        end
    },
    {
        'Skip',
        function()
            local map = get_next_map()
            tfm.exec.newGame(map)
        end
    }
}

-- Maps
local anti_cheat_maps = {
    agil  = { 212542, 308992, 31420, 315801, 323085, 344865, 345257, 352381, 356982, 357328, 367520, 386029, 391831, 419374, 429822, 470727, 507325, 508796, 606723, 664949, 1724289, 1951856, 1964752, 2070768, 2134537, 2141379, 2369254, 3575108, 3821104, 4815404, 5032745, 5590554, 5805021, 5813480, 6665146 },
    p22   = { 7433094, 7627065 },
    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 },
    pulo = { 178545 }
}

local rotation = {
    hard       = { 7601909, 7601911, 7601913, 7601914, 7601915, 7601917, 7601919, 7601920, 7602019, 7602026, 7602022, 7602027, 7602029, 7602031, 7602033, 7602034, 7602039, 7602042, 7602056, 7602067, 7602078, 7602082, 7602084, 7602085, 7602089, 7602092, 7602094, 7602097, 7602372, 7602373, 7602374, 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, 7615266, 7615270, 7615272, 7615275, 7615327, 7615332, 7615333, 7615335, 7615338, 7615342, 7615343, 7615346, 7615347, 7615351, 7615355, 7615358, 7615360, 7645917, 7645918, 7645921, 7645922, 7645923, 7645927, 7645939, 7645941, 7645946, 7645951, 7728915, 7728921, 7728925, 7728931, 7728934, 7728936, 7728938, 7728942, 7728944, 7728947, 7728959, 7728964, 7728972, 7728974, 7728977, 7729122 },
    p1         = { 3186667, 5000099, 5339729, 7445961, 2917535, 2977431, 2005722, 3659613, 4318967, 1513031, 3661838, 5775860, 4203014, 1611752, 2218643, 385840, 1705452, 3734905, 2852366, 5149469, 5514161, 5522156, 3868463, 3746500, 1602910, 3018949, 3558216, 7332438, 7345446, 7271680, 7271427, 7250826, 7251952, 7235639, 2686505, 2836263, 2926504, 1587408, 2334110, 6915216, 5473030, 6649653, 1756843, 1593939, 3677765, 7097287, 1799933, 3256453, 3394477, 1949959, 4061041, 5492101, 1287222, 4076419, 3681952, 3656379, 349609, 1337717, 1646580, 1897442, 1897442, 6730235, 1347672, 2014026, 3838452, 3438340, 895735, 3099948, 1888550, 2282320, 914992, 339904, 2674591, 2300295, 2572599, 1532360, 1877091, 1427984, 1611663, 967177, 2791383, 2437987, 4465627, 1658156, 3077528, 3701233, 1939255, 1094544, 5067492.544145, 2433512, 6937031, 3675438, 7009481, 6974129, 3903481, 1717664, 2965755, 5173280, 3046622, 1844404, 2319756, 1921105, 235863, 481141, 3710878, 3745348, 1551411, 599339, 1132841, 3186738, 1445806, 2950316, 1999433, 7588217, 7588218, 7588221, 7588222, 7588224, 7588225, 7588229, 7588230, 7588233, 7588235, 7588238, 3517551, 7588239, 7588240, 7588243, 7588244, 7588245, 7588246, 7588249, 7588251, 7588253, 7588256, 7588257, 7586454, 4564380, 1709079, 1463576, 2473784, 1990585, 4225415, 3534755, 1529753, 6568183, 3964168, 4465679, 5830619, 1636847, 3084024, 2978758, 2207242, 2828225, 1430257, 1611752, 5083570, 1503669, 3658619, 3712466, 2156325, 2713762, 7301894, 912490, 3637190, 3690789, 1469911, 5086164, 3702120, 721910, 2093306, 3668632, 3891989, 3865829, 1807161, 2681705, 2013606, 1220037, 7586576, 7586577, 7586578, 7586579, 7586581, 7586582, 7586583, 7586584, 7586585, 7586587, 7586589, 7586590, 7586591, 7586592, 7586593, 7586594, 7586595, 3610554, 7586596, 7586597, 7586598, 7586600, 7586601, 7586602, 3089485, 7586603, 2163742, 1053539, 1721251, 5478906, 6205970, 3156745, 4348352, 3241835, 3326440, 1569481, 3636571, 2986279, 1643776, 3837289, 5431781, 6752042, 2418253, 2416543, 5160713, 3358124, 411687, 1712441, 193187, 2877165, 1608238, 1819776, 3480598, 2626804, 3581991, 3898426, 2481042, 3181008, 4182202, 5611222, 2100416, 2816064, 2543452, 3932685, 5105940, 389768, 5395761, 3697752, 1967351, 6830525, 3896856, 2705995, 3489333, 5484871, 2501538, 5313078, 1118306, 4818087, 3428934, 3757278, 5523199, 1944889, 1519256, 2894515, 3150084, 1468561, 5499302, 4900101, 3570936, 7585875, 7585876, 7585877, 7585879, 7585888, 7585889, 7585892, 7585893, 7585896, 7585897, 7585898, 7585899, 7585900, 3520878, 7585901, 7585903, 7585904, 7585906, 193187, 7585907, 7585908, 7585911, 7585912, 6733104, 521756, 2785571, 7243656, 2504433, 268985, 4697282, 2857448, 2457864, 1387242, 2983538, 1746823, 6872493, 3851834, 3143538, 468972, 5814223, 3841284, 3630979, 3216342, 2774931, 1040236, 677608, 895971, 3564891, 3676523, 2159625, 3697872, 6121939, 3806103, 3946237, 5539855, 1817776, 2185227, 2445318, 2973285, 6203577, 1606904, 3190335, 6103100, 1590935, 520308, 2154166, 6202855.1761416, 2767238, 3539557, 531393, 1537810, 7521287, 3803640, 3705380, 5000056, 1449651, 1666383, 3743515, 5647530, 1779582, 2962094, 3549002, 7259687, 1699725, 1451996, 1610004, 1338610, 296361, 1548446, 3023500, 6304005, 4380537, 7074890, 3520951, 1652941, 3755613, 4009415, 401705, 2237427, 6201167, 2784397, 5255657, 533946, 3015348, 4234518, 3387926, 1808440, 852036, 4271527, 3661778, 1580042, 2880295, 1616692, 2413286, 3988481, 2583328, 3221567, 1453388, 2972456, 5017009, 3663231, 3491935, 3478705, 1891199, 6140452, 6498002, 1706451, 3777243, 1691451, 3685069, 1964070, 5070340, 1972853, 2178289, 1418353, 3849085, 4298073, 2211530, 1845355, 6109280, 2035594, 7583983, 1999538, 733188, 7583985, 1407496, 885790, 3717973, 3906543, 5948551, 5976869, 2452276, 6070666, 1487531, 3026533, 1975642, 6714712, 3217173, 542206, 2913914, 5656820, 1769722, 1780844, 7227763, 7584185, 7584186, 7584187, 7584189, 7584190, 2668543, 7584191, 7584192, 7584193, 7584194, 7584195, 5707667, 7584197, 7584198, 7584201, 7584202, 7584204, 1840109, 3035430, 3641597, 5723425, 716454, 1748936, 2698747, 2024218, 3204335, 2833702, 505805, 2048050, 3696199, 3089894, 1828315, 3069262, 3750609, 2731707, 3729330, 1794589, 2017255, 7491603, 4640565, 4055165, 6840620, 6965421, 3164541, 6965421, 3685464, 2054943, 365315, 5813469, 1033390, 7054190, 1124859, 3641873, 3661173, 1473836, 2431444, 3503305, 5737012, 2423265, 1705725, 1949215, 1589402, 2476398, 5710452, 5919033, 2879902, 3497217, 6571252, 3433197, 6104868, 6726790, 1380450, 2558489, 3721136, 1650589, 3647084, 3624946, 6557245, 3912825, 5166234, 3029129, 1477421, 1799351, 1737233, 2038475, 1446502, 2012857, 1958837, 5432386, 6042206, 243962, 5070428, 2198167, 2749103, 1369255, 2557752, 5188867, 3731931, 3238202, 1439286, 5176687, 1446952, 1142162, 3328963, 721229, 6050971, 3531249, 3756184, 1532940, 6660659, 3184847, 1971197, 3832344, 5293621, 2239095, 7581422, 3379444, 7581425, 5402499, 7581426, 7581430, 7581431, 7581433, 857969, 7090005, 7581435, 7581437, 7581441, 4702472, 7581442, 7581443, 7581444, 7581445, 7581446, 7581447, 7581448, 7581449, 7581450, 5213306, 7581451, 7560419, 7581453, 7581456, 7581457, 7581458, 5746152, 7227007, 4864351, 3060011, 5200910, 3257930, 2398407, 1544861, 3144670, 1644081, 2006666, 1580374, 5796038, 2815472, 5681686, 3100650, 2692126, 1741073, 2102814, 3710363, 1402257, 2665959, 3615479, 2808418, 5756977, 370831, 2129581, 3684931, 2716169, 1609642, 3702443, 4359062, 6516286, 5524577, 2274853, 3831715, 3478750, 554595, 3681488, 3429348, 1630969, 808903, 1815144, 1997567, 2984611, 4966199, 2479767, 3350174, 2977670, 5758757, 1776462, 6032284, 1494544, 4211491, 1819646, 2787653, 2915889, 4723257, 1284922, 3402209, 5544351, 5096786, 1421488, 1319953, 2151630, 3090268, 3728775, 2696883, 6975901, 1682563, 1055301, 4089620, 5493813, 3388889, 3873919, 3621510, 2040327, 7563886, 7563888, 1703062, 1770702, 2049829, 1031162, 1940633, 1477077, 3485112, 3650626, 2240014, 3000880, 4833628, 1568124, 2599257, 2457551, 3963989, 7574385, 1923304, 319426, 2064891, 5952334, 5854437, 2962820, 3909564, 3110731, 3746970, 3671792, 630767, 3960389, 4625712, 1473876, 7088745, 6647453, 3236460, 1391129, 3894282, 1664227, 2816435, 5838710, 3285994, 5017387, 1476814, 2306483, 5568574, 2537299, 1183614, 6255741, 4143293, 1357913, 329489, 768679, 312415, 345232, 541888, 883644, 541088, 415457, 527634, 5327280, 3361351, 1792257, 2797861, 2954979, 3881931, 3733964, 2320378, 7574387, 7574388, 7574390, 7574391, 7574392, 2882873, 2695460, 5597023, 2098179, 7574400, 2201219, 5736061, 1582926, 1677763, 38286787, 1878759, 7543645, 393067, 3067756, 3963989, 6717825, 6731562, 6820863, 5865143, 5746807, 278585, 1821529, 6800839, 141355, 1220087, 2922338, 411415, 7574383, 5604555, 6453895, 7288042, 2011033, 1056854, 3041398, 311316, 7514011, 2211509, 2982818, 1566653, 2266481, 3357603, 2802076, 454094, 1143472, 5661746, 3042024, 4130245, 1380341, 7574381, 7574382, 3413565, 3755295, 3006464, 2866340, 2428982, 3452457, 2736710, 439982, 2713132, 6526973, 2425058, 5489217, 5231904, 3164976, 3783573, 2141733, 5281388, 2624327, 2455731, 4306045, 3318104, 4427048, 5896853, 1642281, 3095578, 3821686, 2247536, 524651, 3635836, 2429975, 2982051, 1854121, 313539, 2055462, 1357903, 3915506, 1213682, 3569080, 1676593, 2187555, 1998209, 2200136, 1739798, 756388, 2543093, 5265432, 2905532, 2479621, 7563913, 1973197, 1349271, 5559971, 7066091, 5520818, 2613717, 3676771, 1278553, 3604629, 1652907, 5804164, 1994754, 7121654, 1672102, 3579181, 3747997, 136372, 2918560, 4395334, 2363401, 2203543, 854252, 7002137, 2459502, 3587695, 2053429, 697099, 734286, 566586, 3707753, 1626985, 5784387, 1265041, 6798468, 3772198, 4244560, 2673219, 1695546, 2994363, 2730612, 3100754, 886099, 3110056, 3701884, 3350141, 3458781, 112125, 7294527, 3099936, 2317494, 2286884, 1620205, 1941646, 2451539, 5462759, 1752343, 1291046, 1767282, 1634135, 4940660, 395638, 1982490, 1476917, 1520050, 5046251, 2511270, 7111081, 3486777, 339688, 1817461, 2601124, 2242986, 1465794, 2925302, 1705533, 2922706, 4836774, 3660363, 745660, 3169468, 1520763, 3509457, 3569617, 355391, 6648567, 862026, 2023835, 2502370, 7193672, 1294506, 3343007, 2226606, 3683984, 1700134, 3292563, 7458781, 2060440, 3777791, 3219347, 5474, 771, 6020360, 6886256, 1585825, 4483044, 2054433, 4372220, 3823226, 2111371, 7014627, 1416017, 1569410, 2901923, 5597196, 3368095, 1959434, 5120511, 3800025, 1874309, 3903481, 6025066, 840023, 2682348, 3699720, 2896854, 3688479, 1502057, 1555263, 809981, 585601, 1375127, 1596918, 360669, 2840545, 5635682, 1846140, 2615488, 2849336, 3201680, 1231531, 3608639, 3146467, 5324271, 1976484, 9789163120589, 3680975, 5517500, 3089475, 3192865, 447198, 5133665, 3565552, 1662547, 2770880, 1311245, 6149285, 6569917, 6569917, 1002415, 562828, 3245190, 5484232, 2459645, 3568909, 7552342, 1203580, 4082130, 2222106, 609377, 6827736, 1605542, 5782928, 1733405, 7073872, 2003397, 3176790, 2704798, 940479, 17024143193031, 3495072, 5246769, 1886726, 3806514, 444669, 4346701, 3637879, 1651912, 2810301, 2483585, 6013518, 2967201, 1712139, 1434614, 2037858, 1486073, 796522, 1704970, 7562539, 6006077, 2904194, 2299901, 7379672, 3428969, 3695243, 1646580, 4856787, 3693603, 1695961, 573162, 1602006, 5225660, 7279147, 4130519, 2847085, 432838, 3367472, 1661557, 5578142, 3848961, 556991, 5470076, 1934684, 7423396, 3827073, 2216672, 5925390, 2422320, 6011897, 1684971, 5874848, 2904364, 1826106, 1299778, 3889066, 1651396, 2474610, 2954389, 2912090, 1557183, 1937029, 2507487, 5478924, 1715294, 2922372, 5463645, 1681132, 4780988, 913716, 3545388, 2932771, 5413653, 1845425, 7295773, 7094153, 2493682, 2990927, 2887564, 2677697, 408672, 5316507, 3703101, 7094153, 2493682, 2990927, 3632558, 2887564, 2677697, 408672, 5316507, 3703101, 1308009, 4770812, 5337079, 3755004, 1415101, 5745185, 982968, 3660773, 1308009, 4770812, 5337079, 3121001, 247806, 2271606, 3931104, 37258313205507, 5505571, 2668317, 2885795, 7051723, 3732788, 6507006, 1709842, 3412978, 119570, 3678477, 1576605, 7175099, 1305918, 2924041, 530050, 1671341, 6538336, 2590428, 3111412, 3444188, 2745018, 4100202, 2604892, 3778127, 2930905, 5229169, 7201798, 1935783, 1766070, 1934713, 3600756, 2213804, 2767444, 2422252, 2581588, 2008408, 3225517, 1583004, 806374, 4743209, 2206428, 1337908, 3639063, 5819000, 3696099, 2222914, 2000227, 7422917, 1883283, 1686313, 5521222, 3089084, 2442179, 1759304, 1747395, 6538525, 2553999, 6982855, 3685130, 6751808, 6099941, 4934225, 1516378, 5805504, 675584, 470956, 2510902, 1242503, 3749719, 2487185, 4129854, 3526684, 5851713, 1567499, 1723502, 485685, 5331758, 3063021, 312874, 5086885, 1334799, 2673350, 2094529, 816937, 1984183, 3660915, 5067745, 1836636, 2570299, 4974043, 2958926, 1617612, 16642067, 2324943, 1207415, 7546911, 2818215, 4244697, 3974286, 1694497, 7165647, 3671337, 2801423, 2510424, 2306838, 1388511, 624595, 1297286, 2436358, 6091196, 5512914, 487571, 534127, 2815852, 6458416, 3804033, 4933567, 5744422, 5722902, 5470939, 5452179, 5457991, 1640994, 2873717, 1524883, 1845772, 3674891, 1875155, 2464178, 1739033, 7421606, 3724024, 1791754, 4159572, 967165, 2701754, 5567026, 2472185, 5552462, 331054, 249043, 3889066, 1651396, 2474610, 2954389, 2912090, 1557183, 1937029, 2507487, 5478924, 1715294, 2922372, 5463645, 1681132, 4780988, 913716, 3545388, 2932771, 5413653, 3084699, 2785576, 379257, 1860558, 4848841, 3177975, 2873752, 2529630, 2521006, 400020, 7543202, 7534845, 3699951, 5905174, 1989575, 2497300, 451053, 2184388, 1392529, 434181, 4851652, 3721264, 2702019, 1597479, 336108, 1338400, 7463026, 1821872, 3678098, 1974435, 6474880, 3134012, 2177055, 1458500, 3305645, 856005, 1595486, 5458093, 1612392, 2460705, 6267145, 1580571, 1538872, 5824666, 3872292, 2604202, 1970794, 1794494, 6914627, 3913043, 522169, 1557181, 2889144, 1682581, 3570595, 2952667, 3531094, 972593, 2828325, 3718893, 625620, 1826923, 3777243, 3162194, 2071143, 3175833, 2822802, 6450734, 3075720, 1552345, 400875, 3695422, 3617908, 4999095, 868500, 3273027, 1830647, 3001168, 839357, 143026, 6509298, 6216983, 2866493, 1699319, 3913043, 6043877, 2777244, 3790887, 1597535, 6096882, 5366786, 1943658, 5967356, 4644327, 2573869, 4886905, 5497221, 6166360, 3757587, 1601279, 409682, 3656856, 1880412, 5548982, 440803, 3486898, 1469614, 1691653, 3517982, 1971388, 1591567, 2016029, 1915474, 1257990, 2836295, 3495373, 1595131, 2712714, 2038888, 2667948, 2112482, 5898371, 2152725, 1794645, 1766575, 3413233, 1394393, 2752920, 5826810, 1800219, 3236194, 780379, 5880743, 3888975, 3239977, 1672342, 1289969, 2634502, 5898371, 1994578, 6070379, 3974343, 3862812, 1959522, 2695007, 1975949, 5539548, 3817687, 1969538, 526457, 3648898, 2497733, 3919737, 3230126, 3112996, 1649655, 1414281, 1419212, 1209447, 4702472, 524427, 1578727, 4670311, 6569858, 1900395, 5593658, 748627, 3220216, 3036369, 1533891, 6104868, 5208730, 3220691, 2113571, 5692470, 1545496, 212279, 6832768, 3411897, 5039866, 4198229, 3220150, 5040626, 6945400, 1580625, 3783670, 5086760, 2954390, 4649501, 5605098, 4316966, 3814007, 1893227, 1570197, 3950540, 1662866, 3720504, 124749, 1739328, 1839751, 3267052, 3780004, 5534969, 5493628, 2189066, 4933333, 5000031, 2414326, 1660312, 877064, 3650461, 1740582, 7532482, 512763, 2995936, 6184316, 1691708, 3970089, 1463216, 17609241760924, 1760924, 2081737, 1557103, 411428, 2094576, 2099900, 2452915, 2454660, 2730564, 2996042, 3354127, 3643246, 4123328, 4123458, 4453267, 4503459, 4853506, 5561809, 6300149, 5746365, 7505479, 7000605, 7430234, 6278694, 6300073, 6304005, 6452374, 6541836, 6646113, 6760404, 6777359, 6833458, 6836893, 6884306, 6901124, 6902041, 6912172, 6967000, 5766391, 1437151, 1718606, 6199995, 7562358, 4214240, 3694198, 2852186, 1170709, 2872105, 1682394, 1202364, 2153009, 4366270, 1824797, 927167, 1295001, 919407, 6814675, 7108753, 5556574, 2818776, 2749154, 215024, 5307145, 4186227, 5721017, 1295391, 2514839, 5895587, 903753, 5642148, 3886007, 7576967, 7577628, 7577632, 7577633, 7577634, 7577635, 7577636, 904700, 7577637, 7577638, 7577639, 7577641, 7577645, 7577646, 7577648, 7577649, 7577650, 7577652, 7577654, 455254, 7577656, 3708532, 7577659, 7577660, 7577661, 7577662, 7577663, 2951831, 1632286, 3133284, 2888737, 2959380, 7316490, 2923902, 1879135, 3817089, 3743709, 5784317, 2196639, 3491472, 2932823, 3556939, 4721537, 5557000, 3707957, 4449825, 4335108, 1650317, 2627810, 4940330, 1197771, 2515859, 924199, 5342184, 3178756, 6461474, 3961089, 2434803, 4028439, 3820443, 2753029, 3902921, 1636847, 5146101, 1352371, 6149586, 2280915, 1566790, 2461560, 1811706, 1663869, 6593705, 1356823, 6712790, 1961069, 3510802, 3674914, 2185637, 1714183, 5772036, 4814426, 2011425, 5719032, 3703405, 5208010, 120696, 1677751, 1390504, 5058856, 3153335, 1997462, 3603807, 41413, 2439981, 2152273, 2837758, 2846092, 5850864, 1155577, 3507172, 287241, 3741419, 692902, 5316041, 5301410, 3682607, 1753932, 3091367, 788325, 1449159, 3366992, 916292, 6347261, 1434657, 6102366, 1255406, 2901402, 1076556, 2798150, 1729711, 5683203, 6837500, 1962691, 5198233, 599132, 567368, 3950087, 4074777, 6419244, 2916236, 4800287, 3757673, 293239, 6536106, 809165, 3415097, 854987, 1990729, 1476644, 3197548, 3732761, 3042947, 1669694, 2670433, 2863240, 3744754, 3042024, 1414583, 1405201, 3900432, 5568878, 1344308, 1827745, 3192935, 1904605, 480826, 1254895, 3641472, 4882220, 1634079, 3172505, 2256215, 562530, 1394768, 786326, 6158708, 3352107, 5391121, 5067010, 2468375, 3201256, 3724600, 6286341, 3549181, 7186722, 339068, 1979304, 5435620, 6028061, 2708731, 5178280, 1201818, 5699567, 3397714, 2247468, 2719292, 2179111, 2232637, 2368305, 1411884, 1623902, 3824123, 2917535, 5641251, 3737863, 1900927, 3026180, 6873059, 3324192, 4289072, 3233197, 2023564, 3691680, 2277265, 1757932, 2676236, 6428562, 5881430, 7576691, 7576693, 7576695, 2794461, 7576709, 1395712, 5530715, 7576703, 5444350, 2207345, 2842087, 3572040, 2162120, 2440783, 3499995, 5130206, 2370767, 4558726, 2591394, 4060762, 3628872, 3532285, 4675569, 2835676, 1528880, 1383825, 7272444, 1961891, 3079549, 2501462, 1986742, 7545766, 5400102, 7070700, 7100013, 3521381, 5504146, 1976484, 2609729, 957128, 997153, 5727892, 2380804, 1310682, 2807482, 3101639, 3044133, 608631, 2563142, 1156897, 3490631, 3662992, 1795637, 5452668, 4217430, 2251303, 3057877, 1646186, 5327503, 2493682, 6191961, 1785252, 6340741, 2488702, 3720570, 2810346, 4877063, 3854293, 575662, 1907014, 3047479, 1986742, 1716079, 2606512, 2606512, 1612436, 1982506, 220935, 1447073, 4069988, 5950280, 5613707, 2720250, 1764190, 7362662, 4327453, 1854383, 1667570, 2956296, 1578036, 354759, 2870581, 1462709, 3718084, 4797932, 3337441, 5410633, 2621030, 1837491, 2825611, 3207688, 6101891, 1965085, 1618019, 1977256, 3936998, 264703, 3180155, 1583081, 1857925, 3577533, 1889832, 1674133, 2395730, 1816288, 865228, 1863285, 562845, 4140811, 3522511, 4675782, 2049637, 885029, 4888891, 3555164, 1112380, 1707338, 3141100, 2815451, 1346358, 1485567, 1929667, 3411709, 545781, 3931308, 2376400, 2074773, 4350786, 5696509, 1212123, 3675423, 870306, 369681, 3911642, 732670, 65153223208273, 1947104, 2861616, 7146696, 5727966, 5544344, 2200571, 1654575, 2870129, 2438149, 1783803, 4726846, 566405, 5521249, 2964283, 1718606, 2931383, 6068515, 356909, 3387580, 3662963, 1390843, 3380309, 2273250, 1463033, 5696927, 3604144, 1995181, 2223354, 621792, 4298881, 2389991, 3018399, 1738402, 4216313, 1588182, 1509640, 3475709, 2732012, 3786946, 5444310, 2740735, 3678170, 1760310, 2760069, 2136431, 4414133, 2661522, 2298033, 3693685, 2041416, 2993613, 4901435, 2629615, 6954201, 1481171, 2857562, 478496, 3487949, 3046275, 1961336, 1919727, 5000014, 2129630, 7205609, 1728908, 446226, 1462790, 1840202, 2094275, 2889323, 2534715, 3685884, 2578386, 1396216, 2598706, 2455062, 1924872, 2824021, 3600181, 361852, 3709369, 346069, 1824086, 1697385, 3066506, 5749982, 4729716, 2257854, 5831412, 1673283, 3681202, 6196146, 3805496, 2819313.42036, 1825683, 5474771, 1567583, 1322970, 3837507, 3651818, 237116, 410761, 3069439, 3774885, 5840365, 3731427, 5725959, 1693284, 6380261, 377836, 7126782, 3514399, 1819063, 1553514, 5512348, 5227442, 5717626, 2876539, 5748062, 2074751, 2050140, 2550766, 2206884, 3206914, 1805487, 4097284, 3022119, 3632876, 3520474, 2643649, 7218822, 4146225, 3984929, 1667881, 418647, 1664955, 558545, 5031716, 2633481, 1384334, 2984889, 3590715, 313671, 5289725, 4252578, 4603458, 2267529, 1609914, 3824465, 4846540, 3084119, 7605580, 7605581, 7605582, 7605583, 7605585, 7605587, 7605588, 7605589, 7605590, 7605591, 7605593, 7605594, 7605595, 7605596, 7605597, 7605599, 7605600, 7605601, 4701213, 2928081, 4008546, 4807572, 1878987, 3545845, 4428798, 6024473, 1013418, 3779727, 6483218, 4739767, 2572437, 4611726, 3639522, 2952445, 1815959, 6217685, 6817815, 1631144, 2716790, 2479159, 7584196, 2892732, 3329644, 6766161, 7544571, 3569727, 5436814, 5152657, 2865540, 3747030, 763507, 502367, 1569338, 6847397, 1664206, 523063, 1713599, 1053435, 4200758, 1700392, 615060, 7566415, 297935, 4425570, 4354774, 6052422, 1621816, 896160, 3514470, 1460803, 5387368, 3103524, 4870394, 3593977, 5896865, 2747553, 447416, 1937367, 1649390, 3255515, 3030719, 1978537, 974974, 1160104, 2519609, 5438063, 1698518, 1948214, 5509365, 5638527, 2479857, 2085706, 4705554, 2118873, 5086697, 5269551, 1677684, 5788578, 3896968, 1980068, 2835893, 7593093, 5813786, 1931832, 3595417, 1647718, 2629657, 3841128, 3799998, 253185, 1485715, 3586929, 1891070, 6469397, 2593776, 4322359, 2223087, 3678963, 5404111, 928932, 1374761, 1264371, 3679928, 2046467, 6225379, 5171444, 5167694, 5157983, 5423355, 7571698, 2568734, 5265717, 1132547, 734801, 1165108, 6096329, 3728829, 5043345, 3658285, 3589964, 3573613, 3557368, 3387826, 1076550, 5069883, 1621292, 3966524, 1451655, 7596558, 7596559, 7596560, 7596562, 7596691, 7596695, 7596696, 2088004, 7596699, 4889205, 916783, 5206625, 1724476, 7467156, 1746469, 3979164, 3864964, 5882565, 3976691, 7598797, 7598799, 7598801, 7598802, 3455263, 7598804, 7598806, 7598807, 1414884, 7598808, 7598809, 7598810, 7598812, 2976790, 5612226, 7598813, 7598816, 2905077, 7598817, 5521190, 7598819, 7598821, 3029253, 3014556, 4350189, 3727215, 6852010, 2971901, 2857239, 556968, 1985203, 2543526, 776388, 2586833, 376396, 1916839, 1464805, 2634571, 2960638, 1399931, 2609575, 7589970, 7589971, 7589972, 7589973, 7589974, 7589976, 7589978, 7589979, 4848465, 3901079, 6205585, 7589982, 7589984, 7589985, 7589986, 7589987, 7589988, 1585804, 3492425, 3919924, 2340745, 3533379, 2969546, 5576533, 2510021, 1890436, 1980004, 5845176, 7590090, 5853829, 2571202, 3543036, 2877339, 1846397, 7140150, 5629504, 3704320, 2223149, 3185643, 6618462, 1529469, 2530165, 1891368, 5941925, 3118877, 1549214, 1730735, 802902, 2663439, 1663236, 3430946, 1382959, 2326215, 5571331, 2002651, 1553455, 2479609, 1352254, 1742587, 2431609, 1536702, 6203635, 650830, 2798632, 5460163, 4883143, 2149868, 5510498, 7579758, 3808106, 2893867, 2032283, 2631904, 1841509, 2414847, 3357194, 6036604, 2174969, 2703901, 3694470, 3839094, 5537746, 728208, 4160966, 1931520, 3835106, 2805936, 3298590, 4273592, 3673153, 1886819, 3120127, 6547114, 5745602, 6629374, 6480535, 5784632, 3305227, 2749185, 3100074, 3764961, 421611, 3166741, 5718531, 1641988, 3072114, 3718648, 3696531, 4995458, 1489352, 5332812, 3990225, 2624923, 2031223, 1868778, 3913081, 1149838, 2330762, 3742469, 846554, 5582180, 2156077, 6507889, 304475, 3745615, 3561381, 3132933, 3697800, 3149627, 5302706, 4106370, 2793053, 1860112, 2340145, 1289525, 7404080, 1661675, 1324386, 1179152, 1740676, 2109767, 708823, 5343022, 420771, 2667812, 2733535, 3699329, 1770511, 2656391, 1819753, 3853276, 2480456, 1460852, 1363261, 1425622, 385105, 3800097, 5061445, 1994320, 4309546, 3239127, 1286937, 2847679, 2319181, 1881982, 5329128, 1707180, 1055018, 1866817, 1700898, 4148579, 2310887, 1697320, 2874444, 2449214, 687298, 3285999, 3696921, 5119425, 3604500, 5540020, 4513718, 3921722, 5160514, 3197249, 1405239, 2620598, 1428463, 1480565, 992578, 1424798, 1780210, 2440885, 7366567, 2698054, 7594744, 7594746, 7594747, 7594748, 7594749, 7594750, 7594751, 7594752, 7594753, 7594754, 7594756, 7594758, 7594759, 7594763, 7594764, 7594765, 7594766, 2420501, 7594767, 7594769, 7594774, 4545101, 7594776, 7594777, 7594778, 7594779, 7594780, 7594781, 7594782, 7594783, 7594784, 7594785, 7594786, 7594788, 7594789, 7594790, 5001366, 3277158, 1510818, 1313887, 5092201, 2550414, 5771583, 5745150, 3768800, 1203713, 2031462, 605936, 5043256, 3684726, 4241064, 3652112, 3797080, 1502512, 4243511, 2398459, 1686942, 1772458, 2415314, 2581348, 2081656, 5941814, 591201, 2025979, 1733434, 2575661, 3484494, 1587693, 3654164, 5760249, 3773397, 3617288, 2853632, 1851969, 2960319, 2742266, 293407, 6133550, 4698671, 2740472, 3676395, 3679140, 5472351, 1803169, 3690316, 5538831, 116040, 5239176, 901784, 7595741, 7595742, 7595743, 4441552, 7595745, 876613, 7595746, 7595748, 7595749, 7595750, 7595751, 7595752, 7595753, 7595754, 7595755, 7595756, 3024291, 7595757, 3559791, 866665, 7595759, 7595760, 7595761, 7595763, 7595764, 7116999, 7595765, 7595766, 7595767, 7595768, 7595770, 7595771, 7595772, 7595773, 7595774, 1867649, 2371914, 3904844, 4119570 },
    wj         = { 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 }
}

local game_start = false
local game_pause = false
local hold_keys  = false
local map_is_P38 = false
local player_won = false

local max_points = 10 -- Maximum score

local lobby_map = 7728918

local is_tribe_house = (string_byte(string_sub(tfm.get.room.name, 2, 2)) == 3)

--[[ Functions Lib ]]--
local function string_first_upper(str)
    return string_gsub(str, '^%l', string_upper)
end

local function string_split(str, p)
    local t = { }
    for part in string_gmatch(str, '[^' .. p .. ']+') do
        t[#t + 1] = part
    end
    return t
end

local function table_shuffle(t)
    local size = #t
    for i = size, 1, -1 do
        local rand = math_random(size)
        t[i], t[rand] = t[rand], t[i]
    end
    return t
end

local function table_contains(t, element)
    if (not element) then
        return false
    end
    for k, v in next, t do
        if (k == element or v == element) then
            return true
        end
    end
    return false
end

local function update_ui_access(name)
    local n = players[name].ui_access[2]
    if (n == 0) then
        return
    end
    for i = 0, n do
        ui.removeTextArea(i, name)
    end

    players[name].ui_access = { '', 0 }
end

local function display_teams(name, update_mode)
    local st_team_list, nd_team_list = table_concat(teams[1].members, '\n'), table_concat(teams[2].members, '\n')
    local st_team_color, nd_team_color = teams[1].color, teams[2].color
    if (update_mode) then
        return ui.updateTextArea(13, string_format("<p align='center'><font color='#%s'>%s", st_team_color, st_team_list), name), ui.updateTextArea(14, string_format("<p align='center'><font color='#%s'>%s", nd_team_color, nd_team_list), name)
    end

    update_ui_access(name)

    local is_admin = admins[name]

    local st_team_players, nd_team_players = table_concat(teams[1].members, "\n"), table_concat(teams[2].members, "\n")
    local st_team_border_color, nd_team_border_color = teams[1].border_color, teams[2].border_color

    ui_addTextArea(0, string_format("<p align='center'><font size='28' color='#%s'>%s</font><font size='20'>x<font size='28' color='#%s'>%s", st_team_color, teams[1].score, nd_team_color, teams[2].score), name, 110, 52, 580, 295, 0x122529, 0xc9c9c9, 1, true)
    ui_addTextArea(1, "", name, 170, 100, 460, 237, 0x122529, 0xc9c9c9, 1, true)
    ui_addTextArea(2, "\n\n\n<textformat leading='-8'><font color='#c9c9c9'>__________\n______", name, 120, 52, 170, 285, 0x0d181a, '0x' .. st_team_border_color, 1, true)
    ui_addTextArea(3, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<textformat leading='-8'><p align='right'><font color='#c9c9c9'>______\n__________", name, 510, 52, 170, 285, 0x0d181a, '0x' .. nd_team_border_color, 1, true)
    ui_addTextArea(4, string_format("<textformat leading='-8'><p align='right'><font size='18' color='#%s'>Team Red</font>\n<font color='#c9c9c9'>__________\n______", st_team_color), name, 110, 52, 180, 40, 0x0d181a, '0x' .. st_team_border_color, 1, true)
    ui_addTextArea(5, string_format("<textformat leading='-8'><p align='left'><font size='18' color='#%s'>Team Blue</font>\n<font color='#c9c9c9'>__________\n______", nd_team_color), name, 510, 52, 180, 40, 0x0d181a, '0x' .. nd_team_border_color, 1, true)
    ui_addTextArea(6, string_format("<p align='center'><j>Max Score:</j> %s", max_points), name, 337, 110, 125, 20, 0x0d181a, 0xffffff, 1, true)

    local fill_button_tag = (is_admin and "<ch><a href='event:controls.fill.both'>" or '<n2>')
    local clear_button_tag = (is_admin and "<ce><a href='event:controls.clear.1.2'>" or '<n2>')
    local reset_button_tag = (is_admin and "<r><a href='event:game.reset'>" or '<n2>')
    local start_button_tag = (is_admin and "<vp><a href='event:game.start'>" or '<n2>')

    ui_addTextArea(7, string_format("<p align='center'>%sFill", fill_button_tag), name, 346, 138, 50, 20, 0x0d181a, 0xffffff, 1, true)
    ui_addTextArea(8, string_format("<p align='center'>%sClear", clear_button_tag), name, 404, 138, 50, 20, 0x0d181a, 0xffffff, 1, true)
    ui_addTextArea(9, string_format("<p align='center'><j>Mode:</j> %s", game_settings.mode), name, 337, 246, 125, 20, 0x0d181a, 0xffffff, 1, true)
    ui_addTextArea(10, string_format("<p align='center'>%sRESET", reset_button_tag), name, 337, 166, 125, 20, 0x0d181a, 0xffffff, 1, true)
    ui_addTextArea(11, string_format("<p align='center'>%sStart", start_button_tag), name, 375, 207, 50, 20, 0x0d181a, 0xffffff, 1, true)
    ui_addTextArea(12, string_format("<p align='center'><textformat leading='4'><j>Made by:</j> Renan\n<j>Burla maps:</j> Starkyller</textformat><textformat leading='-8'>\n\nv%s", version), name, 315, 270, 170, 57, 0x0d181a, 0xffffff, 1, true)

    -- Player list of both teams respectively
    ui_addTextArea(13, string_format("<p align='center'><font color='#%s'>%s", st_team_color, st_team_list), name, 120, 120, 170, 215, 0, 0, 0, true)
    ui_addTextArea(14, string_format("<p align='center'><font color='#%s'>%s", nd_team_color, nd_team_list), name, 510, 100, 170, 215, 0, 0, 0, true)

    players[name].ui_access = { 'info', 14 } -- This UI name, Last TextArea ID
end

local function display_settings(name, update_mode)
    local str = ''
    for k, v in next, game_settings do
        local _str = v
        if (type(v) == 'boolean') then
            _str = v and '<vp>on</vp>' or '<r>off</r>'
        end
        str = str .. '<g>' .. string_first_upper(k) .. '</g>: <a href="event:game.settings.' .. k .. '">' .. _str .. '</a>\n'
    end

    if (update_mode) then
        return ui.updateTextArea(3, "<p align='center'><font size='14'>" .. str, name)
    end

    update_ui_access(name)

    ui_addTextArea(0, '', name, 250, 85, 300, 230, 0x122529, 0, 1, true)
    ui_addTextArea(1, "<p align='center'><b><font size='12'>Settings</font></b></p>", name, 255, 90, 290, 20, 0x0d181a, 0, 1, true)
    ui_addTextArea(2, "<p align='right'><font size='10'><r><a href='event:game.settings'>X</a><r></font></p>", name, 255, 90, 290, 20, 0, 0, 0, true)
    ui_addTextArea(3, "<p align='center'><font size='14'>" .. str, name, 255, 129, 290, 180, 0x0d181a, 0, 1, true)

    players[name].ui_access = { 'settings', 3 } -- This UI name, Last TextArea ID
end

local function display_score(name)
    local x, y = players[name].score_position.x, players[name].score_position.y
    ui_addTextArea(16, string_format("<p align='center'><font size='16'><a href='event:controls.change_score_position.left_score'>«</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.change_score_position.right_score'>»</a></font></p>", teams[1].color, teams[1].score, teams[2].color, teams[2].score), name, x, y, nil, nil, 0, 0, 0, true)
end

local function get_score_difference()
    return math_abs(teams[1].score - teams[2].score)
end

local function change_score_position(name, side)
    local x, y = players[name].score_position.x, players[name].score_position.y

    if (side == 'left_score') then
        if (x > 5 and x <= 360) then
            players[name].score_position.x, players[name].score_position.y = 5, 20 
        elseif (x > 360) then
            players[name].score_position.x, players[name].score_position.y = 360, 20
        end
    elseif (side == 'right_score') then
        if (x < 360) then
            players[name].score_position.x, players[name].score_position.y = 360, 20
        elseif (x < 720 and x >= 360) then
            players[name].score_position.x, players[name].score_position.y = 720, 20
        end
    else
        players[name].score_position.click = true
    end

    display_score(name)
end

local function check_teams_tie()
    if (teams[1].score == teams[2].score and (get_score_difference() == 0)) then
        if (math_abs(teams[1].score - max_points) == 1) then
            max_points = (teams[1].score + 2)
            update_game_info()
        end
    end
end

function get_next_map(from_anti_cheat, anti_cheat_category)
    local _next

    -- Anti Cheat
    if (from_anti_cheat) then
        if (not anti_cheat_category) then
            _next = anti_cheat_maps['p38'][math_random(#anti_cheat_maps['p38'])]
            return _next
        end

        local list = anti_cheat_maps[anti_cheat_category]
        if (list) then
            local len = #list
            if (len < 1) then
                return
            end

            local index = math_random(len)

            if (anti_cheat_category == 'xml') then -- Not done yet
                _next = list[index].xml
            else
                _next = list[index]
            end
        end

        return _next
    end

    if (#np_list > 0) then
        _next = np_list[1];table_remove(np_list, 1)
        return _next
    end

    -- This is not supposed to be readable
    _next = (_a[1] == _b(game_settings.mode)) and '#17' or nil
    if (not _next) then
        local current_map = tfm.get.room.currentMap

        while true do
            for i = 2, #_a do
                if (_a[i] == _b(game_settings.mode)) then
                    local _rotation = rotation[game_settings.mode]
                    local code = _rotation[math_random(#_rotation)]

                    if (i == 5) then -- Mix mode
                        local t = { code, '#17' }
                        _next = t[math_random(#t)]
                    else
                        _next = code
                    end

                    break
                end
            end

            if (not _next or _next ~= current_map) then
                break
            end
        end
    end

    return _next
end

function set_next_map(map, type)
    if (map == 'anti') then
        map = get_next_map(true, type)
    end
    np_list[#np_list + 1] = map
end

local function skip_dead_players(exception)
    local exception = exception or 0

    local last = 0

    for _, v in next, tfm.get.room.playerList do
        if (not v.isDead) then
            if (last > exception) then
                return
            end
            last = (last + 1)
        end
    end

    if (last <= exception) then
        local map = get_next_map()
        tfm.exec.newGame(map)
    end
end

local function team_with_fewer_players()
    local t = { }
    for i = 1, #teams do
        t[#t + 1] = { #teams[i].members, i }
    end
    table_sort(t, function(a, b)
        return a[1] < b[1]
    end)
    return t[1][2]
end

local function add_player_to_team(player, team_id)
    if (game_settings.no_souris) then
        if (not check_player(player)) then
            return
        end
    end

    if (players[player].team_id ~= 0) then
        return
    end

    local team_id = team_id or team_with_fewer_players()
    teams[team_id].members[#teams[team_id].members + 1] = player

    players[player].in_game = true
    players[player].team_id = team_id

    if (not game_start) then
        display_teams(nil, true)
    end
end

local function kick_player(player)
    if (tfm.get.room.playerList[player] and players[player].in_game) then
        local team_id = players[player].team_id
        for i = 1, #teams[team_id].members do
            local _player = teams[team_id].members[i]
            if (_player == player) then
                table_remove(teams[team_id].members, i)

                players[_player].banned, players[_player].in_game = true, false
                players[_player].team_id    = 0

                tfm.exec.killPlayer(_player)
                break
            end
        end

        if (not game_start) then
            display_teams(nil, true)
        end
    end
end

local function reset_game()
    teams[1].members, teams[2].members = { }, { }
    teams[1].score, teams[2].score = 0, 0

    game_start = false

    for k in next, players do
        players[k].in_game = false
        players[k].team_id    = 0

        display_teams(k)
    end
end

local function update_game_info()
    ui.setMapName('<j>Team VS Team ' .. version .. '</j>   |   <ch>Max Score: ' .. max_points .. '</ch>')
    ui.removeTextArea(23)

    if (not game_start) then
        ui.updateTextArea(6, string_format("<p align='center'><j>Max Score:</j> %s", max_points))
        ui.updateTextArea(9, string_format("<p align='center'><j>Mode:</j> %s", game_settings.mode))
    end
end

--[[ Init ]]--
for k, v in next, {'AutoShaman', 'AutoNewGame', 'AutoTimeLeft', 'AutoScore', 'PhysicalConsumables'} do
    tfm.exec['disable' .. v]()
end
system.disableChatCommandDisplay()

tfm.exec.newGame(lobby_map)

--[[ Game API ]]--
function eventNewPlayer(name)
    if (not players[name]) then
        players[name]      = {
            ui_access      = { '', 0 },
            score_position = {
                click      = false,
                x          = 360,
                y          = 20
            },
            key_presses    = {
                [0] = { 0, "Left" },
                [1] = { 0, "Up" },
                [2] = { 0, "Right" }
            },

            banned         = false,
            frozen         = false,
            in_game        = false,
            in_room        = true,
            map_cat_show   = true,

            team_id        = 0
        }
    else
        players[name].in_room = true
    end
    check_player(name)
    
    if (not game_start) then
        display_teams(name)
    else
        if (game_pause) then
            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, true)
        end
    end

    if (game_settings.auto_join) then
        add_player_to_team(name)
    end

    for _, v in next, { 0, 1, 2, 8, 27, 46 } do
        system.bindKeyboard(name, v, true)
    end
    system.bindMouse(name)

    ui_addTextArea(18, "<p align='center'><b><i><font size='12'><a href='event:game.info'>i</a></font></i></b></p>", name, 5, -20, 16, 20, nil, nil, .6, true)

    if (admins[name]) then
        ui_addTextArea(19, "<p align='center'><b><font size='12'><a href='event:game.settings'>Settings</a></font></b></p>", name, 31, -20, 80, 20, nil, nil, .6, true)

        local str = "<font size='10'>"
        for i = 1, #admin_buttons do
            local name = admin_buttons[i][1]
            str = str .. string_format("<a href='event:controls.%s'>%s</a>", name, name) .. ' <j>|</j> '
        end
        ui_addTextArea(20, str, name, 121, -18, nil, 20, nil, nil, 0, true)
    end
end
table.foreach(tfm.get.room.playerList, eventNewPlayer)

function eventNewGame()
    hold_keys, player_won = false, false

    if (game_settings.no_souris) then
        kill_all_guests()
    end

    if (game_start) then
        local perm_code

        local xml = tfm.get.room.xmlMapInfo
        if (xml) then
            perm_code = xml.permCode
            map_is_P38 = (perm_code == 38)
        end

        for k, v in next, players do
            players[k].frozen = false

            update_ui_access(k)

            if (v.in_game) then
                for i = 1, 2 do
                    if (table_contains(teams[i].members, k)) then
                        tfm.exec.setNameColor(k, '0x' .. teams[i].color)
                    end
                end
            else
                tfm.exec.killPlayer(k)
            end

            if (admins[k]) then
                if (v.map_cat_show) then
                    ui.updateTextArea(22, '<j>P' .. perm_code .. '</j>', k)
                end
            end

            display_score(k)
        end

        tfm.exec.setGameTime(63)
    else
        for k in next, players do
            players[k].frozen = false

            display_teams(k)
            tfm.exec.setPlayerScore(k, 0)
        end

        ui.removeTextArea(16)
        ui.removeTextArea(17)

        tfm.exec.setGameTime(9e5)
        tfm.exec.disableAfkDeath(true)
    end

    update_game_info()
end

function eventLoop(elapsed, remaining)
    if (remaining < 1000) then
        if (game_start) then
            if (not game_pause) then
                tfm.exec.newGame(get_next_map())
            end
            return
        else
            tfm.exec.newGame(lobby_map)
        end
    end

    if (not game_settings.anti_macro) then
        return
    end
    if (elapsed < 3500) then
        return
    end

    hold_keys = true

    for k, v in next, players do
        if (not v.frozen) then
            for key, presses in next, v.key_presses do
                if (v.in_game) then
                    if (presses[1] > 20) then
                        players[k].frozen = true

                        tfm.exec.freezePlayer(k)

                        local str = string_format("<r>[Anti-Macro]</r> %s %s key presses detected (%s)", k, presses[1], presses[2])
                        if (is_tribe_house) then
                            ui_addTextArea(23, "<font size='10'>" .. str, nil, 2, 380, nil, nil, nil, nil, 0, true)
                        else
                            tfm.exec.chatMessage(str)
                        end
                    end
                end

                players[k].key_presses[key][1] = 0
            end
        end
    end
end

function eventTextAreaCallback(id, name, link)
    local is_admin = admins[name]
    
    local link = string_split(link, '.')
    if (link[1] == 'game') then
        if (link[2]) then
            if (link[2] == 'start') then
                if (game_start) then
                    return
                end

                local game_can_start = (#teams[1].members > 0 and #teams[2].members > 0)
                if (game_can_start) then
                    teams[1].score, teams[2].score = 0, 0

                    game_start = true

                    local map = get_next_map()
                    tfm.exec.newGame(map)
                    tfm.exec.disableAfkDeath(false)
                end

                ui.removeTextArea(16)
                return ui.removeTextArea(17)
            elseif (link[2] == 'info') then
                if (players[name].ui_access[1] == 'info') then
                    return update_ui_access(name)
                end

                return display_teams(name)
            elseif (link[2] == 'settings') then
                local setting = link[3]
                if (setting and table_contains(game_settings, setting)) then
                    if (type(game_settings[setting]) == 'boolean') then
                        game_settings[setting] = not game_settings[setting]
                        return display_settings(name, true)
                    end

                    local i = 2
                    for k in next, game_settings do
                        i = (i + 1)

                        if (setting == k) then
                            break
                        end
                    end

                    return ui.addPopup(i, 2, "<p align='center'><b>game_settings." .. setting, name, 296, 144, 200, true)
                end

                if (players[name].ui_access[1] == 'settings') then
                    return update_ui_access(name)
                end

                return display_settings(name)
            elseif (link[2] == 'reset') then
                return reset_game()
            end
        end
    elseif (link[1] == 'controls') then
        if (link[2]) then
            -- Change scoreboard position
            if (link[2] == 'change_score_position') then
                if (link[3]) then
                    return change_score_position(name, link[3])
                end
                return change_score_position(name)

            -- Teams buttons
            elseif (link[2] == 'clear') then
                if (link[3]) then
                    for i = 3, #link do
                        local team_id = tonumber(link[i])
                        local team = teams[team_id]
                        if (team) then
                            local n = #team.members
                            if (n > 0) then
                                for i = 1, n do
                                    players[team.members[i]].in_game = false
                                    players[team.members[i]].team_id    = 0
                                end

                                teams[team_id].members = { }

                                display_teams(nil, true)
                            end
                        end
                    end
                end

                return
            elseif (link[2] == 'fill') then
                if (link[3]) then
                    local team_id

                    local _players = { }
                    for k, v in next, players do
                        if (v.in_room and v.team_id == 0) then
                            _players[#_players + 1] = k
                        end
                    end
                    local len = #_players
                    if (len == 0) then
                        return
                    end
                    local quant = math_ceil(len / 2)

                    _players = table_shuffle(_players)

                    if (link[3] == 'both') then
                        team_id = 1
                        for i = 1, len do
                            if (i > quant) then
                                team_id = 2
                            end

                            add_player_to_team(_players[i], team_id)
                        end

                        return
                    end

                    team_id = tonumber(link[3])
                    local team = teams[team_id]
                    if (team) then
                        for i = 1, len do
                            add_player_to_team(_players[i], team_id)
                        end
                    end
                end

                return
            else
                -- Admin Buttons
                for i = 1, #admin_buttons do
                    local name, func = admin_buttons[i][1], admin_buttons[i][2]
                    if (link[2] == name) then
                        return func()
                    end
                end
            end
        end
    end
end

function eventPopupAnswer(id, name, answer)
    if (id > 2) then
        local i = 2
        for k, v in next, game_settings do
            -- Minified
            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;display_settings(name, true)update_game_info()end
                break
            end
        end
    end
end

function eventChatCommand(name, cmd)
    local cmd = string_split(cmd, ' ')
    cmd[1] = string_lower(cmd[1])

    local is_admin = admins[name]
    if (is_admin) then
        if (cmd[1] == 'team') then
            local team_id = (cmd[2] and tonumber(cmd[2]))
            if (not team_id) then
                return
            end

            for i = 3, #cmd do
                local player = string_first_upper(cmd[i])
                if (tfm.get.room.playerList[player]) then
                    add_player_to_team(player, team_id)
                end
            end

            return
        elseif (cmd[1] == 'teamscore' or cmd[1] == 'team_score') then
            local n = (cmd[2] and tonumber(cmd[2]))
            if (n) then
                local team = teams[n]
                if (team) then
                    local score = (cmd[3] and tonumber(cmd[3]))
                    if (score) then
                        if (game_start) then
                            teams[n].score = score

                            table.foreach(tfm.get.room.playerList, display_score)
                            return check_teams_tie()
                        end
                    end
                end
            end

            return
        elseif (cmd[1] == 'map' or cmd[1] == 'np') then
            if (cmd[2]) then
                return tfm.exec.newGame(cmd[2])
            end

            local map = get_next_map()
            return tfm.exec.newGame(map)
        elseif (cmd[1] == 'npp' or cmd[1] == 'nextmap' or cmd[1] == 'next_map') then
            if (cmd[2]) then
                if (cmd[3]) then
                    return set_next_map(cmd[2], cmd[3])
                end
                return set_next_map(cmd[2])
            end

            return
        elseif (cmd[1] == 'clearnpp' or cmd[1] == 'clearnextmaps' or cmd[1] == 'clear_next_maps') then
            for i = 1, #admin_buttons do
                local name, func = admin_buttons[i][1], admin_buttons[i][2]
                if (name == 'Clear Next Maps') then
                    func()
                end
            end

            return
        elseif (cmd[1] == 'anti') then
            local map = get_next_map(true)

            local cat = (cmd[2] and string_lower(cmd[2]))
            if (cat) then
                map = get_next_map(true, cat)
            end
            return tfm.exec.newGame(map)
        elseif (cmd[1] == 'ban' or cmd[1] == 'kick' or cmd[1] == 'remove') then
            local player = (cmd[2] and string_first_upper(cmd[2]))
            if (player) then
                kick_player(player)
            end

            return
        elseif (cmd[1] == 'max' or cmd[1] == 'score') then
            local score = (cmd[2] and tonumber(cmd[2]))
            if (score) then
                if (score < 2) then
                    score = 2
                elseif (score > 9999999) then
                    score = 9999999
                end
                max_points = score

                update_game_info()
            end

            return
        elseif (cmd[1] == 'reset') then
            return reset_game()
        elseif (cmd[1] == 'admin' and (name == 'Renangostoso#0000')) then
            local player = (cmd[2] and string_first_upper(cmd[2]))
            if (player) then
                if (tfm.get.room.playerList[player]) then
                    admins[player] = true
                end
            end

            return
        elseif (cmd[1] == 'unadmin' and (name == 'Renangostoso#0000')) then
            local player = (cmd[2] and string_first_upper(cmd[2]))
            if (player) then
                if (tfm.get.room.playerList[player]) then
                    admins[player] = false
                end
            end

            return
        elseif (cmd[1] == 'pause') then
            if (not game_start) then
                return
            end

            game_pause = (not game_pause)
            if (game_pause) then
                return ui_addTextArea(21, "<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)
            end
            
            ui.removeTextArea(21)

            return tfm.exec.setGameTime(4, false)
        elseif (cmd[1] == 'mapcat' or cmd[1] == 'map_cat') then
            local map_cat_show = players[name].map_cat_show
            players[name].map_cat_show = (not map_cat_show)
            if (map_cat_show) then
                ui_addTextArea(22, '<j>P?</j>', name, -26, 2, nil, nil, nil, nil, 0, true)
            else
                ui.removeTextArea(22, name)
            end

            return
        end
    end

    if (cmd[1] == 'version') then
        ui.addPopup(69, 0, 'Version: ' .. version, name, nil, nil, nil, true)
    end
end

function eventPlayerWon(name)
    if (game_start) then
        if (not player_won) then
            if (not game_pause) then
                if (not map_is_P38) then
                    tfm.exec.setGameTime(4, false)

                    teams[players[name].team_id].score = (teams[players[name].team_id].score + 1)
                    table.foreach(tfm.get.room.playerList, display_score)

                    check_teams_tie()

                    local color, winner = ''

                    local score_difference = get_score_difference()
                    if (teams[1].score >= max_points and (score_difference > 1)) then
                        color = '#' .. teams[1].color
                        winner = 'TEAM1'
                    elseif (teams[2].score >= max_points and (score_difference > 1)) then
                        color = '#' .. teams[2].color
                        winner = 'TEAM2'
                    end

                    if (winner) then
                        game_start = false

                        ui_addTextArea(17, 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)
                    else
                        player_won = true

                        tfm.exec.setPlayerScore(name, tfm.get.room.playerList[name].score + 1)

                        skip_dead_players()
                    end
                end
            end
        end
    end
end

function eventPlayerDied(name)
    if (game_start) then
        skip_dead_players()
    end
end

function eventPlayerLeft(name)
    if (not game_start) then
        local team_id = players[name].team_id
        if (team_id ~= 0) then
            for i = 1, #teams[team_id].members do
                if (teams[team_id].members[i] == name) then
                    table_remove(teams[team_id].members, i)
                    break
                end
            end
        end

        players[name] = nil

        return display_teams(nil, true)
    end

    players[name].in_room = false
end

function eventKeyboard(name, key, down, x, y)
    if (key == 27) then
        return update_ui_access(name)
    end

    if (players[name].key_presses[key]) then
        players[name].key_presses[key][1] = hold_keys and (players[name].key_presses[key][1] + 1) or 0
        return
    end

    if (game_settings.quick_death) then
        tfm.exec.killPlayer(name)
    end
end

function eventMouse(name, x, y)
    if (players[name].score_position.click) then
        players[name].score_position.x, players[name].score_position.y = (x - 38), (y - 10)
        players[name].score_position.click = false

        display_score(name)
    end
end