Advertisement
Guest User

Official EN FC Small Football Edition

a guest
Nov 22nd, 2017
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.52 KB | None | 0 0
  1. -- Module [football] by Matiasgim and Sincabellera
  2.  
  3. --tfm.exec.setRoomMaxPlayers(14)
  4. tfm.exec.disableAutoShaman(true)
  5.  
  6. local MAP = "@7136237";
  7. local MAX_SCORE = 20;
  8. local 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.";
  9. local keys = {space = 32, left = 37, right = 39, a = 65, d = 68, q = 81, x = 88};
  10. local team1 = {id = 1, score = 1, colour = "0x0000FF", colour2 = "0x8888FF", tag = "<BV>", name = "the blue team", players = {}};
  11. local team2 = {id = 2, score = 1, colour = "0xFF0000", colour2 = "0xFF8888", tag = "<R>", name = "the red team", players = {}};
  12. local ball = {player = nil, object = 0, t = 0, x = 0, y = 0, vx = 0, vy = 0, ax = 0, ay = 0, takeTime = 0, shootTime = 0};
  13. local tasks = {};
  14.  
  15. local addShamanObject = function(...)
  16.     local object, x, y, r, vx, vy = ...
  17.     print(object .. "," .. x .. "," .. y .. "," .. r .. "," .. vx .. "," .. vy)
  18.     return tfm.exec.addShamanObject(...)
  19. end
  20.  
  21. local players = {};
  22. local spectators = {Matiasgim};
  23.  
  24. function table.copy(t)
  25.   local t2 = {}
  26.   for k,v in pairs(t) do
  27.     t2[k] = v
  28.   end
  29.   return t2
  30. end
  31.  
  32. function printInfo(name, value, tabs)
  33.     tabs = tabs or "";
  34.     local t = type(value);
  35.     print(tabs .. t .. " " .. tostring(name) .. " = " .. tostring(value));
  36.     if t == "table" then
  37.         for n, v in pairs(value) do
  38.             if v == value then
  39.                 print(tabs .. "\tself " .. n);
  40.             else
  41.                 printInfo(n, v, tabs .. "\t");
  42.             end
  43.         end
  44.     end
  45. end
  46.  
  47. -------------------------
  48. -- Fonction principale --
  49. -------------------------
  50.  
  51. function main()
  52.     command.addHandler("debug", doDebug);
  53.     command.addHandler("cheese", doCheese);
  54.     command.addHandler("help", doHelp);
  55.     command.addHandler("arrow", doArrow);
  56.     --command.addHandler("t", doTeamChat);
  57.    
  58.     debug.disableEventLog(debugOff);
  59.     tfm.exec.disableAutoScore(true);
  60.     tfm.exec.disableAutoNewGame(true);
  61.     tfm.exec.setGameTime(0, true);
  62.     --tfm.exec.chatMessage(WELCOME_MESSAGE);
  63.     tfm.exec.newGame(MAP);
  64. end
  65.  
  66. ------------------------
  67. -- Fonction newGame ----
  68. ------------------------
  69.  
  70. function eventNewGame()
  71.     team1.players = {};
  72.     team2.players = {};
  73.     team1.score = 1;
  74.     team2.score = 1;
  75.     gameOver = false;
  76.     arrows = false;
  77.     clearTextArea = false;
  78.     for name, player in pairs(tfm.get.room.playerList) do
  79.         if player.isShaman then
  80.             tfm.exec.killPlayer(name);
  81.             tfm.exec.respawnPlayer(name);
  82.             shaman = name;
  83.         end
  84.         initPlayer(name);
  85.     end
  86.    
  87.     for name, player in pairs(tfm.get.room.playerList) do
  88.         if player.isShaman then
  89.             tfm.exec.killPlayer(name);
  90.             tfm.exec.respawnPlayer(name);
  91.             shaman = name;
  92.         end
  93.         returnPlayer(name);
  94.     end
  95.     ball.object = nil;
  96.     if #team1.players > 0 and math.random() > 0.5 then
  97.         tasks[os.time() + 5000] = function() giveBall(team1.players[math.random(#team1.players)]) end;
  98.     elseif #team2.players > 0 then
  99.         tasks[os.time() + 5000] = function() giveBall(team2.players[math.random(#team2.players)]) end;
  100.     end
  101. end
  102.  
  103. ------------------------------
  104. -- Fonction PlayerGetCheese --
  105. ------------------------------
  106. function eventPlayerGetCheese(player)
  107.     ball.player = player;
  108. end
  109.  
  110. ------------------------
  111. -- Fonction eventLoop --
  112. ------------------------
  113.  
  114. function doArrow(player)
  115.     if arrows then
  116.     arrows = false
  117.     else
  118.     arrows = true
  119.     end
  120. end
  121.  
  122. function eventLoop()
  123.     --[[if clearTextArea then
  124.     ui.removeTextArea(0, player)
  125.     clearTextArea = false
  126.     end]]
  127.     --local done = {}
  128.     local now = os.time();
  129.    
  130.     -- task handler
  131.     for when, task in pairs(table.copy(tasks)) do
  132.         if when <= now then
  133.             tasks[when] = nil;
  134.             task();
  135.         end
  136.     end
  137.     if not gameOver then
  138.         tfm.exec.setGameTime(60 * team1.score + team2.score + 1, true);
  139.     if arrows then
  140.         local object = ball.object;
  141.         local player = ball.player;
  142.         if object then
  143.             local x, y = getBallLocation();
  144.             addShamanObject(0, x, y - 25, 0, 0, 0, true);
  145.         elseif player then
  146.             local ballPlayer = players[player];
  147.             if false or ballPlayer then
  148.                 addShamanObject(0, ballPlayer.x, ballPlayer.y - 50, 0, 0, 0, true);
  149.             end
  150.             local tfmPlayer = tfm.get.room.playerList[player];
  151.             if tfmPlayer then
  152.                 addShamanObject(0, tfmPlayer.x, tfmPlayer.y - 50, 0, 0, 0, true);
  153.                 end
  154.                 end
  155.                 end
  156.     -- Flèches
  157.        
  158.         --[[local object = ball.object;
  159.         local player = ball.player;
  160.         if object then
  161.             local x, y = getBallLocation();
  162.             addShamanObject(0, x, y - 25, 0, 0, 0, true);
  163.         elseif player then
  164.             local ballPlayer = players[player];
  165.             if false or ballPlayer then
  166.                 addShamanObject(0, ballPlayer.x, ballPlayer.y - 50, 0, 0, 0, true);
  167.             end
  168.             local tfmPlayer = tfm.get.room.playerList[player];
  169.             if tfmPlayer then
  170.                 addShamanObject(0, tfmPlayer.x, tfmPlayer.y - 50, 0, 0, 0, true);
  171.             end
  172.         end]]
  173.     else
  174.         local left =50;
  175.         local right = 1550;
  176.         if team1.score > team2.score then
  177.             right = 800;
  178.         elseif team2.score > team1.score then
  179.             left = 800;
  180.         end
  181.         addShamanObject(28, math.random(left, right), 350, 0, 0, 0, false);
  182.     end
  183. end
  184.  
  185. -----------------------
  186. -- Fonction keyboard --
  187. -----------------------
  188.  
  189. function eventKeyboard(player, key, down, x, y)
  190.     if down and players[player] then
  191.         if key == keys.left or key == keys.a or key == keys.q then
  192.             players[player].direction = -1;
  193.         elseif key == keys.right or key == keys.d then
  194.             players[player].direction = 1;
  195.         end
  196.     end
  197.     if key == keys.space then
  198.         local now = os.time();
  199.         local x2, y2 = getBallLocation(now);
  200.         if player == ball.player then
  201.             if down then
  202.                 ball.space = now;
  203.             elseif ball.space then
  204.                 local force = (now - ball.space) / 100;
  205.                 if force > 8 then
  206.                     force = 8;
  207.                 end
  208.                 ball.space = nil;
  209.                 shootBall(x, y, 5, -6 - force);
  210.                 players[player].shootTime = now;
  211.                 ball.takeTime = 0;
  212.                 ball.shooter = player;
  213.             end
  214.         elseif ball.object then
  215.             local shootTime = players[player].shootTime or 0;
  216.             if now > shootTime + 1000 and isClose(x, y - 25, getBallLocation(now)) then
  217.                 removeBall();
  218.                 ball.takeTime = now;
  219.                 giveBall(player);
  220.                 ball.space = nil;
  221.                 ball.passer = ball.shooter;
  222.             end
  223.         elseif ball.player and players[ball.player] and players[ball.player].team.id ~= players[player].team.id and now > ball.takeTime + 1000 then
  224.             local ballPlayer = tfm.get.room.playerList[ball.player];
  225.             local tfmPlayer = tfm.get.room.playerList[player];
  226.             if isClose(x, y, ballPlayer.x, ballPlayer.y) or isClose(tfmPlayer.x, tfmPlayer.y, ballPlayer.x, ballPlayer.y) then
  227.                 takeBall(ballPlayer.x, ballPlayer.y);
  228.                 ball.takeTime = now;
  229.                 giveBall(player);
  230.                 ball.space = nil;
  231.                 ball.passer = nil;
  232.             end
  233.         end
  234.     end
  235.     --players[player].x = x;
  236.     --players[player].y = y;
  237. end
  238.  
  239. ----------------------
  240. -- Fonction isClose --
  241. ----------------------
  242.  
  243. function isClose(x, y, x2, y2)
  244.     local d = 25;
  245.     return x < x2+d and x > x2-d and y < y2+d and y > y2-d;
  246. end
  247.  
  248. -------------------------
  249. -- Fonction removeBall --
  250. -------------------------
  251.  
  252. function removeBall()
  253.     tfm.exec.removeObject(ball.object);
  254.     ball.object = nil;
  255.     if ball.floorTimer then
  256.         system.removeTimer(ball.floorTimer);
  257.     end
  258.     ball.floorTimer = nil;
  259.     if ball.goalTimer then
  260.         tasks[ball.goalTimer] = nil;
  261.     end
  262.     ball.goalTimer = nil;
  263. end
  264.  
  265. ------------------------
  266. -- Fonction shootBall --
  267. ------------------------
  268.  
  269. function shootBall(x, y, vx, vy)
  270.     ball.x = x;
  271.     ball.y = y;
  272.     ball.vx = players[ball.player].direction * (vx or 5);
  273.     ball.vy = (vy or -6);
  274.     ball.ax = 0;
  275.     ball.ay = 5;
  276.     if ball.object then
  277.         tfm.exec.removeObject(ball.object);
  278.     end
  279.     ball.t = os.time();
  280.     --ball.object = addShamanObject(tfm.enum.shamanObject.littleBox, x, y, 0, ball.vx, ball.vy, true);
  281.     ball.object = addShamanObject(17, x, y, 0, 0, 0, true);
  282.     tfm.exec.moveObject(ball.object, x, y, false, ball.vx*10, ball.vy*10, false);
  283.     if not gameOver then
  284.         local yf = 330; --floor
  285.         setFloorTimer(yf);
  286.         if ball.vx < 0 then
  287.             setGoalTimer(0);
  288.         elseif ball.vx > 0 then
  289.             setGoalTimer(800);
  290.         end
  291.     end
  292.     takeBall(x, y);
  293. end
  294.  
  295. ----------------------------
  296. -- Fonction setFloorTimer --
  297. ----------------------------
  298.  
  299. function setFloorTimer(yf)
  300.     if ball.floorTimer then
  301.         system.removeTimer(ball.floorTimer);
  302.     end
  303.     if yf then
  304.         local tf;
  305.         if (ball.ay == 0) then
  306.             tf = (yf - ball.y) / (30*ball.vy);
  307.         else
  308.             tf = (-(30*ball.vy) + math.sqrt((30*ball.vy)*(30*ball.vy) - 4*(30*ball.ay)*(ball.y-yf))) / (2*(30*ball.ay));
  309.             if tf < 0 then
  310.                 --print"-");
  311.                 tf = (-(30*ball.vy) - math.sqrt((30*ball.vy)*(30*ball.vy) - 4*(30*ball.ay)*(ball.y-yf)))/(2*(30*ball.ay));
  312.             end
  313.         end
  314.         if tf < 1 then
  315.             tf = 1;
  316.         end
  317.         --ball.floorTimer = system.newTimer(hitFloor, tf * 1000, false, tf);
  318.     end
  319. end
  320.  
  321. -----------------------
  322. -- Fonction hitFloor --
  323. -----------------------
  324.  
  325. function hitFloor(timer, tf)
  326.     local now = os.time();
  327.     local x, y = getBallLocation(now);
  328.     ball.x = x;
  329.     ball.y = 330;
  330.     ball.vy = 0;
  331.     ball.ax = 0;
  332.     ball.ay = 0;
  333.     ball.t = now;
  334.     tfm.exec.moveObject(ball.object, ball.x, ball.y, false, 0, ball.vy, false);
  335.     --print"hit!");
  336.     --printtf .. "," .. x .. "," .. y);
  337. end
  338.  
  339. ---------------------------
  340. -- Fonction setGoalTimer --
  341. ---------------------------
  342.  
  343. function setGoalTimer(xg)
  344.     if ball.goalTimer then
  345.         tasks[ball.goalTimer] = nil;
  346.     end
  347.     if xg then
  348.         local tg;
  349.         if (ball.ax == 0) then
  350.             tg = (xg - ball.x) / (30*ball.vx);
  351.         else
  352.             tg = (-(30*ball.vx) + math.sqrt((30*ball.vx)*(30*ball.vx) - 4*(30*ball.ax)*(ball.x-xg))) / (2*(30*ball.ax));
  353.             if tg < 0 then
  354.                 --print"-");
  355.                 tg = (-30*ball.vx - math.sqrt(900*ball.vx*ball.vx - 480*ball.ax*(ball.x-xg))) / (60*ball.ax);
  356.             end
  357.         end
  358.         local _, hit = getBallLocation(os.time() + tg * 1000);
  359.         local height = 275;
  360.         ball.scored = hit > height;
  361.        
  362.         if tg < 1 then
  363.             tg = 1;
  364.         end
  365.         ball.goalTimer = os.time() + tg * 1000;
  366.         tasks[ball.goalTimer] = hitGoal;
  367.     end
  368. end
  369.  
  370. ----------------------
  371. -- Fonction hitgoal --
  372. ----------------------
  373.  
  374. add = ui.addTextArea
  375. font = "<p align='center'><font size='11'><face='verdana'>"
  376.  
  377. function hitGoal()
  378.     local winner;
  379.     local loser;
  380.     local loser;
  381.     if ball.vx > 0 then
  382.         winner = team1;
  383.         loser = team2;
  384.     elseif ball.vx < 0 then
  385.         winner = team2;
  386.         loser = team1;
  387.     end
  388.     if ball.scored then
  389.         winner.score = winner.score + 1;
  390.         if players[ball.shooter].team == winner then
  391.             tfm.exec.setPlayerScore(ball.shooter, 10, true);
  392.             local pass = "";
  393.             if ball.passer and players[ball.passer] and players[ball.passer].team == winner then
  394.                 tfm.exec.setPlayerScore(ball.passer, 5, true);
  395.                 pass = " after a pass from " .. winner.tag .. ball.passer .. "<BL>";
  396.             end
  397.             add(0, font .. winner.tag .. ball.shooter .. "<BL> scored" .. pass .. "!\n" .. team1.tag .. team1.name .. " <V>" .. team1.score .. "<BL> - <V>" .. team2.score .. team2.tag .. " " .. team2.name, nil, 300, 50, 200, height, 0x324752, 0x382020, 0.9, false);
  398.         else
  399.             tfm.exec.setPlayerScore(ball.shooter, -10, true);
  400.             add(0, font .. loser.tag .. ball.shooter .. "<BL> scored an own goal!\n" .. team1.tag .. team1.name .. " <V>" .. team1.score .. "<BL> - <V>" .. team2.score .. team2.tag .. " " .. team2.name, nil, 300, 50, 200, height, 0x324752, 0x382020, 0.9, false);
  401.         end
  402.         --add(1,team1.tag .. team1.name .. " <V>" .. team1.score .. "<BL> - <V>" .. team2.score .. team2.tag .. " " .. team2.name, nil, 300, 50, 200, height, 0x324752, 0x382020, 0.9, false);
  403.         if winner.score == MAX_SCORE then
  404.             add(0, font .. "<J>Well done, players of " .. winner.tag .. winner.name .. "<J>, you win!", nil, 300, 50, 200, height, 0x324752, 0x382020, 0.9, false);
  405.             gameOver = true;
  406.             tfm.exec.setGameTime(20, true);
  407.             system.newTimer(function() tfm.exec.newGame(MAP) end, 20000, false);
  408.         end
  409.     else
  410.         add(0, font .. players[ball.shooter].team.tag .. ball.shooter .. "<BL> missed!", nil, 300, 50, 200, height, 0x324752, 0x382020, 0.9, false);
  411.     end
  412.     removeBall();
  413.     ball.shooter = nil;
  414.     ball.passer = nil;
  415.    
  416.     for name, player in pairs(players) do
  417.         returnPlayer(name);
  418.     end
  419.     if #loser.players > 0 then
  420.         giveBall(loser.players[math.random(#loser.players)]);
  421.     else
  422.         giveBall(winner.players[math.random(#winner.players)]);
  423.     end
  424. end
  425.  
  426. -----------------------
  427. -- Fonction takeBall --
  428. -----------------------
  429.  
  430. function takeBall(x, y)
  431.     tfm.exec.killPlayer(ball.player);
  432.     tfm.exec.respawnPlayer(ball.player);
  433.     if x and y then
  434.         tfm.exec.movePlayer(ball.player, x, y);
  435.     end
  436.     ball.player = nil;
  437. end
  438.    
  439. function giveBall(player)
  440.     tfm.exec.giveCheese(player);
  441.     ball.player = player;
  442. end
  443.  
  444. function getBallLocation(t)
  445.     t = t or os.time();
  446.     local dt = os.difftime(t, ball.t) / 1000;
  447.     local x = ball.x + dt*(ball.vx + ball.ax*dt) * 30;
  448.     --local y = ball.y + dt*(ball.vy + ball.ay*dt) * 30;
  449.     -- FIXED GROUND
  450.     local y = math.min(ball.y + dt*(ball.vy + ball.ay*dt) * 30, 330);
  451.     return x, y;
  452. end
  453.  
  454. ------------------------
  455. -- Fonction newPlayer --
  456. ------------------------
  457.  
  458. function eventNewPlayer(player)
  459.     --tfm.exec.chatMessage(WELCOME_MESSAGE, player);
  460.     initPlayer(player);
  461.     tfm.exec.respawnPlayer(player);
  462.     returnPlayer(player);
  463. end
  464.  
  465. -------------------------
  466. -- Fonction initPlayer --
  467. -------------------------
  468.  
  469. function initPlayer(player)
  470.     players[player] = {direction = 1, x = 0, y = 0};
  471.     for key, code in pairs(keys) do
  472.         tfm.exec.bindKeyboard(player, code, true, true);
  473.         tfm.exec.bindKeyboard(player, code, false, true);
  474.     end
  475.     local team;
  476.     if #team1.players < #team2.players then
  477.         team = team1;
  478.     elseif #team1.players > #team2.players then
  479.         team = team2;
  480.     elseif math.random() < 0.5 then
  481.         team = team1;
  482.     else
  483.         team = team2;
  484.     end
  485.     table.insert(team.players, player);
  486.     players[player].team = team;
  487.    
  488.     --tfm.exec.chatMessage("<N>Press the <VP>space bar<N> to take or shoot the ball.", player);
  489.     --tfm.exec.chatMessage("<J>You joined " .. team.tag .. team.name .. "<J>!", player);
  490. end
  491.  
  492. ---------------------------
  493. -- Fonction returnPlayer --
  494. ---------------------------
  495.  
  496. function returnPlayer(player)
  497.     if not players[player] then
  498.         initPlayer(player)
  499.     end
  500.     local team = players[player].team;
  501.     tfm.exec.setNameColor(player, team.colour);
  502.     if team == team1 then
  503.         tfm.exec.movePlayer(player, math.random(50, 400), 350);
  504.     elseif team == team2 then
  505.         tfm.exec.movePlayer(player, math.random(400, 750), 350);
  506.     end
  507. end
  508.  
  509. -------------------------
  510. -- Fonction playerLeft --
  511. -------------------------
  512.  
  513. function eventPlayerLeft(player)
  514.     local team = players[player].team;
  515.     local index;
  516.     for i, name in ipairs(team.players) do
  517.         if name == player then
  518.             index = i;
  519.         end
  520.     end
  521.     table.remove(team.players, index);
  522.     if ball.player == player then
  523.         if #team.players == 0 and team == team1 then
  524.             team = team2;
  525.         elseif #team.players == 0 and team == team2 then
  526.             team = team1
  527.         end
  528.         giveBall(team.players[math.random(#team.players)]);
  529.     end
  530.    
  531.     for key, code in pairs(keys) do
  532.         tfm.exec.bindKeyboard(player, code, true, false);
  533.         tfm.exec.bindKeyboard(player, code, false, false);
  534.     end
  535. end
  536.  
  537. ----------------------
  538. -- Fonction doDebug --
  539. ----------------------
  540.  
  541. local debugOff = true;
  542. function doDebug(player)
  543.     if player == "Makinit" then
  544.         debugOff = not debugOff;
  545.         debug.disableEventLog(debugOff);
  546.     end
  547. end
  548.  
  549. -----------------------
  550. -- Fonction doCheese --
  551. -----------------------
  552.  
  553. function doCheese(player)
  554.     if player == "L" then
  555.         tfm.exec.giveCheese("L");
  556.     end
  557. end
  558.  
  559. -- Test --
  560.  
  561. ---------------------
  562. -- Fonction doHelp --
  563. ---------------------
  564.  
  565. function doHelp(player)
  566.     local message = [[<J>You are a team player and you have to cooperate to score!
  567. 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.
  568. The first team to reach ]] .. MAX_SCORE .. [[ points will win!
  569. Commands:
  570. <N>!help<J> - displays this message
  571. <N>!t message<J> - team chat]];
  572.     ui.addPopup(0, 0, message, player, 250, yPos, 300, true);
  573. end
  574.  
  575. --------------------------
  576. -- Fonctions doTeamChat --
  577. --------------------------
  578.  
  579. --[[function doTeamChat(player, ...)
  580.     local arg = {...}
  581.     local team = players[player].team;
  582.     local text = string.gsub(string.gsub(table.concat(arg, " "), "<", "&lt;"), ">", "&gt;");
  583.     if team and text and text ~= "" then
  584.         local message = team.tag .. "[" .. player .. "]<N> " .. text;
  585.         for i, name in ipairs(team.players) do
  586.             tfm.exec.chat(message, name);
  587.         end-
  588.     end
  589. end]]
  590.  
  591. -- command handling
  592.  
  593. function eventChatCommand(player, message)
  594.     local args = split(message, "%s");
  595.     local text = table.remove(args, 1);
  596.    
  597.     command.handle(string.lower(text), player, args);
  598. end
  599.  
  600. command = {handlers = {}};
  601.  
  602. function command.addHandler(text, handler)
  603.     if command.handlers[text] == nil then
  604.         command.handlers[text] = {};
  605.         system.disableChatCommandDisplay(text, true);
  606.     end
  607.     table.insert(command.handlers[text], handler);
  608. end
  609.    
  610. function command.removeHandler(text, handler)
  611.     if command.handlers[text] ~= nil then
  612.         local index
  613.         for i, h in ipairs(command.handlers[text]) do
  614.             if handler == h then
  615.                 index = i;
  616.             end
  617.         end
  618.         if index ~= nil then
  619.             table.remove(command.handlers[text], index)
  620.             if #command.handlers[text] == 0 then
  621.                 command.handlers[text] = nil;
  622.                 --system.disableChatCommandDisplay(text, false);
  623.             end
  624.         end
  625.     end
  626. end
  627.  
  628. function command.handle(text, player, args)
  629.     if command.handlers[text] ~= nil then
  630.         for i, handler in ipairs(command.handlers[text]) do
  631.             handler(player, unpack(args));
  632.         end
  633.     end
  634. end
  635.  
  636. function split(input, seperator)
  637.     local res = {};
  638.     for part in string.gmatch(input, "[^" .. seperator .. "]+") do
  639.         table.insert(res, part);
  640.     end
  641.     return res;
  642. end
  643.  
  644. -- system unpack is unavailable
  645. function unpack(t, i)
  646.     i = i or 1;
  647.     if t[i] ~= nil then
  648.         return t[i], unpack(t, i + 1);
  649.     end
  650. end
  651.  
  652. main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement