Advertisement
Guest User

// VC:MP TeamSystem

a guest
Oct 29th, 2014
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 21.31 KB | None | 0 0
  1. // VC:MP TeamSystem
  2. // ------------------------------------------------------------------------------------------------
  3. // Global table used to scope script commands
  4. _CMD <- {}
  5.  
  6. // ------------------------------------------------------------------------------------------------
  7. // Global enumeration to hold the command syntax
  8. enum CmdSyn
  9. {
  10.     TeamUp = "!teamup <partener-name>",
  11.     SplitUp = "!splitup",
  12.     DenyReq = "!denyreq <partener-name>",
  13.     DenyAll = "!denyall",
  14.     AcceptReq = "!acceptreq <partener-name>",
  15.     AcceptAny = "!acceptany",
  16.     FlushReq = "!flushreq",
  17.     PlaySolo = "!playsolo",
  18.     Partner = "!partner"
  19. }
  20.  
  21. // ------------------------------------------------------------------------------------------------
  22. // Global enumeration to hold the message style and colours
  23. enum MsgTag {
  24.     Dbg = "[#11455D][DEBUG][#F4F3EE]",
  25.     Msg = "[#64A5BB][MESSAGE][#F4F3EE]",
  26.     Scs = "[#698433][SUCCESS][#F4F3EE]",
  27.     Inf = "[#FFD35C][INFO][#F4F3EE]",
  28.     Wrn = "[#FF8202][WARNING][#F4F3EE]",
  29.     Err = "[#EA3E70][ERROR][#F4F3EE]",
  30.     Ftl = "[#C82C3A][FATAL][#F4F3EE]"
  31. }
  32.  
  33. // ------------------------------------------------------------------------------------------------
  34. // Scoped functions used to send formatted messages to players
  35. _Msg <- {
  36.     // --------------------------------------------------------------------------------------------
  37.     function Client(...)
  38.     {
  39.         local i_player = vargv[0], r = vargv[1], g = vargv[2], b = vargv[3];
  40.         vargv = vargv.slice(3);
  41.         vargv[0] = this;
  42.         local str = ::format.acall(vargv);
  43.         ClientMessage(str, i_player, r, g, b);
  44.     }
  45.     // --------------------------------------------------------------------------------------------
  46.     function ClientAlpha(...)
  47.     {
  48.         local i_player = vargv[0], r = vargv[1], g = vargv[2], b = vargv[3], a = vargv[4];
  49.         vargv = vargv.slice(4);
  50.         vargv[0] = this;
  51.         local str = ::format.acall(vargv);
  52.         ClientMessage(str, i_player, r, g, b, a);
  53.     }
  54.     // --------------------------------------------------------------------------------------------
  55.     function ClientAll(...)
  56.     {
  57.         local r = vargv[0], g = vargv[1], b  = vargv[2];
  58.         vargv = vargv.slice(2);
  59.         vargv[0] = this;
  60.         local str = ::format.acall(vargv);
  61.         ClientMessageToAll(str, r, g, b);
  62.     }
  63.     // --------------------------------------------------------------------------------------------
  64.     function ClientAllAlpha(...)
  65.     {
  66.         local r = vargv[0], g = vargv[1], b = vargv[2], a = vargv[3];
  67.         vargv = vargv.slice(3);
  68.         vargv[0] = this;
  69.         local str = ::format.acall(vargv);
  70.         ClientMessageToAll(str, r, g, b, a);
  71.     }
  72.     // --------------------------------------------------------------------------------------------
  73.     function Game(...)
  74.     {
  75.         local i_player = vargv[0], r = vargv[1], g = vargv[2], b = vargv[3];
  76.         vargv = vargv.slice(3);
  77.         vargv[0] = this;
  78.         local str = ::format.acall(vargv);
  79.         Announce(str, i_player, r, g, b);
  80.     }
  81.     // --------------------------------------------------------------------------------------------
  82.     function GameAlpha(...)
  83.     {
  84.         local i_player = vargv[0], r = vargv[1], g = vargv[2], b = vargv[3], a = vargv[4];
  85.         vargv = vargv.slice(4);
  86.         vargv[0] = this;
  87.         local str = ::format.acall(vargv);
  88.         Announce(str, i_player, r, g, b, a);
  89.     }
  90.     // --------------------------------------------------------------------------------------------
  91.     function GameAll(...)
  92.     {
  93.         local r = vargv[0], g = vargv[1], b = vargv[2];
  94.         vargv = vargv.slice(2);
  95.         vargv[0] = this;
  96.         local str = ::format.acall(vargv);
  97.         AnnounceAll(str, r, g, b);
  98.     }
  99.     // --------------------------------------------------------------------------------------------
  100.     function GameAllAlpha(...)
  101.     {
  102.         local r = vargv[0], g = vargv[1], b = vargv[2], a = vargv[3];
  103.         vargv = vargv.slice(3);
  104.         vargv[0] = this;
  105.         local str = ::format.acall(vargv);
  106.         AnnounceAll(str, r, g, b, a);
  107.     }
  108.     // --------------------------------------------------------------------------------------------
  109.     function Player(...)
  110.     {
  111.         local i_player = vargv[0];
  112.         vargv[0] = this;
  113.         local str = ::format.acall(vargv);
  114.         MessagePlayer(str, i_player);
  115.     }
  116. }
  117.  
  118. // ------------------------------------------------------------------------------------------------
  119. _ClientPool <- []
  120.  
  121. // ------------------------------------------------------------------------------------------------
  122. _RequestPool <- []
  123.  
  124. // ------------------------------------------------------------------------------------------------
  125. // Class responsible for management and identification of player instances
  126. class _Client
  127. {
  128.     // --------------------------------------------------------------------------------------------
  129.     function constructor(i_player)
  130.     {
  131.         // Verify the player instance
  132.         if (typeof i_player != "instance") return null;
  133.         // Store the player instance
  134.         else Instance = i_player
  135.     }
  136.     // --------------------------------------------------------------------------------------------
  137.     function Connect()
  138.     {
  139.         // Ignored....
  140.     }
  141.     // --------------------------------------------------------------------------------------------
  142.     function Disconnect()
  143.     {
  144.         // See if the player had any partner
  145.         if (Partner != null) {
  146.             // Notify the partner about the split-up
  147.             _Msg.Player(Partner, @"%s %s has disconnected and you no longer have a partner.", MsgTag.Inf, Instance.Name);
  148.             // Free the partner from used
  149.             _ClientPool[Partner.ID].Partner = null;
  150.             // Clear any stored instances
  151.             Partner = null;
  152.         }
  153.         // See if there's any requests made by this instance and clear them
  154.         if (_RequestPool[Instance.ID] != null) {
  155.             // Notify the partner about the result
  156.             _Msg.Player(_RequestPool[Instance.ID].Target, @"%s %s has disconnected and his team-up request was flushed.", MsgTag.Inf, Instance.Name);
  157.             // Remove the request from the pool/list
  158.             _RequestPool[Instance.ID] = null;
  159.         }
  160.         // See if there's any requests made to this instance and clear them
  161.         foreach (idx, req in _RequestPool) {
  162.             // See if this is a valid request
  163.             if (req != null && req.Target.ID == Instance.ID) {
  164.                 // Notify the partner about the rejected request
  165.                 _Msg.Player(req.Invoker, @"%s %s has disconnected and cannot accept team-up request.", MsgTag.Inf, i_player.Name);
  166.                 // Clear the request from the pool/list
  167.                 _RequestPool[idx] = null;
  168.             }
  169.         }
  170.         // Clear any stored instances
  171.         Instance = null;
  172.     }
  173.     // --------------------------------------------------------------------------------------------
  174.     Instance = null
  175.     // --------------------------------------------------------------------------------------------
  176.     Partner = null
  177.     // --------------------------------------------------------------------------------------------
  178.     PlaySolo = false
  179. }
  180.  
  181. // ------------------------------------------------------------------------------------------------
  182. _CMD.TeamUp <- function(i_player, args)
  183. {
  184.     // See if there isn't already a request in the pool and send a notice to the invoker to flush his previous request
  185.     if (_RequestPool[i_player.ID] != null) return _Msg.Player(i_player, @"%s Please flush your previous request to:  %s", MsgTag.Scs, _RequestPool[i_player.ID].Target.Name);
  186.  
  187.     // See if we are dealing with a valid command
  188.     if (typeof args != "string" || args.len() <= 0) return _Msg.Player(i_player, @"%s Syntax: %s", MsgTag.Inf, CmdSyn.TeamUp);
  189.     // Strip the command from unnecessary space characters
  190.     args = strip(args);
  191.    
  192.     // Check one more time if we still have a valid command
  193.     if (typeof args != "string" || args.len() <= 0) return _Msg.Player(i_player, @"%s Syntax: %s", MsgTag.Inf, CmdSyn.TeamUp);
  194.     // Try to find the target instance by name first
  195.     local i_partner = FindPlayer(args);
  196.    
  197.     // See if we found a valid player instance for our partner
  198.     if (typeof i_partner != "instance") return _Msg.Player(i_player, @"%s There's no player on the server identified by: %s", MsgTag.Err, args);
  199.     // See if the invoker tries to team up with him self
  200.     else if (i_player.ID == i_partner.ID) return _Msg.Player(i_player, @"%s You cannot team up with your self.", MsgTag.Wrn);
  201.     // See if the invoker has the option to play solo enabled
  202.     else if (_ClientPool[i_player.ID].PlaySolo) return _Msg.Player(i_player, @"%s You already chose to play solo.", MsgTag.Wrn);
  203.     // See if the partner has the option to play solo enabled
  204.     else if (_ClientPool[i_partner.ID].PlaySolo) return _Msg.Player(i_player, @"%s %s chose to play solo.", MsgTag.Wrn, i_partner.Name);
  205.     // See if the invoker is already in a team
  206.     else if (_ClientPool[i_player.ID].Partner != null) return _Msg.Player(i_player, @"%s You are already teamed-up with: %s", MsgTag.Wrn, _ClientPool[i_player.ID].Partner.Name);
  207.     // See if the requested partner is already in a team
  208.     else if (_ClientPool[i_partner.ID].Partner != null) return _Msg.Player(i_player, @"%s %s is already teamed-up with: %s", MsgTag.Wrn, i_partner.Name, _ClientPool[i_partner.ID].Partner.Name);
  209.    
  210.     // Submit the request to the pool
  211.     _RequestPool[i_player.ID] = {Invoker = i_player, Target = i_partner, Timeout = (time()+30)};
  212.     // Notify the requested partner
  213.     _Msg.Player(i_partner, @"%s %s would like to team-up with you.", MsgTag.Inf, i_player.Name);
  214.     // Notify the invoker about his request
  215.     _Msg.Player(i_player, @"%s %s successfully received your team-up request.", MsgTag.Scs, i_partner.Name);
  216. }
  217.  
  218. // ------------------------------------------------------------------------------------------------
  219. _CMD.SplitUp <- function(i_player, args)
  220. {
  221.     // See if the invoker is in a team
  222.     if (_ClientPool[i_player.ID].Partner != null) {
  223.         // Inform the invoker about his action
  224.         _Msg.Player(i_player, @"%s You split-up from: %s", MsgTag.Scs, _ClientPool[i_player.ID].Partner.Name);
  225.         // Send a notice to the partner
  226.         _Msg.Player(_ClientPool[i_player.ID].Partner, @"%s %s split-up from you.", MsgTag.Inf, i_player.Name);
  227.         // Remove the link from the partner
  228.         _ClientPool[_ClientPool[i_player.ID].Partner.ID].Partner = null;
  229.         // Remove the link from the invoker
  230.         _ClientPool[i_player.ID].Partner = null;
  231.     // Notify the invoker that he doesn't have a team to split-up
  232.     } else _Msg.Player(i_player, @"%s You don't have a team to split-up.", MsgTag.Wrn);
  233. }
  234.  
  235. // ------------------------------------------------------------------------------------------------
  236. _CMD.DenyReq <- function(i_player, args)
  237. {
  238.     // See if we are dealing with a valid command
  239.     if (typeof args != "string" || args.len() <= 0) return _Msg.Player(i_player, @"%s Syntax: %s", MsgTag.Inf, CmdSyn.DenyReq);
  240.     // Strip the command from unnecessary space characters
  241.     args = strip(args);
  242.    
  243.     // Check one more time if we still have a valid command
  244.     if (typeof args != "string" || args.len() <= 0) return _Msg.Player(i_player, @"%s Syntax: %s", MsgTag.Inf, CmdSyn.DenyReq);
  245.     // Try to find the target instance by name first
  246.     local i_partner = FindPlayer(args);
  247.    
  248.     // See if we found a valid player instance for our partner
  249.     if (typeof i_partner != "instance") return _Msg.Player(i_player, @"%s There's no player on the server identified by: %s", MsgTag.Err, args);
  250.    
  251.     // Notify the partner about the rejected request
  252.     _Msg.Player(i_partner, @"%s %s rejected your team-up request.", MsgTag.Inf, i_player.Name);
  253.     // Notify the invoker about the rejected request
  254.     _Msg.Player(i_player, @"%s You successfully rejected the team-up request from %s", MsgTag.Scs, i_partner.Name);
  255.     // Flush the request from the pool/list
  256.     _RequestPool[i_partner.ID] = null;
  257. }
  258.  
  259. // ------------------------------------------------------------------------------------------------
  260. _CMD.DenyAll <- function(i_player, args)
  261. {
  262.     // Go through each element in the request pool and clear it if it's addressed to the invoker
  263.     foreach (idx, req in _RequestPool) {
  264.         // See if this is a valid request
  265.         if (req != null && req.Target.ID == i_player.ID) {
  266.             // Notify the partner about the rejected request
  267.             _Msg.Player(req.Invoker, @"%s %s rejected your team-up request.", MsgTag.Inf, i_player.Name);
  268.             // Notify the invoker about the rejected request
  269.             _Msg.Player(i_player, @"%s You successfully rejected the team-up request from %s", MsgTag.Scs, req.Invoker.Name);
  270.             // Clear the request from the pool/list
  271.             _RequestPool[idx] = null;
  272.         }
  273.     }
  274. }
  275.  
  276. // ------------------------------------------------------------------------------------------------
  277. _CMD.AcceptReq <- function(i_player, args)
  278. {
  279.     // See if we are dealing with a valid command
  280.     if (typeof args != "string" || args.len() <= 0) return _Msg.Player(i_player, @"%s Syntax: %s", MsgTag.Inf, CmdSyn.AcceptReq);
  281.     // Strip the command from unnecessary space characters
  282.     args = strip(args);
  283.    
  284.     // Check one more time if we still have a valid command
  285.     if (typeof args != "string" || args.len() <= 0) return _Msg.Player(i_player, @"%s Syntax: %s", MsgTag.Inf, CmdSyn.AcceptReq);
  286.     // Try to find the target instance by name first
  287.     local i_partner = FindPlayer(args);
  288.    
  289.     // See if we found a valid player instance for our partner
  290.     if (typeof i_partner != "instance") return _Msg.Player(i_player, @"%s There's no player on the server identified by: %s", MsgTag.Err, args);
  291.    
  292.     // Notify the invoker about the result
  293.     _Msg.Player(i_partner, @"%s %s accepted your team up request.", MsgTag.Inf, i_player.Name);
  294.     // Notify the partner about the result
  295.     _Msg.Player(i_player, @"%s You accepted the team up request from %s", MsgTag.Scs, i_partner.Name);
  296.     // Remove this request from the pool/list
  297.     _RequestPool[i_partner.ID] = null;
  298.     // Link the players together
  299.     _ClientPool[i_player.ID].Partner = i_partner;
  300.     _ClientPool[i_partner.ID].Partner = i_player;
  301.    
  302.     // A variable to count the rest of the requests
  303.     local req_count = 0;
  304.     // Go through each element in the request pool and clear it if it's addressed to the invoker
  305.     foreach (idx, req in _RequestPool) {
  306.         // See if this is a valid request
  307.         if (req != null && req.Target.ID == i_player.ID) {
  308.             // Notify the partner about the rejected request
  309.             _Msg.Player(req.Invoker, @"%s %s rejected your team-up request.", MsgTag.Inf, i_player.Name);
  310.             // Increase the request counter
  311.             req_count++;
  312.             // Clear the request from the pool/list
  313.             _RequestPool[idx] = null;
  314.         }
  315.     }
  316.     // Notify the invoker about the rest of the requests
  317.     _Msg.Player(i_player, @"%s You successfully rejected the rest of the requests (%d).", MsgTag.Inf, req_count);
  318. }
  319.  
  320. // ------------------------------------------------------------------------------------------------
  321. _CMD.AcceptAny <- function(i_player, args)
  322. {
  323.     // An array to hold the indexes of the available requests
  324.     local requests = array(0);
  325.     // Find all the requests made to the invoker
  326.     foreach (idx, req in _RequestPool) {
  327.         // See if this is a valid request
  328.         if (req != null && req.Target.ID == i_player.ID) {
  329.             // Add the request index to the list
  330.             requests.push(idx);
  331.         }
  332.     }
  333.     // See if we have any requests made to this player
  334.     if (requests.len() <= 0) return _Msg.Player(i_player, @"%s, You don't have any team-up requests.", MsgTag.Inf);
  335.     // See if we have only one request
  336.     else if (requests.len() == 1) return _CMD.AcceptReq(i_player, _RequestPool[requests[0]].Invoker.Name);
  337.     // Set the seed for the random number generator
  338.     srand(time());
  339.     // Make the seed even more random for small ranges
  340.     srand(time() % ((time() / rand()) % rand()));
  341.     // Get a random index from the list
  342.     local rnum = rand() % requests.len();
  343.     // Accept the request of the partner located at the generated index
  344.     _CMD.AcceptReq(i_player, _RequestPool[requests[rnum]].Invoker.Name);
  345. }
  346.  
  347. // ------------------------------------------------------------------------------------------------
  348. _CMD.FlushReq <- function(i_player, args)
  349. {
  350.     // See if there's a request in the pool/list
  351.     if (_RequestPool[i_player.ID] != null) {
  352.         // Inform the invoker about his action
  353.         _Msg.Player(i_player, @"%s You revoked your team-up request to:  %s", MsgTag.Scs, _RequestPool[i_player.ID].Target.Name);
  354.         // Send a notice to the target
  355.         _Msg.Player(_RequestPool[i_player.ID].Target, @"%s %s revoked his team-up request.", MsgTag.Inf, i_player.Name);
  356.         // Flush the request
  357.         _RequestPool[i_player.ID] = null;
  358.     // Notify the invoker that there is no previous request
  359.     } else _Msg.Player(i_player, @"%s You don't have any team-up request.", MsgTag.Wrn);
  360. }
  361.  
  362. // ------------------------------------------------------------------------------------------------
  363. _CMD.PlaySolo <- function(i_player, args)
  364. {
  365.     // See if the invoker isn't in a team already
  366.     if (_ClientPool[i_player.ID].Partner != null) return _Msg.Player(i_player, @"%s You need to split-up from %x", MsgTag.Wrn, _ClientPool[i_player.ID].Partner.Name);
  367.     // See if the invoker has this option enabled or not
  368.     if (_ClientPool[i_player.ID].PlaySolo) {
  369.         // Deactivate the play solo option
  370.         _ClientPool[i_player.ID].PlaySolo = false;
  371.         // Notify the invoker about his action
  372.         _Msg.Player(i_player, @"%s You successfully deactivated the play solo option.", MsgTag.Scs);
  373.     } else {
  374.         // Activate the play solo option
  375.         _ClientPool[i_player.ID].PlaySolo = true;
  376.         // Notify the invoker about his action
  377.         _Msg.Player(i_player, @"%s You successfully activated the play solo option.", MsgTag.Scs);
  378.     }
  379. }
  380.  
  381. // ------------------------------------------------------------------------------------------------
  382. _CMD.Partner <- function(i_player, args)
  383. {
  384.     // See if the invoker has a partner or not
  385.     if (_ClientPool[i_player.ID].Partner != null) {
  386.         // Inform the invoker about his partner
  387.         _Msg.Player(i_player, @"%s Your partner is %s", MsgTag.Inf, _ClientPool[i_player.ID].Partner.Name);
  388.     // Notify the invoker that he doesn't have a partner
  389.     } else _Msg.Player(i_player, @"%s You don't have a partner.", MsgTag.Wrn);
  390. }
  391.  
  392. // ------------------------------------------------------------------------------------------------
  393. // Processes all the active team-up requests
  394. function _RequestProcess()
  395. {
  396.     // Get the current time
  397.     local cur_time = time();
  398.     // Loop through all the queued requests
  399.     foreach (idx, req in _RequestPool) {
  400.         // See if this is a valid request
  401.         if (req != null && req.Timeout <= cur_time) {
  402.             // Notify the invoker about the expired request
  403.             _Msg.Player(req.Invoker, @"%s Your team-up request to %s has expired.", MsgTag.Inf, req.Target.Name);
  404.             // Clear the request from the pool/list
  405.             _RequestPool[idx] = null;
  406.         }
  407.     }
  408. }
  409.  
  410. // ------------------------------------------------------------------------------------------------
  411. function onServerStart()
  412. {
  413.     // Reserve enough space to hold the maximum number of Clients that the server can hold
  414.     _ClientPool = array(GetMaxPlayers());
  415.     // Reserve enough space to hold the maximum number of Clients that the server can hold
  416.     _RequestPool = array(GetMaxPlayers());
  417.     // Attempt to find any previously connected Clients in case of a script reload
  418.     foreach (idx, inst in _ClientPool) {
  419.         // Attempt to find the player by it's unique identifier
  420.         local res = FindPlayer(idx);
  421.         // See if a valid player instance was found at this ID
  422.         if (res != null) {
  423.             // Create a Client instance for this player instance
  424.             inst = _Client(res);
  425.             // Allow the Client instance to initialize
  426.             inst.Connect();
  427.         }
  428.     }
  429.     // Start the request cleaning timer
  430.     NewTimer("_RequestProcess", 5000, 0);
  431. }
  432.  
  433. // ------------------------------------------------------------------------------------------------
  434. function onServerStop()
  435. {
  436.     // Attempt to de-initialize all connected players from the server
  437.     foreach (inst in _ClientPool) {
  438.         // See if there was any Client instance in this slot
  439.         if (inst != null) {
  440.             // Allow the Client instance to de-initialize
  441.             inst.Disconnect();
  442.             // Clear the slot
  443.             _ClientPool[i_player.ID] = null;
  444.         }
  445.     }
  446.     // Clear all the team-up requests
  447.     foreach (idx, req in _RequestPool) _RequestPool[idx] = null;
  448. }
  449.  
  450. // ------------------------------------------------------------------------------------------------
  451. function onPlayerJoin(i_player)
  452. {
  453.     // Create a Client instance for this player instance
  454.     _ClientPool[i_player.ID] = _Client(i_player);
  455.     // Allow the newly created Client instance to initialize
  456.     _ClientPool[i_player.ID].Connect();
  457. }
  458.  
  459. // ------------------------------------------------------------------------------------------------
  460. function onPlayerPart(i_player, reason)
  461. {
  462.     // Allow the Client instance to de-initialize
  463.     _ClientPool[i_player.ID].Disconnect();
  464.     // Clear the slot for other Clients
  465.     _ClientPool[i_player.ID] = null;
  466. }
  467.  
  468. // ------------------------------------------------------------------------------------------------
  469. function onPlayerCommand(i_player, cmd, args)
  470. {
  471.     switch (cmd)
  472.     {
  473.         // ----------------------------------------------------------------------------------------
  474.         case "teamup":      _CMD.TeamUp(i_player, args); break;
  475.         case "splitup":     _CMD.SplitUp(i_player, args); break;
  476.         // ----------------------------------------------------------------------------------------
  477.         case "denyreq":     _CMD.DenyReq(i_player, args); break;
  478.         case "denyall":     _CMD.DenyAll(i_player, args); break;
  479.         // ----------------------------------------------------------------------------------------
  480.         case "acceptreq":   _CMD.AcceptReq(i_player, args); break;
  481.         case "acceptany":   _CMD.AcceptAny(i_player, args); break;
  482.         // ----------------------------------------------------------------------------------------
  483.         case "flushreq":    _CMD.FlushReq(i_player, args); break;
  484.         case "playsolo":    _CMD.PlaySolo(i_player, args); break;
  485.         case "partner":     _CMD.Partner(i_player, args); break;
  486.         // ----------------------------------------------------------------------------------------
  487.         default: _Msg.Player(i_player, "%s Unknown command: %s %s", MsgTag.Err, cmd, args);
  488.     }
  489. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement