Advertisement
Tectoon

[TFM] #Football

Sep 25th, 2015
845
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.08 KB | None | 0 0
  1. -- Depois iremos mudar o "print" para "tfm.exec.chatMessage" Quando liberarem!
  2.  
  3. tfm.exec.disableAutoShaman(true)
  4.  
  5. function table.copy(t)
  6.   local t2 = {}
  7.   for k,v in pairs(t) do
  8.     t2[k] = v
  9.   end
  10.   return t2
  11. end
  12.  
  13. function printInfo(name, value, tabs)
  14.     tabs = tabs or "";
  15.     local t = type(value);
  16.     print(tabs .. t .. " " .. tostring(name) .. " = " .. tostring(value));
  17.     if t == "table" then
  18.         for n, v in pairs(value) do
  19.             if v == value then
  20.                 print(tabs .. "\tself " .. n);
  21.             else
  22.                 printInfo(n, v, tabs .. "\t");
  23.             end
  24.         end
  25.     end
  26. end
  27.  
  28. MAP = "@3791114";
  29. MAX_SCORE = 20;
  30. WELCOME_MESSAGE = "<J>Welcome! This is a football game for testing modules. Write <N>!help<J> for more information. Please report any issues to Makinit.";
  31. keys = {space = 32, left = 37, right = 39, a = 65, d = 68, q = 81};
  32. team1 = {id = 1, score = 1, colour = "0x0000FF", colour2 = "0x8888FF", tag = "<BV>", name = "the blue team", players = {}};
  33. team2 = {id = 2, score = 1, colour = "0xFF0000", colour2 = "0xFF8888", tag = "<R>", name = "the red team", players = {}};
  34. ball = {player = nil, object = 0, t = 0, x = 0, y = 0, vx = 0, vy = 0, ax = 0, ay = 0, takeTime = 0, shootTime = 0};
  35.  
  36. players = {};
  37. spectators = {};
  38.  
  39. function main()
  40.     command.addHandler("debug", doDebug);
  41.     command.addHandler("cheese", doCheese);
  42.     command.addHandler("help", doHelp);
  43.     command.addHandler("t", doTeamChat);
  44.    
  45.     debug.disableEventLog(debugOff);
  46.     tfm.exec.disableAutoScore(true);
  47.     tfm.exec.disableAutoNewGame(true);
  48.     tfm.exec.setGameTime(0, true);
  49.     print(WELCOME_MESSAGE);
  50.     tfm.exec.newGame(MAP);
  51. end
  52.  
  53. function eventNewGame()
  54.     team1.players = {};
  55.     team2.players = {};
  56.     team1.score = 1;
  57.     team2.score = 1;
  58.     gameOver = false;
  59.     for name, player in pairs(tfm.get.room.playerList) do
  60.         if player.isShaman then
  61.             tfm.exec.killPlayer(name);
  62.             tfm.exec.respawnPlayer(name);
  63.             shaman = name;
  64.         end
  65.         initPlayer(name);
  66.     end
  67.    
  68.     for name, player in pairs(tfm.get.room.playerList) do
  69.         if player.isShaman then
  70.             tfm.exec.killPlayer(name);
  71.             tfm.exec.respawnPlayer(name);
  72.             shaman = name;
  73.         end
  74.         returnPlayer(name);
  75.     end
  76.     ball.object = nil;
  77.     if #team1.players > 0 and math.random() > 0.5 then
  78.         tasks[os.time() + 5000] = function() giveBall(team1.players[math.random(#team1.players)]) end;
  79.     elseif #team2.players > 0 then
  80.         tasks[os.time() + 5000] = function() giveBall(team2.players[math.random(#team2.players)]) end;
  81.     end
  82. end
  83.  
  84. function eventPlayerGetCheese(player)
  85.     ball.player = player;
  86. end
  87.  
  88. tasks = {};
  89. function eventLoop()
  90.     --local done = {}
  91.     local now = os.time();
  92.    
  93.     -- task handler
  94.     for when, task in pairs(table.copy(tasks)) do
  95.         if when <= now then
  96.             tasks[when] = nil;
  97.             task();
  98.         end
  99.     end
  100.    
  101.     if not gameOver then
  102.         tfm.exec.setGameTime(60 * team1.score + team2.score + 1, true);
  103.         local object = ball.object;
  104.         local player = ball.player;
  105.         if object then
  106.             local x, y = getBallLocation();
  107.             tfm.exec.addShamanObject(tfm.enum.shamanObject.arrow, x, y - 25, 0, 0, 0, true);
  108.         elseif player then
  109.             local ballPlayer = players[player];
  110.             if false or ballPlayer then
  111.                 tfm.exec.addShamanObject(tfm.enum.shamanObject.arrow, ballPlayer.x, ballPlayer.y - 50, 0, 0, 0, true);
  112.             end
  113.             local tfmPlayer = tfm.get.room.playerList[player];
  114.             if tfmPlayer then
  115.                 tfm.exec.addShamanObject(tfm.enum.shamanObject.arrow, tfmPlayer.x, tfmPlayer.y - 50, 0, 0, 0, true);
  116.             end
  117.         end
  118.     else
  119.         local left = 50;
  120.         local right = 1550;
  121.         if team1.score > team2.score then
  122.             right = 800;
  123.         elseif team2.score > team1.score then
  124.             left = 800;
  125.         end
  126.         tfm.exec.addShamanObject(tfm.enum.shamanObject.balloon, math.random(left, right), 350, 0, 0, 0, false);
  127.     end
  128. end
  129.  
  130. function eventKeyboard(player, key, down, x, y)
  131.     if down and players[player] then
  132.         if key == keys.left or key == keys.a or key == keys.q then
  133.             players[player].direction = -1;
  134.         elseif key == keys.right or key == keys.d then
  135.             players[player].direction = 1;
  136.         end
  137.     end
  138.     if key == keys.space then
  139.         local now = os.time();
  140.         local x2, y2 = getBallLocation(now);
  141.         if player == ball.player then
  142.             if down then
  143.                 ball.space = now;
  144.             elseif ball.space then
  145.                 local force = (now - ball.space) / 100;
  146.                 if force > 8 then
  147.                     force = 8;
  148.                 end
  149.                 ball.space = nil;
  150.                 shootBall(x, y, 5, -6 - force);
  151.                 players[player].shootTime = now;
  152.                 ball.takeTime = 0;
  153.                 ball.shooter = player;
  154.             end
  155.         elseif ball.object then
  156.             local shootTime = players[player].shootTime or 0;
  157.             if now > shootTime + 1000 and isClose(x, y - 25, getBallLocation(now)) then
  158.                 removeBall();
  159.                 ball.takeTime = now;
  160.                 giveBall(player);
  161.                 ball.space = nil;
  162.                 ball.passer = ball.shooter;
  163.             end
  164.         elseif ball.player and players[ball.player] and players[ball.player].team.id ~= players[player].team.id and now > ball.takeTime + 1000 then
  165.             local ballPlayer = tfm.get.room.playerList[ball.player];
  166.             local tfmPlayer = tfm.get.room.playerList[player];
  167.             if isClose(x, y, ballPlayer.x, ballPlayer.y) or isClose(tfmPlayer.x, tfmPlayer.y, ballPlayer.x, ballPlayer.y) then
  168.                 takeBall(ballPlayer.x, ballPlayer.y);
  169.                 ball.takeTime = now;
  170.                 giveBall(player);
  171.                 ball.space = nil;
  172.                 ball.passer = nil;
  173.             end
  174.         end
  175.     end
  176.     --players[player].x = x;
  177.     --players[player].y = y;
  178. end
  179.  
  180. function isClose(x, y, x2, y2)
  181.     local d = 25;
  182.     return x < x2+d and x > x2-d and y < y2+d and y > y2-d;
  183. end
  184.  
  185. function removeBall()
  186.     tfm.exec.removeObject(ball.object);
  187.     ball.object = nil;
  188.     if ball.floorTimer then
  189.         system.removeTimer(ball.floorTimer);
  190.     end
  191.     ball.floorTimer = nil;
  192.     if ball.goalTimer then
  193.         tasks[ball.goalTimer] = nil;
  194.     end
  195.     ball.goalTimer = nil;
  196. end
  197.  
  198. function shootBall(x, y, vx, vy)
  199.     ball.x = x;
  200.     ball.y = y;
  201.     ball.vx = players[ball.player].direction * (vx or 5);
  202.     ball.vy = (vy or -6);
  203.     ball.ax = 0;
  204.     ball.ay = 5;
  205.     if ball.object then
  206.         tfm.exec.removeObject(ball.object);
  207.     end
  208.     ball.t = os.time();
  209.     --ball.object = tfm.exec.addShamanObject(tfm.enum.shamanObject.littleBox, x, y, 0, ball.vx, ball.vy, true);
  210.     ball.object = tfm.exec.addShamanObject(17, x, y, 0, 0, 0, true);
  211.     tfm.exec.moveObject(ball.object, x, y, false, ball.vx*10, ball.vy*10, false);
  212.     if not gameOver then
  213.         local yf = 330; --floor
  214.         setFloorTimer(yf);
  215.         if ball.vx < 0 then
  216.             setGoalTimer(0);
  217.         elseif ball.vx > 0 then
  218.             setGoalTimer(1600);
  219.         end
  220.     end
  221.     takeBall(x, y);
  222. end
  223.  
  224. function setFloorTimer(yf)
  225.     if ball.floorTimer then
  226.         system.removeTimer(ball.floorTimer);
  227.     end
  228.     if yf then
  229.         local tf;
  230.         if (ball.ay == 0) then
  231.             tf = (yf - ball.y) / (30*ball.vy);
  232.         else
  233.             tf = (-(30*ball.vy) + math.sqrt((30*ball.vy)*(30*ball.vy) - 4*(30*ball.ay)*(ball.y-yf))) / (2*(30*ball.ay));
  234.             if tf < 0 then
  235.                 --print"-");
  236.                 tf = (-(30*ball.vy) - math.sqrt((30*ball.vy)*(30*ball.vy) - 4*(30*ball.ay)*(ball.y-yf)))/(2*(30*ball.ay));
  237.             end
  238.         end
  239.         if tf < 1 then
  240.             tf = 1;
  241.         end
  242.         ball.floorTimer = system.newTimer(hitFloor, tf * 1000, false, tf);
  243.     end
  244. end
  245.  
  246. function hitFloor(timer, tf)
  247.     local now = os.time();
  248.     local x, y = getBallLocation(now);
  249.     ball.x = x;
  250.     ball.y = 330;
  251.     ball.vy = 0;
  252.     ball.ax = 0;
  253.     ball.ay = 0;
  254.     ball.t = now;
  255.     tfm.exec.moveObject(ball.object, ball.x, ball.y, false, 0, ball.vy, false);
  256.     --print"hit!");
  257.     --printtf .. "," .. x .. "," .. y);
  258. end
  259.  
  260. function setGoalTimer(xg)
  261.     if ball.goalTimer then
  262.         tasks[ball.goalTimer] = nil;
  263.     end
  264.     if xg then
  265.         local tg;
  266.         if (ball.ax == 0) then
  267.             tg = (xg - ball.x) / (30*ball.vx);
  268.         else
  269.             tg = (-(30*ball.vx) + math.sqrt((30*ball.vx)*(30*ball.vx) - 4*(30*ball.ax)*(ball.x-xg))) / (2*(30*ball.ax));
  270.             if tg < 0 then
  271.                 --print"-");
  272.                 tg = (-30*ball.vx - math.sqrt(900*ball.vx*ball.vx - 480*ball.ax*(ball.x-xg))) / (60*ball.ax);
  273.             end
  274.         end
  275.         local _, hit = getBallLocation(os.time() + tg * 1000);
  276.         local height = 275;
  277.         ball.scored = hit > height;
  278.        
  279.         if tg < 1 then
  280.             tg = 1;
  281.         end
  282.         ball.goalTimer = os.time() + tg * 1000;
  283.         tasks[ball.goalTimer] = hitGoal;
  284.     end
  285. end
  286.  
  287. function hitGoal()
  288.     local winner;
  289.     local loser;
  290.     if ball.vx > 0 then
  291.         winner = team1;
  292.         loser = team2;
  293.     elseif ball.vx < 0 then
  294.         winner = team2;
  295.         loser = team1;
  296.     end
  297.     if ball.scored then
  298.         winner.score = winner.score + 1;
  299.         if players[ball.shooter].team == winner then
  300.             tfm.exec.setPlayerScore(ball.shooter, 10, true);
  301.             local pass = "";
  302.             if ball.passer and players[ball.passer] and players[ball.passer].team == winner then
  303.                 tfm.exec.setPlayerScore(ball.passer, 5, true);
  304.                 pass = " after a pass from " .. winner.tag .. ball.passer .. "<BL>";
  305.             end
  306.             print(winner.tag .. ball.shooter .. "<BL> scored" .. pass .. "!");
  307.         else
  308.             tfm.exec.setPlayerScore(ball.shooter, -10, true);
  309.             print(loser.tag .. ball.shooter .. "<BL> scored an own goal!");
  310.         end
  311.         print(team1.tag .. team1.name .. " <V>" .. team1.score .. "<BL> - <V>" .. team2.score .. team2.tag .. " " .. team2.name);
  312.         if winner.score == MAX_SCORE then
  313.             print("<J>Well done, players of " .. winner.tag .. winner.name .. "<J>, you win!");
  314.             gameOver = true;
  315.             tfm.exec.setGameTime(20, true);
  316.             system.newTimer(function() tfm.exec.newGame(MAP) end, 20000, false);
  317.         end
  318.     else
  319.         print(players[ball.shooter].team.tag .. ball.shooter .. "<BL> missed!");
  320.     end
  321.     removeBall();
  322.     ball.shooter = nil;
  323.     ball.passer = nil;
  324.    
  325.     for name, player in pairs(players) do
  326.         returnPlayer(name);
  327.     end
  328.     if #loser.players > 0 then
  329.         giveBall(loser.players[math.random(#loser.players)]);
  330.     else
  331.         giveBall(winner.players[math.random(#winner.players)]);
  332.     end
  333. end
  334.  
  335. function takeBall(x, y)
  336.     tfm.exec.killPlayer(ball.player);
  337.     tfm.exec.respawnPlayer(ball.player);
  338.     if x and y then
  339.         tfm.exec.movePlayer(ball.player, x, y);
  340.     end
  341.     ball.player = nil;
  342. end
  343.    
  344. function giveBall(player)
  345.     tfm.exec.giveCheese(player);
  346.     ball.player = player;
  347. end
  348.  
  349. function getBallLocation(t)
  350.     t = t or os.time();
  351.     local dt = os.difftime(t, ball.t) / 1000;
  352.     local x = ball.x + dt*(ball.vx + ball.ax*dt) * 30;
  353.     local y = ball.y + dt*(ball.vy + ball.ay*dt) * 30;
  354.     return x, y;
  355. end
  356.  
  357. function eventNewPlayer(player)
  358.     print(WELCOME_MESSAGE, player);
  359.     initPlayer(player);
  360.     tfm.exec.respawnPlayer(player);
  361.     returnPlayer(player);
  362. end
  363.  
  364. function initPlayer(player)
  365.     players[player] = {direction = 1, x = 0, y = 0};
  366.     for key, code in pairs(keys) do
  367.         tfm.exec.bindKeyboard(player, code, true, true);
  368.         tfm.exec.bindKeyboard(player, code, false, true);
  369.     end
  370.     local team;
  371.     if #team1.players < #team2.players then
  372.         team = team1;
  373.     elseif #team1.players > #team2.players then
  374.         team = team2;
  375.     elseif math.random() < 0.5 then
  376.         team = team1;
  377.     else
  378.         team = team2;
  379.     end
  380.     table.insert(team.players, player);
  381.     players[player].team = team;
  382.    
  383.     print("<N>Press the <VP>space bar<N> to take or shoot the ball.", player);
  384.     print("<J>You joined " .. team.tag .. team.name .. "<J>!", player);
  385. end
  386.  
  387. function returnPlayer(player)
  388.     if not players[player] then
  389.         initPlayer(player)
  390.     end
  391.     local team = players[player].team;
  392.     tfm.exec.setNameColor(player, team.colour);
  393.     if team == team1 then
  394.         tfm.exec.movePlayer(player, math.random(50, 800), 350);
  395.     elseif team == team2 then
  396.         tfm.exec.movePlayer(player, math.random(800, 1550), 350);
  397.     end
  398. end
  399.  
  400. function eventPlayerLeft(player)
  401.     local team = players[player].team;
  402.     local index;
  403.     for i, name in ipairs(team.players) do
  404.         if name == player then
  405.             index = i;
  406.         end
  407.     end
  408.     table.remove(team.players, index);
  409.     --players[player] = nil;
  410.     if ball.player == player then
  411.         if #team.players == 0 and team == team1 then
  412.             team = team2;
  413.         elseif #team.players == 0 and team == team2 then
  414.             team = team1
  415.         end
  416.         giveBall(team.players[math.random(#team.players)]);
  417.     end
  418.    
  419.     for key, code in pairs(keys) do
  420.         tfm.exec.bindKeyboard(player, code, true, false);
  421.         tfm.exec.bindKeyboard(player, code, false, false);
  422.     end
  423. end
  424.  
  425. debugOff = true;
  426. function doDebug(player)
  427.     if player == "Makinit" then
  428.         debugOff = not debugOff;
  429.         debug.disableEventLog(debugOff);
  430.     end
  431. end
  432.  
  433. function doCheese(player)
  434.     if player == "Makinit" then
  435.         tfm.exec.giveCheese("Makinit");
  436.     end
  437. end
  438.  
  439. function doHelp(player)
  440.     local message = [[<J>You are a team player and you have to cooperate to score!
  441. Press the <VP>space bar<J> to take the ball, shoot the ball or tackle an opponent. When you hold it longer you will shoot harder.
  442. The first team to reach ]] .. MAX_SCORE .. [[ points will win!
  443. Commands:
  444. <N>!help<J> - displays this message
  445. <N>!t message<J> - team chat]];
  446.     print(message, player);
  447. end
  448.  
  449. function doTeamChat(player, ...)
  450.     local team = players[player].team;
  451.     local text = string.gsub(string.gsub(table.concat(arg, " "), "<", "&lt;"), ">", "&gt;");
  452.     if team and text and text ~= "" then
  453.         local message = team.tag .. "[" .. player .. "]<N> " .. text;
  454.         for i, name in ipairs(team.players) do
  455.             print(message, name);
  456.         end
  457.     end
  458. end
  459.  
  460. -- command handling
  461.  
  462. function eventChatCommand(player, message)
  463.     local args = split(message, "%s");
  464.     local text = table.remove(args, 1);
  465.    
  466.     command.handle(string.lower(text), player, args);
  467. end
  468.  
  469. command = {handlers = {}};
  470.  
  471. function command.addHandler(text, handler)
  472.     if command.handlers[text] == nil then
  473.         command.handlers[text] = {};
  474.         system.disableChatCommandDisplay(text, true);
  475.     end
  476.     table.insert(command.handlers[text], handler);
  477. end
  478.    
  479. function command.removeHandler(text, handler)
  480.     if command.handlers[text] ~= nil then
  481.         local index
  482.         for i, h in ipairs(command.handlers[text]) do
  483.             if handler == h then
  484.                 index = i;
  485.             end
  486.         end
  487.         if index ~= nil then
  488.             table.remove(command.handlers[text], index)
  489.             if table.getn(command.handlers[text]) == 0 then
  490.                 command.handlers[text] = nil;
  491.                 --system.disableChatCommandDisplay(text, false);
  492.             end
  493.         end
  494.     end
  495. end
  496.  
  497. function command.handle(text, player, args)
  498.     if command.handlers[text] ~= nil then
  499.         for i, handler in ipairs(command.handlers[text]) do
  500.             handler(player, unpack(args));
  501.         end
  502.     end
  503. end
  504.  
  505. function split(input, seperator)
  506.     local res = {};
  507.     for part in string.gmatch(input, "[^" .. seperator .. "]+") do
  508.         table.insert(res, part);
  509.     end
  510.     return res;
  511. end
  512.  
  513. -- system unpack is unavailable
  514. function unpack(t, i)
  515.     i = i or 1;
  516.     if t[i] ~= nil then
  517.         return t[i], unpack(t, i + 1);
  518.     end
  519. end
  520.  
  521. main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement