Downloads containing tp.mut

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Teleportation mutatorFeatured Download ak-47 Mutator 10 Download file

File preview

  1. #pragma name "Teleport (by ak-47)"
  2.  
  3.  
  4. const string COMMAND_POS = "!pos";
  5. const string COMMAND_TP = "!tp ?(\\d\\d?)";
  6. const string COMMAND_TP_RELOC = "!tp ?(\\d*), ?(\\d*)";
  7. const string COMMAND_TPA = "!tpa ?(\\d\\d?)";
  8. const string COMMAND_TPA_ACCEPT = "!((tp ?y)|a) ?((\\d\\d?)";
  9. const string COMMAND_TAKEOVER = "!takeover ?(\\d\\d?) ?(lax)?";
  10. const string COMMAND_RELEASE = "!release";
  11.  
  12. const int MOUSE_TRACK_KEY = 2;  // right button click
  13. const uint MOUSE_PRECISION_FACTOR = 65536;  // this is high, ok?
  14.  
  15. const int8 NO_PLAYER_INFORMATION = -1;
  16. const int FRAME_PIXELS = 32;
  17. const uint8 MAX_TPA_REQUESTS = 3;
  18. const uint8 OVERRIDE_TAKEOVER_KEY = 0x10;
  19.  
  20. array<array<uint8>> requestMap (32);
  21. array<bool> isRequestingTPA (32);
  22. int8 takenOverPlayerID = 0;
  23. bool laxTakeOver = false;
  24.  
  25. enum PACKET_ID {
  26.         UPDATE_POSITION,
  27.         TPA_REQUEST,
  28.         TAKEOVER
  29. }
  30.  
  31.  
  32. /*
  33. Moves a player from the current position
  34. to the desired one, determined by the arguments following the first.
  35. */
  36. void setLocalPlayerPosition
  37. (
  38.     jjPLAYER@ player,
  39.     int xPos,
  40.     int yPos,
  41.     bool affectDirection = true
  42. )
  43. {
  44.     if (affectDirection && player.xPos != xPos)
  45.         player.direction = ((player.xPos - xPos) < 0) ? abs(player.direction) : -abs(player.direction);
  46.     player.xPos = xPos;
  47.     player.yPos = yPos;
  48. }
  49.  
  50.  
  51. void sendUpdatePositionPacket
  52. (
  53.     jjPLAYER@ player,
  54.     int newXPos,
  55.     int newYPos,
  56.     int8 toPlayerID = NO_PLAYER_INFORMATION,
  57.         bool log = true
  58. )
  59. {
  60.     jjSTREAM packet;
  61.     packet.push(uint8(UPDATE_POSITION));
  62.     packet.push(player.playerID);
  63.     packet.push(toPlayerID);
  64.     packet.push(newXPos);
  65.     packet.push(newYPos);
  66.     packet.push(log);
  67.     jjSendPacket(packet, player.clientID);
  68. }
  69.  
  70.  
  71. void onUpdatePositionPacket(jjSTREAM &in packet, int fromClientID)
  72. {
  73.     uint8 playerID;
  74.         packet.pop(playerID);
  75.     jjPLAYER@ player = jjPlayers[playerID];
  76.  
  77.     int8 toPlayerID;
  78.     packet.pop(toPlayerID);
  79.  
  80.     if (player.isLocal)
  81.     {
  82.         int newXPos;
  83.         int newYPos;
  84.                 bool log;
  85.         packet.pop(newXPos);
  86.         packet.pop(newYPos);
  87.                 packet.pop(log);
  88.         setPlayerPosition(
  89.             player,
  90.             newXPos,
  91.             newYPos,
  92.             toPlayerID,
  93.                         log
  94.         );
  95.     }
  96. }
  97.  
  98.  
  99. void sendTPARequestPacket
  100. (
  101.     jjPLAYER@ player,
  102.     jjPLAYER@ toPlayer,
  103.     uint8 requestID
  104. )
  105. {
  106.     jjSTREAM packet;
  107.     packet.push(uint8(TPA_REQUEST));
  108.     packet.push(player.playerID);
  109.     packet.push(toPlayer.playerID);
  110.     packet.push(requestID);
  111.     jjSendPacket(packet, toPlayer.clientID);
  112. }
  113.  
  114.  
  115. void onTPARequestPacket(jjSTREAM &in packet, int fromClientID)
  116. {
  117.     uint8 playerID;
  118.     packet.pop(playerID);
  119.     jjPLAYER@ player = jjPlayers[playerID];
  120.  
  121.     int8 toPlayerID;
  122.     packet.pop(toPlayerID);
  123.  
  124.     uint8 requestID;
  125.     packet.pop(requestID);
  126.  
  127.     jjConsole(
  128.         "Request #" + formatUInt(requestID) + ": "
  129.         + player.nameUnformatted
  130.         + " wants to teleport to you. "
  131.         + "Type \"!a "
  132.         + formatUInt(requestID)
  133.         + "\" to accept this request."
  134.     );
  135. }
  136.  
  137. void onTakeoverPacket(jjSTREAM &in packet, int fromClientID)
  138. {
  139.         // Why do we get those junks here? I don't know.
  140.         uint8 junk_1;
  141.         uint16 junk_2;
  142.         packet.pop(junk_1);
  143.         packet.pop(junk_2);
  144.         uint8 previousTakenOverPlayerID = takenOverPlayerID;
  145.         bool wasLax = laxTakeOver;
  146.         packet.pop(takenOverPlayerID);
  147.         packet.pop(laxTakeOver);
  148.         /* if (jjPlayers[takenOverPlayerID].isLocal && previousTakenOverPlayerID != takenOverPlayerID)
  149.         {              
  150.                 jjConsole(jjPlayers[0].nameUnformatted + " (the host) has gained control over your position. Follow the instructions carefully.");
  151.                 return;
  152.         }
  153.         if (!jjPlayers[takenOverPlayerID].isLocal && !wasLax && jjPlayers[previousTakenOverPlayerID].isLocal)
  154.                 jjConsole(jjPlayers[0].nameUnformatted + " (the host) has brought you back the privilege of freedom. Beware though.");
  155.         */
  156. }
  157.  
  158. void sendTakeoverPacket()
  159. {
  160.     jjSTREAM packet;
  161.         packet.push(TAKEOVER);
  162.         packet.push(takenOverPlayerID);
  163.         packet.push(laxTakeOver);
  164.         jjSendPacket(packet);
  165. }
  166.  
  167. void setTakenOver(uint8 value, bool lax = false)
  168. {
  169.         takenOverPlayerID = value;
  170.         laxTakeOver = lax;
  171.         sendTakeoverPacket();
  172. }
  173.  
  174.  
  175. void onReceive(jjSTREAM &in packet, int fromClientID)
  176. {
  177.     int8 packetID;
  178.     packet.pop(packetID);
  179.  
  180.     switch (packetID)
  181.     {
  182.         case UPDATE_POSITION:
  183.             onUpdatePositionPacket(packet, fromClientID);
  184.             break;
  185.         case TPA_REQUEST:
  186.             onTPARequestPacket(packet, fromClientID);
  187.             break;
  188.                 case TAKEOVER:
  189.                         onTakeoverPacket(packet, fromClientID);
  190.                         break;
  191.     }
  192. }
  193.  
  194.  
  195. void logPlayerTeleportation
  196. (
  197.     jjPLAYER@ player,
  198.     int xPos,
  199.     int yPos,
  200.     int8 toPlayerID = NO_PLAYER_INFORMATION
  201. )
  202. {
  203.     string teleportationInformation;
  204.     if (toPlayerID != NO_PLAYER_INFORMATION)
  205.     {
  206.         jjPLAYER@ toPlayer = jjPlayers[toPlayerID];
  207.         teleportationInformation += toPlayer.nameUnformatted + " at ";
  208.     }
  209.     teleportationInformation += formatInt(int(xPos / FRAME_PIXELS));
  210.     teleportationInformation += ", ";
  211.     teleportationInformation += formatInt(int(yPos / FRAME_PIXELS));
  212.     if (jjIsServer)
  213.     {
  214.         jjConsole(
  215.             player.nameUnformatted
  216.             + " is being teleported to "
  217.             + teleportationInformation
  218.         );
  219.     }
  220.     else if (player.playerID == jjLocalPlayers[0].playerID)
  221.     {
  222.         jjConsole("You are being teleported to " + teleportationInformation);
  223.     }
  224. }
  225.  
  226.  
  227. void setPlayerPosition
  228. (
  229.     jjPLAYER@ player,
  230.     int xPos,
  231.     int yPos,
  232.     int8 toPlayerID = NO_PLAYER_INFORMATION,
  233.     bool log = true
  234. )
  235. {
  236.     setLocalPlayerPosition(player, xPos, yPos);
  237.     if (log) logPlayerTeleportation(player, xPos, yPos, toPlayerID);
  238.     if (!player.isLocal && jjIsServer)
  239.         sendUpdatePositionPacket(player, xPos, yPos, toPlayerID, log);
  240. }
  241.  
  242. void setPlayerPosition
  243. (
  244.     jjPLAYER@ player,
  245.     jjPLAYER@ toPlayer,
  246.         bool log = true
  247. )
  248. {
  249.     setPlayerPosition(player, int(toPlayer.xPos), int(toPlayer.yPos), toPlayer.playerID, log);
  250. }
  251.  
  252. int8 saneGetPlayerID(uint8 playerID, bool mustBeInGame = true, bool log = true)
  253. {
  254.     if (playerID < 0 || playerID > 31)
  255.     {
  256.         if (log) jjConsole("|>> Player number in list must be in range 1-32", true);
  257.         return NO_PLAYER_INFORMATION;
  258.     };
  259.     if (mustBeInGame && !jjPlayers[playerID].isInGame)
  260.     {
  261.         if (log) jjConsole("|>> Player is not in the game", true);
  262.         return NO_PLAYER_INFORMATION;
  263.     }
  264.     return playerID;
  265. }
  266.  
  267.  
  268. bool canTeleport
  269. (
  270.     uint8 playerID,
  271.     uint8 targetPlayerID,
  272.         bool log = true
  273. )
  274. {
  275.     if (targetPlayerID == playerID)
  276.     {
  277.         if (log) jjConsole("|>> Hold your horses, young lady", true);
  278.         return false;
  279.     }
  280.         jjPLAYER@ toPlayer = jjPlayers[saneGetPlayerID(targetPlayerID, true, log)];
  281.     return true;
  282. }
  283.  
  284.  
  285. void mimickPlayerMouse(jjPLAYER@ targetPlayer, jjPLAYER@ mimickedPlayer)
  286. {
  287.         if
  288.         (
  289.                 MOUSE_TRACK_KEY != -1
  290.                 && mimickedPlayer.isLocal
  291.                 && targetPlayer.isInGame
  292.                 && jjKey[MOUSE_TRACK_KEY]
  293.         )
  294.         {
  295.                 int x = int(jjMouseX + mimickedPlayer.cameraX - (MOUSE_PRECISION_FACTOR * (mimickedPlayer.subscreenX - jjBorderWidth)));
  296.                 int y = int(jjMouseY + mimickedPlayer.cameraY - (MOUSE_PRECISION_FACTOR * (mimickedPlayer.subscreenY - jjBorderHeight)));
  297.                 setPlayerPosition(targetPlayer, x, y, NO_PLAYER_INFORMATION, false);
  298.         }
  299. }
  300.  
  301. void onPlayerInput(jjPLAYER@ player)
  302. {
  303.         if (!player.isLocal) return;
  304.         if (jjIsServer) {
  305.                 jjPLAYER@ targetPlayer = jjKey[OVERRIDE_TAKEOVER_KEY] ? player : jjPlayers[takenOverPlayerID];
  306.                 mimickPlayerMouse(targetPlayer, player);
  307.         }
  308.         else if (laxTakeOver ? true : player.playerID != takenOverPlayerID)
  309.                 mimickPlayerMouse(player, player);
  310. }
  311.  
  312.  
  313. bool onLocalChat(string &in stringReceived, CHAT::Type chatType)
  314. {
  315.         if (!jjIsServer) return false;
  316.         array<string> arguments;
  317.        
  318.         if (jjRegexMatch(stringReceived, COMMAND_TAKEOVER, arguments)) {
  319.                 int8 candidate = saneGetPlayerID(uint8(parseUInt(arguments[1]) - 1));
  320.                 bool lax = arguments[2] != "";
  321.                 if (candidate != NO_PLAYER_INFORMATION)
  322.                 {
  323.                         setTakenOver(uint8(candidate), lax);
  324.                         jjConsole(jjPlayers[takenOverPlayerID].nameUnformatted + " has been taken over. You've become Darth Vader!");
  325.                 }
  326.                 return true;
  327.         }
  328.         if (stringReceived == COMMAND_RELEASE) {
  329.                 if (takenOverPlayerID != 0)
  330.                         jjConsole(jjPlayers[takenOverPlayerID].nameUnformatted + " has been released.");
  331.                 setTakenOver(0);
  332.                 return true;
  333.         }
  334.         return false;
  335.  
  336. }
  337.  
  338. void onChat(int clientID, string &in stringReceived, CHAT::Type chatType)
  339. {
  340.     if (!jjIsServer) {return;}
  341.  
  342.     jjPLAYER@ player = jjPlayersWithClientID(clientID)[0];
  343.  
  344.     if (stringReceived == COMMAND_POS) {
  345.         string xPos = formatUInt(int(player.xPos / FRAME_PIXELS));
  346.         string yPos = formatUInt(int(player.yPos / FRAME_PIXELS));
  347.         jjConsole("Your position is: ||" + xPos + ", " + yPos, true);
  348.         return;
  349.     }
  350.  
  351.     array<string> moveToPosition;
  352.     if (jjRegexMatch(stringReceived, COMMAND_TP_RELOC, moveToPosition)) {
  353.         int xPos = int(parseInt(moveToPosition[1]) * FRAME_PIXELS);
  354.         int yPos = int(parseInt(moveToPosition[2]) * FRAME_PIXELS);
  355.         setPlayerPosition(player, xPos, yPos);
  356.         return;
  357.     }
  358.        
  359.  
  360.     jjPLAYER@ toPlayer;
  361.     uint8 playerID = player.playerID;
  362.  
  363.     array<string> moveToPlayer;
  364.     if (jjRegexMatch(stringReceived, COMMAND_TP, moveToPlayer))
  365.     {
  366.         uint8 targetPlayerID = parseUInt(moveToPlayer[1]) - 1;
  367.         @toPlayer = @jjPlayers[targetPlayerID];
  368.         if (canTeleport(playerID, targetPlayerID))
  369.             setPlayerPosition(player, toPlayer);
  370.         return;
  371.     }
  372.  
  373.     array<string> askIfCanMoveToPlayer;
  374.  
  375.     if (jjRegexMatch(stringReceived, COMMAND_TPA, askIfCanMoveToPlayer))
  376.     {
  377.         uint8 targetPlayerID = parseUInt(askIfCanMoveToPlayer[1]) - 1;
  378.  
  379.         if (canTeleport(playerID, targetPlayerID)) {
  380.             @toPlayer = @jjPlayers[targetPlayerID];
  381.             bool isRequesting = isRequestingTPA[playerID];
  382.             bool isOppositeRequesting = isRequestingTPA[targetPlayerID];
  383.  
  384.             if (isRequesting) {
  385.                 jjConsole(
  386.                     "|>> You already want to teleport to someone!"
  387.                     + "Type '!tpa cancel' to cancel that request.",
  388.                     true
  389.                 );
  390.                 return;
  391.             }
  392.  
  393.             if (isOppositeRequesting) {
  394.                 jjConsole(
  395.                     "|>> " + player.nameUnformatted
  396.                     + " already wants to teleport to somebody!"
  397.                 );
  398.                 return;
  399.             }
  400.  
  401.             if (requestMap[targetPlayerID].length() == MAX_TPA_REQUESTS) {
  402.                 jjConsole(
  403.                     "|>> Too many players want to teleport to "
  404.                     + toPlayer.nameUnformatted
  405.                     + ". Please try again later!"
  406.                 );
  407.                 return;
  408.             }
  409.  
  410.             requestMap[uint8(targetPlayerID)].insertLast(uint8(playerID));
  411.             sendTPARequestPacket(player, toPlayer, requestMap[uint8(targetPlayerID)].length() - 1);
  412.             isRequestingTPA[uint8(playerID)] = true;
  413.         }
  414.         return;
  415.     }
  416.  
  417.     array<string> acceptTPARequest;
  418.  
  419.     if (jjRegexMatch(stringReceived, COMMAND_TPA, acceptTPARequest))
  420.     {
  421.         uint8 acceptID = parseUInt(acceptTPARequest[2]);
  422.         array<uint8> requests = requestMap[toPlayer.playerID];
  423.  
  424.         if (acceptID == 0 || acceptID-- >= requests.length())
  425.         {
  426.             jjConsole("|>> Request ID too big");
  427.             return;
  428.         }
  429.  
  430.         int8 toPlayerID = requests[acceptID];
  431.  
  432.         if (toPlayerID == NO_PLAYER_INFORMATION)
  433.         {
  434.             jjConsole("|>> This request is invalid or expired");
  435.             return;
  436.         }
  437.  
  438.         if (canTeleport(playerID, toPlayerID))
  439.         {
  440.             setPlayerPosition(player, toPlayer);
  441.             isRequestingTPA[uint8(playerID)] = false;
  442. //            requestMap[uint8(toPlayerID)][acceptID] = NO_PLAYER_INFORMATION;
  443.         }
  444.  
  445.     }
  446. }
  447.