Advertisement
Gekkeiju

Bootcamp Relay

Oct 21st, 2015
427
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 22.89 KB | None | 0 0
  1. ---Last update : 16/11/2015
  2.  
  3. -----You may change the following 6 values----------
  4.  
  5. -- 1) The maximum number of players in a team
  6. TEAM_SIZE = 4
  7.  
  8. -- 2) The minimum number of players in a team
  9. MIN_SIZE = 2
  10.  
  11. -- 3) Game time (seconds)
  12. TIME = 180
  13.  
  14. -- 4) Length of the interval between rounds. (seconds)
  15. INTERVAL = 8
  16.  
  17. -- 5) Time limit for each section. Players need to reach the next check point in SECTION_TIME seconds.
  18. SECTION_TIME = 15
  19.  
  20. -- 6) Map list
  21. maps = {
  22.     {"@500000", {{1, 69}, {513, 362}, {691, 290}, {510, 210}, {794, 74}, {527, 63}}, 5},
  23.     {"@213755", {{631, 332}, {618, 197}, {415, 213}, {352, 146}, {535, 31}, {91, 168}}, 7},
  24.     {"@213752", {{736, 300}, {546, 230}, {725, 92}, {286, 102}}, 5},
  25.     {"@208653", {{759, 310}, {754, 177}, {204, 361}, {87, 201}}, 3},
  26.     {"@205506", {{187, 246}, {353, 150}, {480, 161}, {763, 316}, {759, 140}}, 3},
  27.     {"@205240", {{74, 353}, {167, 190}, {531, 340}, {582, 264}, {769, 112}, {701, 20}, {202, 290}, {33, 354}}, 7}, {"@204647", {{161, 148}, {520, 106}, {759, 37}, {571, 38}}, 5}, {"@204488", {{450, 348}, {748, 145}, {605, 61}, {447, 36}, {97, 343}}, 5}, {"@203664", {{325, 337}, {231, 220}, {540, 260}, {556, 142}, {276, 333}, {323, 206}}, 4}, {"@202574", {{302, 351}, {310, 253}, {488, 252}, {396, 156}, {422, 44}}, 5}, {"@201000", {{77, 348}, {36, 258}, {60, 73}, {770, 319}, {675, 221}, {552, 64}}, 4}, {"@195672", {{562, 327}, {743, 215}, {718, 54}, {371, 134}, {25, 359}}, 3}, {"@193662", {{737, 140}, {486, 132}, {481, 26}, {193, 245}, {170, 307}, {434, 221}, {529, 28}}, 5}, {"@192560", {{724, 328}, {719, 177}, {684, 36}, {501, 44}, {80, 330}, {87, 154}, {35, 195}, {425, 341}, {719, 361}, {719, 212}}, 7}, {"@191443", {{48, 156}, {187, 118}, {647, 369}, {757, 224}, {757, 31}}, 6}, {"@192158", {{492, 226}, {516, 26}, {253, 359}, {177, 217}}, 3}, {"@191203", {{770, 332}, {774, 162}, {590, 153}, {375, 154}, {60, 296}}, 5}, {"@191177", {{121, 333}, {116, 257}, {210, 132}, {406, 107}, {764, 171}}, 5}, {"@185428", {{476, 247}, {459, 181}, {401, 74}, {656, 30}}, 2}, {"@183139", {{558, 367}, {607, 285}, {716, 176}, {522, 111}, {150, 347}, {472, 40}}, 5}, {"@182769", {{760, 318}, {509, 147}, {155, 322}, {103, 211}}, 3}, {"@180801", {{189, 149}, {204, 28}, {414, 148}, {488, 336}, {359, 258}}, 4}, {"@176507", {{333, 184}, {509, 149}, {533, 47}, {176, 202}}, 4}, {"@175204", {{771, 315}, {794, 133}, {196, 342}, {101, 207}, {281, 101}}, 5}, {"@172951", {{772, 350}, {771, 156}, {291, 232}, {491, 137}, {619, 77}, {166, 365}}, 6}, {"@172520", {{750, 329}, {716, 207}, {462, 166}, {390, 59}}, 4}, {"@172512", {{241, 227}, {165, 116}, {151, 23}, {728, 25}, {651, 137}}, 6}, {"@172501", {{542, 337}, {744, 295}, {766, 165}, {716, 67}}, 5}, {"@171148", {{420, 260}, {721, 336}, {768, 333}, {721, 118}}, 3}, {"@169076", {{51, 208}, {373, 309}, {382, 203}, {765, 121}, {422, 304}}, 5}, {"@166430", {{498, 294}, {770, 308}, {629, 122}, {219, 246}, {24, 255}}, 3}, {"@163159", {{387, 315}, {436, 291}, {601, 199}, {244, 150}, {450, 114}, {726, 69}}, 3}, {"@160841", {{347, 361}, {237, 272}, {30, 359}, {-10, 262}, {65, 185}, {28, 137}, {214, 107}, {385, 92}}, 9}, {"@157960", {{70, 341}, {20, 340}, {20, 275}, {18, 130}, {23, 38}}, 1},
  28. {"@157203", {{504, 349}, {553, 349}, {660, 236}, {716, 54}, {142, 343}, {-15, 312}}, 5}, {"@157004", {{346, 245}, {393, 120}, {218, 29}, {717, 339}, {773, 316}, {743, 171}}, 4}, {"@151655", {{717, 297}, {738, 22}, {332, 250}, {287, 190}, {9, 199}, {16, 100}, {312, 115}}, 7}, {"@2329940", {{169, 217}, {212, 24}, {481, 293}, {288, 353}, {567, 352}, {317, 293}, {783, 142}, {610, 22}, {279, 208}}, 5}, {"@4445580", {{391, 227}, {762, 141}, {213, 86}, {154, 101}, {366, 206}}, 4}, {"@886744", {{232, 256}, {469, 340}, {499, 235}, {733, 80}, {422, 145}, {155, 161}}, 3}, {"@330933", {{615, 330}, {678, 329}, {700, 129}, {587, 88}, {541, 84}, {428, 211}, {380, 78}, {218, 129}}, 6}, {"@179807", {{647, 322}, {696, 158}, {771, 310}, {738, 181}, {582, 147}, {399, 239}}, 3}, {"@177652", {{753, 354}, {751, 282}, {270, 287}, {166, 82}, {344, 21}}, 5}, {"@206396", {{482, 352}, {498, 143}, {650, 147}, {697, 137}, {570, 27}, {215, 170}}, 6}, {"@179488", {{751, 329}, {747, 160}, {778, 62}, {502, 68}, {133, 268}}, 4}, {"@1427980", {{697, 212}, {546, 87}, {72, 151}, {340, 257}, {487, 163}, {314, 101}}, 3}, {"@815336", {{117, 346}, {204, 294}, {695, 161}, {466, 36}, {450, 324}, {173, 347}}, 4}, {"@161434", {{232, 211}, {312, 61}, {743, 367}, {789, 302}, {740, 259}, {764, 144}, {195, 371}, {8, 287}}, 6}, {"@216173", {{704, 247}, {767, 41}, {598, 128}, {355, 108}, {235, 244}, {6, 241}, {202, 287}, {318, 207}, {541, 268}, {730, 77}}, 6}, {"@172621", {{346, 367}, {393, 255}, {414, 155}, {687, 236}, {685, 98}, {523, 82}, {412, 72}}, 8}, {"@592189", {{615, 357}, {651, 88}, {390, 80}, {156, 54}, {110, 53}}, 3}, {"@168754", {{793, 33}, {129, 370}, {192, 314}, {252, 284}, {329, 271}}, 2}, {"@512887", {{391, 91}, {655, 81}, {457, 353}, {527, 175}, {739, 359}, {622, 83}, {294, 290}}, 5}, {"@306365", {{173, 196}, {215, 38}, {362, 351}, {409, 352}, {432, 252}, {462, 125}, {733, 101}, {596, 267}, {788, 327}, {704, 233}}, 7}, {"@2130169", {{14, 257}, {42, 101}, {434, 43}, {744, 168}, {520, 169}, {741, 368}}, 7}, {"@410045", {{450, 365}, {494, 300}, {251, 102}, {81, 140}, {59, 49}, {471, 240}, {721, 363}, {741, 249}}, 6}, {"@186066", {{490, 300}, {478, 190}, {530, 22}, {722, 100}, {140, 353}, {27, 305}, {41, 20}, {268, 191}, {357, 148}}, 4}, {"@2636519", {{759, 192}, {428, 173}, {720, 59}, {661, 103}, {204, 174}}, 4}, {"@263819", {{57, 276}, {66, 43}, {221, 182}, {374, 42}, {737, 39}, {631, 118}, {736, 340}, {480, 291}}, 8}, {"@528032", {{299, 105}, {331, 29}, {509, 81}, {576, 72}, {740, 39}, {160, 356}, {172, 277}, {34, 284}}, 8}, {"@511136", {{127, 253}, {163, 130}, {184, 42}, {455, 31}, {724, 113}}, 6}, {"@295932", {{566, 362}, {568, 254}, {580, 124}, {743, 58}, {697, 189}, {652, 188}, {725, 193}, {762, 111}, {602, 78}}, 6}, {"@271193", {{151, 303}, {185, 210}, {203, 92}, {308, 271}, {336, 70}, {440, 88}, {525, 64}, {744, 349}, {764, 245}, {726, 95}}, 8}, {"@3988424", {{299, 264}, {90, 80}, {644, 33}, {701, 83}, {518, 189}, {696, 263}, {556, 187}, {582, 32}}, 6}, {"@166032", {{687, 330}, {741, 316}, {736, 178}, {677, 40}, {357, 225}, {144, 254}, {1, 257}, {109, 36}, {639, 286}}, 9}, {"@460961", {{762, 377}, {705, 190}, {656, 155}, {651, 82}, {412, 163}, {286, 121}, {128, 78}, {420, 356}}, 8}, {"@315666", {{795, 178}, {106, 376}, {86, 296}, {85, 212}, {28, 39}, {350, 156}, {399, 157}, {445, 67}, {622, 94}}, 8}, {"@162482", {{634, 314}, {570, 193}, {722, 123}, {734, 52}, {547, 54}, {87, 310}}, 6}, {"@316012", {{163, 231}, {737, 370}, {644, 274}, {757, 179}, {646, 179}, {450, 220}, {346, 194}, {311, 71}}, 5}, {"@304861", {{64, 154}, {165, 64}, {365, 330}, {392, 328}, {438, 330}, {595, 263}, {589, 131}, {612, 45}}, 4}
  29.     }
  30. --[[
  31. ----The structure of the map list----
  32.  
  33. maps = {map data1, map data2, ... , map dataN}
  34.  
  35. -map data -> {map code, check points coordinates, cheese check point}
  36. -map code -> for example "@500000"
  37. -check points coordinates -> {{x1, y1}, {x2, y2}, ..., {xM, yM}}
  38. -cheese check point is the number the first check point where mice are spawned with cheese
  39. ]]--
  40.  
  41.  
  42. ------Dont change anything below-----------
  43. print("length of maps: " .. tostring(#maps))
  44.  
  45. if type(TEAM_SIZE) ~= type(1) then TEAM_SIZE = 4 end
  46. TEAM_SIZE = math.max(1, TEAM_SIZE)
  47. if type(TIME) ~= type(1) then TIME = 180 end
  48. TIME = math.max(60, TIME)
  49. if type(INTERVAL) ~= type(1) then INTERVAL = 8 end
  50. INTERVAL = math.max(3, INTERVAL)
  51. if type(SECTION_TIME) ~= type(1) then SECTION_TIME = 15 end
  52. SECTION_TIME = math.max(5, SECTION_TIME)
  53. if type(MIN_SIZE) ~= type(1) then MIN_SIZE = 2 end
  54. MIN_SIZE = math.min(TEAM_SIZE, math.max(1, MIN_SIZE))
  55.  
  56. players = {}
  57. map = {cp={},ccp=1}
  58. teams = {}
  59. --[[
  60. teams[i] = {
  61.     member = {},    :names
  62.     runner = 1, :index of the current runner
  63.     cp = 0,     :the last check point (0:start point)
  64.     cpTime = 0, :section time limit remaining (seconds)
  65.     winTime = -1    :the time elapsed when the team wins since the start of the round(milliseconds)
  66. }
  67. ]]--
  68.  
  69. countl = 0;
  70. interval = false;
  71. interval_rem = 0;
  72. IDs = {invitation = 0, interval = 1, message = 2, timer = 3, help = 4}  -- 11, 12, 13,... are for check points
  73.  
  74. text = {
  75.     begin = "Let's begin! team: %s",
  76.     begin_no_team = "No team was made",
  77.     few_players = "Not enough players to make a team",
  78.     alone = "Please wait for a new comer to make your team.",
  79.     get_alone = "Your fellows have gone away.",
  80.     join_team = "You joined a new team. Member : %s",
  81.     new_member = "%s is now your teammate.",
  82.     new_team = "A new team joined. Member : %s",
  83.     finish = "Winner : %s<br>%s",
  84.     invite = "Do you want to participate?"
  85. }
  86.  
  87. tfm.exec.disableAutoNewGame(true)
  88. tfm.exec.disableAutoShaman(true)
  89. tfm.exec.disableAfkDeath(true)
  90. tfm.exec.disableAutoTimeLeft(true)
  91.  
  92. function sendChatMessage(message, name, prefix, f)
  93.     if name~=nil then
  94.         if players[name] == nil then
  95.             return
  96.         end
  97.         message=(text[players[name].lang] or text)[message] or message
  98.         if prefix then
  99.             message=prefix..message
  100.         end
  101.         if f then
  102.             message=message:format(f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10])
  103.         end
  104.         --tfm.exec.chatMessage(message, name)
  105. --temporary
  106.         if #(players[name].chat.messages)==5 then
  107.             table.remove(players[name].chat.messages, 1)
  108.         end
  109.         table.insert(players[name].chat.messages, message)
  110.         ui.updateTextArea(IDs.message, table.concat(players[name].chat.messages,"<br>"), name)
  111. --temporary
  112.     else
  113.         for name,player in pairs(tfm.get.room.playerList) do
  114.             sendChatMessage(message, name, prefix, f)
  115.         end
  116.     end
  117. end
  118.  
  119. function eventLoop(current, remaining)
  120.     countl = countl + 1
  121.     if interval then
  122.         interval_rem = interval_rem - 1;
  123.         if interval_rem <= 0 then
  124.             interval = false
  125.             startRound()
  126.             showIntervalRemaining()
  127.         else
  128.             if interval_rem % 2 == 0 then
  129.                 showIntervalRemaining(interval_rem / 2)
  130.             end
  131.         end
  132.     else
  133.         if remaining < 500 then
  134.             if not interval then
  135.                 finishRound();
  136.                 interval = true
  137.                 interval_rem = INTERVAL * 2
  138.                 showIntervalRemaining(interval_rem / 2)
  139.                 ui.addPopup(IDs.invitation, 1, "<font size=\"20\">Do you want to participate?</font>", nil, 250, 300, 300, true)
  140.             end
  141.         else
  142.             for i, team in pairs(teams) do
  143.                 if team.winTime and team.winTime < 0 then
  144.                     if team.cpTime > SECTION_TIME then
  145.                         tfm.exec.killPlayer(team.member[team.runner])
  146.                     end
  147.                     team.cpTime = team.cpTime + 0.5
  148.                     if team.cpTime % 1 == 0 then
  149.                         for j, name in pairs(team.member) do
  150.                             ui.updateTextArea(IDs.timer, SECTION_TIME - team.cpTime, name)
  151.                         end
  152.                     end
  153.                 end
  154.             end
  155.         end
  156.     end
  157. end
  158.  
  159. function showIntervalRemaining(remaining)
  160.     if not remaining then
  161.         for name, player in pairs(players) do
  162.             if player.attendance == nil then
  163.                 ui.addTextArea(IDs.interval, "This round has already begun.", name, 250, 250, 300, 30, 0x324650, 0, 1, true)
  164.             else
  165.                 ui.removeTextArea(IDs.interval, name)
  166.             end
  167.         end
  168.     else
  169.         ui.addTextArea(IDs.interval, "The next round will start in ".. tostring(remaining) .. " seconds.", nil, 250, 250, 300, 30, 0x324650, 0, 1, true)
  170.     end
  171. end
  172.  
  173. function eventPopupAnswer(id, name, answer)
  174.     local p = players[name]
  175.     if id == IDs.invitation then
  176.         if answer=="yes" then
  177.             if p.attendance then
  178.                 return
  179.             end
  180.             p.attendance = true
  181.             if not interval then
  182.                 reconstructTeams(name)
  183.             end
  184.         else
  185.             p.attendance = false
  186.         end
  187.         if not interval then
  188.             ui.removeTextArea(IDs.interval, name)
  189.         end
  190.     end
  191. end
  192. function eventNewPlayer(name)
  193.     tfm.exec.bindKeyboard(name, 32, true, true)
  194.     tfm.exec.bindKeyboard(name, 9, true, true)
  195.     ui.addTextArea(IDs.timer, "10", name, 780, 20, 20, 15, 0,0,0, true)
  196.     ui.addTextArea(IDs.message, "", name, 10, 20, 500,300,0,0,0,true)   --temporary alternative for the chat area
  197.     players[name]={
  198.         name=name,
  199.         lang=roomLang,
  200.         attendance = nil, --nil, true, false
  201.         chat={type=0, messages={}} -- temporary alternative for the chat area
  202.     }
  203.     if not interval then showIntervalRemaining() end
  204.     ui.addPopup(IDs.invitation, 1, "<font size=\"20\">Do you want to participate?</font>", name, 250, 300, 300, true)
  205.     drawCheckPoint(name)
  206.     eventChatCommand(name, "help")
  207. end
  208.  
  209. function startRound()
  210.     local mp = queue or maps[math.random(#maps)][1]
  211.     queue = nil
  212.     tfm.exec.newGame(mp)
  213. end
  214.  
  215. function eventNewGame()
  216.     local sum
  217.     local member = {}
  218.     local nteam
  219.     local tem
  220.     local tem2
  221.     local rnd
  222.     local formation = {}
  223.    
  224.     map = {}
  225.     map.code = "@" .. tostring(tfm.get.room.xmlMapInfo.mapCode)
  226.    
  227.     for i,mapdata in pairs(maps) do
  228.         if map.code == mapdata[1] then
  229.             tem = mapdata
  230.             break;
  231.         end
  232.     end
  233.     if not tem then
  234.         tem = {map.code, {}}
  235.     end
  236.     if tem[2] and type(tem[2])==type({}) then
  237.         for i = 1, #tem[2] do
  238.             tem2 = tem[2][i]
  239.             if not (type(tem2)==type({}) and type(tem2[1])==type(1) and type(tem2[2])==type(1)) then
  240.                 print("Invalid check points")
  241.                 tem[2] = nil
  242.                 break
  243.             end
  244.         end
  245.     else
  246.         print("Invalid check points")
  247.         tem[2] = nil
  248.     end
  249.     map.cp = tem[2] or {}   --check points
  250.     if type(tem[3])~=type(1) then
  251.         tem[3] = #(map.cp) + 1
  252.     else
  253.         tem[3] = math.min(#(map.cp) + 1, math.max(1, tem[3]))
  254.     end
  255.     map.ccp = tem[3] or #(map.cp) + 1   --the first check point requiring cheese
  256.  
  257. --Make up teams
  258.     for name, player in pairs(players) do
  259.         if player.attendance then
  260.             table.insert(member, name)
  261.         end
  262.     end
  263.     sum = #member
  264.     if sum < MIN_SIZE * 2 then
  265.         if sum >= MIN_SIZE then
  266.             table.insert(formation, math.min(sum, TEAM_SIZE))
  267.         end
  268.     elseif sum <= TEAM_SIZE then
  269.         tem = math.floor(sum/2)
  270.         table.insert(formation, tem)
  271.         table.insert(formation, sum - tem)
  272.     else
  273.         nteam = math.ceil(sum / TEAM_SIZE)
  274.         tem = math.floor(sum / nteam)
  275.         if tem < MIN_SIZE then
  276.             for i = 1, nteam - 1 do
  277.                 table.insert(formation, TEAM_SIZE)
  278.             end
  279.         else
  280.             for i = 1, sum % nteam do
  281.                 table.insert(formation, tem + 1)
  282.             end
  283.             for i = (sum % nteam) + 1, nteam do
  284.                 table.insert(formation, tem)
  285.             end
  286.         end
  287.     end
  288.     teams = {}
  289.     for i, value in pairs(formation) do
  290.         teams[i] = {
  291.             member = {},
  292.             runner = 1,
  293.             cp = 0,
  294.             cpTime = 0,
  295.             winTime = -1
  296.         }
  297.         for h = 1, value do
  298.             rnd = math.random(#member)
  299.             teams[i].member[h] = member[rnd]
  300.             players[member[rnd]].team = teams[i]
  301.             table.remove(member, rnd)
  302.         end
  303.     end
  304.     for i, name in pairs(member) do
  305.         sendChatMessage("alone", name)
  306.     end
  307.  
  308.     local t = {}
  309.     for i, team in pairs(teams) do
  310.         table.insert(t, table.concat(team.member, "-"))
  311.     end
  312.     if #teams == 0 then
  313.         sendChatMessage("begin_no_team")
  314.     else
  315.         sendChatMessage("begin", nil, nil, {table.concat(t, " vs ")})
  316.     end
  317.  
  318.  
  319.     for i = 1, map.ccp - 1 do
  320.         ui.addTextArea(10 + i, "", nil, map.cp[i][1] - 12, map.cp[i][2] - 12, 25, 25, 0x91A918, 0xBBFFBB, 0.5)
  321.     end
  322.     for i = map.ccp, #(map.cp) do
  323.         ui.addTextArea(10 + i, "<font size=\"20\" color=\"#EFD76D\"><b>C</b></font>", nil, map.cp[i][1] - 12, map.cp[i][2] - 12, 25, 25, 0x91A918, 0xBBFFBB, 0.5)
  324.     end
  325.     for i, team in pairs(teams) do
  326.         for h = 2, #(team.member) do
  327.             tfm.exec.killPlayer(team.member[h])
  328.         end
  329.     end
  330.     tfm.exec.setGameTime(TIME)
  331. end
  332.  
  333. function drawCheckPoint(name)
  334.     if name then
  335.         local p = players[name]
  336.         if p.team then
  337.             for i=1, p.team.cp do
  338.                 ui.removeTextArea(10 + i, name)
  339.             end
  340.             for i = p.team.cp + 1, map.ccp - 1 do
  341.                 ui.addTextArea(10 + i, "", nil, map.cp[i][1] - 12, map.cp[i][2] - 12, 25, 25, 0x91A918, 0xFFFFFF, 0.5)
  342.             end
  343.             for i = math.max(map.ccp, p.team.cp + 1), #(map.cp) do
  344.                 ui.addTextArea(10 + i, "<font size=\"20\" color=\"#EFD76D\"><b>C</b></font>", nil, map.cp[i][1] - 12, map.cp[i][2] - 12, 25, 25, 0x91A918, 0xBBFFBB, 0.5)
  345.             end
  346.         else
  347.             for i = 1, map.ccp - 1 do
  348.                 ui.addTextArea(10 + i, "", nil, map.cp[i][1] - 12, map.cp[i][2] - 12, 25, 25, 0x91A918, 0xFFFFFF, 0.5)
  349.             end
  350.             for i = map.ccp, #(map.cp) do
  351.                 ui.addTextArea(10 + i, "<font size=\"20\" color=\"#EFD76D\"><b>C</b></font>", nil, map.cp[i][1] - 12, map.cp[i][2] - 12, 25, 25, 0x91A918, 0xBBFFBB, 0.5)
  352.             end
  353.         end
  354.     else
  355.         for n, player in pairs(players) do
  356.             drawCheckPoint(n)
  357.         end
  358.     end
  359. end
  360.  
  361. function eventKeyboard(name, code, down, x, y)
  362.     local p = players[name]
  363.     local p2 = tfm.get.room.playerList[name]
  364.     local lim
  365.     if code==32 then
  366.         local team = p.team
  367.         if team and team.member[team.runner] == name then
  368.             if p2.hasCheese then
  369.                 lim = #(map.cp)
  370.             else
  371.                 lim = map.ccp - 1
  372.             end
  373.             for i = team.cp + 1, lim do
  374.                 if (map.cp[i][1] - x)^2 + (map.cp[i][2] - y)^2 < 256 then
  375.                     team.cp = i
  376.                     team.cpTime = 0
  377.                     for j, name in pairs(team.member) do
  378.                         for h=1, i do
  379.                             ui.removeTextArea(10 + h, name)
  380.                         end
  381.                     end
  382.                     break
  383.                 end
  384.             end
  385.         end
  386.     elseif code==9 then --tribe house only
  387.         local message = table.concat(players[name].chat.messages, "<br>")
  388.         local type = players[name].chat.type
  389.         ui.removeTextArea(IDs.message, name);
  390.         if type % 3 == 0 then
  391.             ui.addTextArea(IDs.message, message, name, 10, 20, 400, 150, 0x583d23, 0xFFFFFF, 1, true)
  392.         elseif type % 3 == 2 then
  393.             ui.addTextArea(IDs.message, message, name, 10, 20, 400, 150, 0, 0, 0, true)
  394.         end
  395.         players[name].chat.type = type + 1
  396.     end
  397. end
  398.  
  399. function eventPlayerDied(name)
  400.     local pname
  401.     local team = nil
  402.     if players[name] then
  403.         team = players[name].team
  404.         if team and team.member[team.runner]==name then
  405.             local cp_xy = map.cp[team.cp]
  406.             team.runner = (team.runner % #(team.member)) + 1
  407.             pname = team.member[team.runner]
  408.             tfm.exec.respawnPlayer(pname)
  409.             if team.cp > 0 then
  410.                 if team.cp >= map.ccp then
  411.                     tfm.exec.giveCheese(pname)
  412.                 end
  413.                 tfm.exec.movePlayer(pname, cp_xy[1], cp_xy[2])
  414.             end
  415.             team.cpTime = 0
  416.         elseif not team then
  417.             tfm.exec.respawnPlayer(name)
  418.         end
  419.     end
  420. end
  421.  
  422. function eventPlayerWon(name, time)
  423.     local p = players[name]
  424.     local team = p.team
  425.     if team and team.member[team.runner]==name then
  426.         for i, pname in pairs(team.member) do
  427.             if pname ~= name then
  428.                 tfm.exec.respawnPlayer(pname)
  429.                 tfm.exec.giveCheese(pname)
  430.                 tfm.exec.playerVictory(pname)
  431.             end
  432.         end
  433.         team.winTime = time
  434.     end
  435.     for i, team in pairs(teams) do
  436.         if team.winTime==nil or team.winTime < 0 then
  437.             return
  438.         end
  439.     end
  440.     eventLoop(0,0)
  441. end
  442.  
  443. function finishRound()
  444.     local rank = ""
  445.     local winner
  446.     for i, team in pairs(teams) do
  447.         if team.winTime < 0 then
  448.             team.winTime = 10000
  449.         end
  450.     end
  451.     table.sort(teams, function (a,b) return (a.winTime < b.winTime) end)
  452.     if teams[1] and teams[1].winTime ~= 10000 then
  453.         winner = table.concat(teams[1].member, "-") .."(".. tostring(teams[1].winTime / 100).."s) "
  454.         for i=2, #teams do
  455.             if teams[i].winTime == 10000 then break end
  456.             rank = rank..tostring(i)..":"..table.concat(teams[i].member, "-").."("..tostring(teams[i].winTime / 100).."s) ";
  457.         end
  458.         sendChatMessage("finish", nil, nil, {winner, rank})
  459.     end
  460.  
  461.     for name, player in pairs(players) do
  462.         player.attendance = nil
  463.         player.team = nil
  464.         player.skip = nil
  465.         player.mirror = nil
  466.     end
  467.     for i=1 , #(map.cp) do
  468.         ui.removeTextArea(10 + i, nil)
  469.     end
  470. end
  471.  
  472. function eventPlayerLeft(name)
  473.     local p = players[name]
  474.     local team = p.team
  475.     if team and team.winTime < 0 then
  476.         for i, pname in pairs(team.member) do
  477.             if pname==name then
  478.                 table.remove(team.member,i)
  479.                 break
  480.             end
  481.         end
  482.         reconstructTeams(nil, team)
  483.     end
  484.     players[name] = nil
  485. end
  486.  
  487. function reconstructTeams(comer, leftTeam)
  488.     local recruit = {}
  489.     local free = {}
  490.     local tem
  491.     local sum
  492.     for name, player in pairs(players) do
  493.         if not player.team and player.attendance then
  494.             table.insert(free, name)
  495.         end
  496.     end
  497.     local i = 1
  498.     while i <= #(teams) do
  499.         if teams[i].winTime > 0 then
  500.             i = i + 1
  501.         else
  502.             tem = #(teams[i].member)
  503.             if tem < TEAM_SIZE then
  504.                 if tem + #free < MIN_SIZE then
  505.                     for j = 1, tem do
  506.                         table.insert(free, teams[i].member[j])
  507.                         players[teams[i].member[j]].team = nil
  508.                     end
  509.                     table.remove(teams, i)
  510.                 else
  511.                     for j = 1, math.min(TEAM_SIZE-tem, #free) do
  512.                         table.insert(teams[i].member, free[1])
  513.                         players[free[1]].team = teams[i]
  514.                         sendChatMessage("join_team", free[1], nil, {table.concat(teams[i].member, "-")})
  515.                         for h, name in pairs(teams[i].member) do
  516.                             if name~=free[1] then sendChatMessage("new_member", name, nil, {free[1]}) end
  517.                         end
  518.                         table.remove(free, 1)
  519.                     end
  520.                     i = i + 1
  521.                 end
  522.             else
  523.                 i = i + 1
  524.             end
  525.         end
  526.     end
  527.     if #free >= MIN_SIZE then
  528.         tem = {
  529.             member = {},
  530.             runner = 1,
  531.             cp = 0,
  532.             cpTime = 0,
  533.             winTime = -1
  534.         }
  535.         for i = 1, math.min(TEAM_SIZE, #free) do
  536.             tem.member[i] = free[i]
  537.             players[free[i]].team = tem
  538.         end
  539.         table.insert(teams, tem)
  540.         sendChatMessage("new_team", nil, nil, {table.concat(tem.member, "-")})
  541.     end
  542.  
  543.     for i, team in pairs(teams) do
  544.         if team.runner > #(team.member) then
  545.             team.runner = 1
  546.         end
  547.         for h, name in pairs(team.member) do
  548.             if name~=team.member[team.runner] then
  549.                 tfm.exec.killPlayer(name)
  550.             else
  551.                 tfm.exec.respawnPlayer(name)
  552.             end
  553.         end
  554.     end
  555.  
  556.     if comer~=nil and players[comer].team==nil then
  557.         sendChatMessage("alone", comer)
  558.     end
  559.  
  560.     if leftTeam then
  561.         for i, member in pairs(leftTeam.member) do
  562.             if players[member].team==nil then
  563.                 sendChatMessage("get_alone", member)
  564.             end
  565.         end
  566.     end
  567.     drawCheckPoint()
  568. end
  569.  
  570. function eventChatCommand(name, message)
  571.     local args={}
  572.     for arg in message:gmatch("[^%s]+") do
  573.         table.insert(args,arg:lower())
  574.     end
  575.     if args[1] == "join" then
  576.         eventPopupAnswer(IDs.invitation, name, "yes")
  577.     elseif args[1] == "map" and name=="Gekkeiju" then
  578.         queue = args[2]
  579.         eventLoop(0, 0)
  580.     elseif args[1] == "skip" then
  581.         if interval then return end
  582.         players[name].skip = true
  583.         local sum = 0
  584.         local yes = 0
  585.         for name, player in pairs(players) do
  586.             if player.attendance then
  587.                 if player.skip then yes = yes + 1 end
  588.                 sum = sum + 1
  589.             end
  590.         end
  591.         if yes/sum > 0.7 then
  592.             eventLoop(0, 0)
  593.         end
  594.     elseif args[1] == "help" then
  595.         ui.addPopup(IDs.help, 0, '<p align ="center"><font size="20">Welcome to Bootcamp Relay!</font></p><font size="15" color="#55FF55">~Rules~</font><font size="12"><li>Work for your teammates</li><li>Rectangles are check points. Press Space key on a check point and the next player will respawn there</li><li>Get to a check point in 15 seconds after leaving the last one</li><li>You need cheese to check at the check points with a yellow"C". Your teammates will respawn there with cheese.</li><li>Type !skip to skip the map (70% votes are required)</li><li>Type !mirror if the check points arrangement needs reversing. (50% votes are required)</li></font>', name, 181, 146, 488, true)
  596.     elseif args[1] == "mirror" then
  597.         if interval then
  598.             return
  599.         end
  600.         players[name].mirror = true
  601.         local sum = 0
  602.         local yes = 0
  603.         for name, player in pairs(players) do
  604.             if player.mirror then
  605.                  yes = yes + 1
  606.             end
  607.             sum = sum + 1
  608.         end
  609.         if yes/sum > 0.5 then
  610.             reverseCheckPoint()
  611.         end
  612.  
  613.     end
  614. end
  615.  
  616. function reverseCheckPoint()
  617.     if map.mirror then return end
  618.     map.mirror = true
  619.     for i, p in pairs(map.cp) do
  620.         p[1] = 800 - p[1]
  621.     end
  622.     drawCheckPoint()
  623. end
  624.  
  625. for name, player in pairs(tfm.get.room.playerList) do
  626.     eventNewPlayer(name)
  627. end
  628. eventLoop(0,0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement