Advertisement
slc_world

VC:MP HealingSystem

Oct 31st, 2014
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 8.10 KB | None | 0 0
  1. // VC:MP HealingSystem
  2.  
  3. // ------------------------------------------------------------------------------------------------
  4. // Global table used to scope base configurations
  5. _CFG <- {}
  6. // Global table used to scope script commands
  7. _CMD <- {}
  8.  
  9. // ------------------------------------------------------------------------------------------------
  10. // Global enumeration to hold the command syntax
  11. enum CmdSyn
  12. {
  13.     HealMe = "healme"
  14. }
  15.  
  16. // ------------------------------------------------------------------------------------------------
  17. // Global enumeration to hold the message style and colours
  18. enum MsgTag {
  19.     Dbg = "[#11455D][DEBUG][#F4F3EE]",
  20.     Msg = "[#64A5BB][MESSAGE][#F4F3EE]",
  21.     Scs = "[#698433][SUCCESS][#F4F3EE]",
  22.     Inf = "[#FFD35C][INFO][#F4F3EE]",
  23.     Wrn = "[#FF8202][WARNING][#F4F3EE]",
  24.     Err = "[#EA3E70][ERROR][#F4F3EE]",
  25.     Ftl = "[#C82C3A][FATAL][#F4F3EE]"
  26. }
  27.  
  28. // ------------------------------------------------------------------------------------------------
  29. // Cost of normal heal command
  30. _CFG.Heal_Cost <- 1000;
  31. // The actual amount of health to set
  32. _CFG.Heal_Amount <- 100;
  33. // Number of milliseconds to delay the healing process
  34. _CFG.Heal_Delay <- 2000;
  35. // Number of milliseconds to wait before waking up the coroutines
  36. _CFG.Heal_Speed <- 50;
  37.  
  38. // ------------------------------------------------------------------------------------------------
  39. // Scoped functions used to send formatted messages to players
  40. _Msg <- {
  41.     // --------------------------------------------------------------------------------------------
  42.     function Player(...)
  43.     {
  44.         // Grab the player instance from the first argument
  45.         local i_player = vargv[0];
  46.         // Replace the player instance with the (this) environment
  47.         vargv[0] = this;
  48.         // Forward all the arguments to the format function
  49.         local str = ::format.acall(vargv);
  50.         // Send the generated message to the specified player
  51.         MessagePlayer(str, i_player);
  52.     }
  53. }
  54.  
  55. // ------------------------------------------------------------------------------------------------
  56. _ClientPool <- []
  57.  
  58. // ------------------------------------------------------------------------------------------------
  59. _HealmePool <- []
  60.  
  61. // ------------------------------------------------------------------------------------------------
  62. // Class responsible for management and identification of player instances
  63. class _Client
  64. {
  65.     // --------------------------------------------------------------------------------------------
  66.     function constructor(i_player)
  67.     {
  68.         // Verify the player instance
  69.         if (typeof i_player != "instance") return null;
  70.         // Store the player instance
  71.         else Instance = i_player
  72.     }
  73.     // --------------------------------------------------------------------------------------------
  74.     function Connect()
  75.     {
  76.         // Ignored....
  77.     }
  78.     // --------------------------------------------------------------------------------------------
  79.     function Disconnect(reason)
  80.     {
  81.         // See if there's any active healing processes made by this instance remove it
  82.         if (_HealmePool[Instance.ID] != null) _HealmePool[Instance.ID] = null;
  83.         // Clear any stored instances
  84.         Instance = null;
  85.     }
  86.     // --------------------------------------------------------------------------------------------
  87.     Instance = null
  88. }
  89.  
  90. // ------------------------------------------------------------------------------------------------
  91. // The actual coroutine that increases the player health progressively
  92. function _HealmeCoroutine(i_player, amount, limit, delay)
  93. {
  94.     // Suspend the coroutine while the delay is in effect
  95.     while (delay > 0) delay -= ::suspend();
  96.     // Start adding health points until we reach zero
  97.     while (amount--) {
  98.         // Increase the player health until the limit is reached
  99.         if (++i_player.Health >= limit) break;
  100.         // Suspend the coroutine
  101.         ::suspend();
  102.     }
  103. }
  104.  
  105. // ------------------------------------------------------------------------------------------------
  106. // Processes all the active healing coroutines
  107. function _HealmeUpdate()
  108. {
  109.     // Loop through all the active coroutines
  110.     foreach (idx, coro in _HealmePool) {
  111.         // See if the player at this index activated the healing process
  112.         if (coro != null) {
  113.             // Wake up the coroutine and pass the elapsed time
  114.             coro.wakeup(_CFG.Heal_Speed);
  115.             // Remove the coroutine if it's finished
  116.             if (coro.getstatus() != "suspended") _HealmePool[idx] = null;
  117.         }
  118.     }
  119. }
  120.  
  121. // ------------------------------------------------------------------------------------------------
  122. _CMD.HealMe <- function(i_player, args)
  123. {
  124.     // Make sure there isn't another healing process active
  125.     if (_HealmePool[i_player.ID] != null) return _Msg.Player(i_player, @"%s Please wait until the current healing process is finished.", MsgTag.Wrn);
  126.     // Make sure the invoker can afford the cost
  127.     else if (i_player.Money < _CFG.Heal_Cost) return _Msg.Player(i_player, @"%s You need $%d more to use the healing command.", MsgTag.Wrn, (_CFG.Heal_Cost - i_player.Money));
  128.     // Make sure the invoker actually needs healing
  129.     else if (i_player.Health >= _CFG.Heal_Amount) return _Msg.Player(i_player, @"%s You have more than enough health to use this command.", MsgTag.Wrn);
  130.  
  131.     // Create and store the coroutine to be continued on next update
  132.     _HealmePool[i_player.ID] = ::newthread(_HealmeCoroutine);
  133.     // Initiate the coroutine with the default arguments
  134.     _HealmePool[i_player.ID].call(i_player, _CFG.Heal_Amount, _CFG.Heal_Amount, _CFG.Heal_Delay);
  135.     // Get the payment for the healing process
  136.     i_player.Money -= _CFG.Heal_Cost;
  137.     // Notify the invoker about the result
  138.     _Msg.Player(i_player, @"%s You activated the healing process in exchange for $%d", MsgTag.Scs, _CFG.Heal_Cost);
  139. }
  140.  
  141. // ------------------------------------------------------------------------------------------------
  142. function onServerStart()
  143. {
  144.     // Reserve enough space to hold the maximum number of Clients that the server can hold
  145.     _ClientPool = array(GetMaxPlayers());
  146.     _HealmePool = array(GetMaxPlayers());
  147.     // Attempt to find any previously connected Clients in case of a script reload
  148.     foreach (idx, inst in _ClientPool) {
  149.         // Attempt to find the player by it's unique identifier
  150.         local res = FindPlayer(idx);
  151.         // See if a valid player instance was found at this ID
  152.         if (res != null) {
  153.             // Create a Client instance for this player instance
  154.             inst = _Client(res);
  155.             // Allow the Client instance to initialize
  156.             inst.Connect();
  157.         }
  158.     }
  159.     // Start the healing update timer
  160.     NewTimer("_HealmeUpdate", _CFG.Heal_Speed, 0);
  161. }
  162.  
  163. // ------------------------------------------------------------------------------------------------
  164. function onServerStop()
  165. {
  166.     // Attempt to de-initialize all connected players from the server
  167.     foreach (inst in _ClientPool) {
  168.         // See if there was any Client instance in this slot
  169.         if (inst != null) {
  170.             // Allow the Client instance to de-initialize
  171.             inst.Disconnect();
  172.             // Clear the slot
  173.             _ClientPool[i_player.ID] = null;
  174.         }
  175.     }
  176.     // Clear all the healing coroutines
  177.     foreach (idx, req in _HealmePool) _HealmePool[idx] = null;
  178. }
  179.  
  180. // ------------------------------------------------------------------------------------------------
  181. function onPlayerJoin(i_player)
  182. {
  183.     // Create a Client instance for this player instance
  184.     _ClientPool[i_player.ID] = _Client(i_player);
  185.     // Allow the newly created Client instance to initialize
  186.     _ClientPool[i_player.ID].Connect();
  187. }
  188.  
  189. // ------------------------------------------------------------------------------------------------
  190. function onPlayerPart(i_player, reason)
  191. {
  192.     // Allow the Client instance to de-initialize
  193.     _ClientPool[i_player.ID].Disconnect(reason);
  194.     // Clear the slot for other Clients
  195.     _ClientPool[i_player.ID] = null;
  196. }
  197.  
  198. // ------------------------------------------------------------------------------------------------
  199. function onPlayerCommand(i_player, cmd, args)
  200. {
  201.     switch (cmd)
  202.     {
  203.         // ----------------------------------------------------------------------------------------
  204.         case "healme":      _CMD.HealMe(i_player, args); break;
  205.         // ----------------------------------------------------------------------------------------
  206.         default: _Msg.Player(i_player, @"%s Unknown command: %s %s", MsgTag.Err, cmd, typeof args == "string" ? args : "");
  207.     }
  208. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement