Advertisement
HR_Shaft

Team Auto-Balance and Team Shuffle for Phasor v2+

Nov 17th, 2014
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.35 KB | None | 0 0
  1. --[[ ###  Team Auto-Balance and Team Shuffle  ###]]--
  2. --[[ ###       by H® Shaft for Phasor v2+     ###]]--
  3.  
  4. -- autobalances teams during team games if there are 4 or more players
  5. -- occurs automatically on player leave and join
  6. -- any player may type 'balance' to balance the teams if not willing to wait.
  7. -- any admin may type 'shuffle' to shuffle or mix the teams.
  8.  
  9. -- edit --
  10. autobal_delay = 15  --| Time in seconds to delay balancing teams during the game and when players join or leave
  11.                     --| you should not go lower than 10 seconds, to allow admins to switch players manually if they choose
  12.  
  13. -- don't edit --
  14. cur_players = 0
  15. team_change = {}
  16. team_shuffle = {}
  17. team_play = false
  18. game_started = false
  19. game_autobal = nil
  20. map_reset = false
  21.  
  22. function GetRequiredVersion()
  23.     return 200
  24. end
  25.  
  26. function OnScriptLoad(process, game, persistent)
  27.     if game == "PC" then
  28.         gametype_base = 0x671340
  29.         network_base = 0x745BA8
  30.     else
  31.         gametype_base = 0x5F5498
  32.         network_base = 0x6C7988
  33.     end
  34.    
  35.     GAME = game
  36.     team_play = getteamplay()
  37.     cur_players = readword(network_base, 0x1A0)
  38.     ScriptLoad()
  39.    
  40.     if not game_started and cur_players > 0 then game_started = true end
  41.    
  42.     if team_play and game_autobal == nil then
  43.         game_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  44.     end
  45.    
  46. end
  47.  
  48. function ScriptLoad()
  49.     if map_reset == true then
  50.         map_reset = false
  51.         team_play = getteamplay()
  52.        
  53.         for i = 0,15 do
  54.             if getplayer(i) then   
  55.                 cur_players = cur_players + 1
  56.                 team_change[i] = false
  57.                 team_shuffle[i] = false
  58.             end
  59.         end
  60.        
  61.         if not game_started and cur_players > 0 then game_started = true end   
  62.        
  63.         if team_play and game_autobal == nil then
  64.             game_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  65.         end
  66.     end
  67. end
  68.  
  69. function OnNewGame(map)
  70.     if game == "PC" or GAME == "PC" then
  71.         gametype_base = 0x671340
  72.         network_base = 0x745BA8
  73.     else
  74.         gametype_base = 0x5F5498
  75.         network_base = 0x6C7988
  76.     end
  77.    
  78.     team_play = getteamplay()
  79.     cur_players = readword(network_base, 0x1A0)
  80.     game_started = true
  81.    
  82.     if not game_started and cur_players > 0 then game_started = true end
  83.    
  84.     if team_play and game_autobal == nil then
  85.         game_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  86.     end    
  87. end
  88.  
  89. function OnPlayerJoin(player)
  90.     if getplayer(player) then
  91.         cur_players = cur_players + 1
  92.         team_change[player] = false
  93.         team_shuffle[player] = false
  94.         if game_started and team_play and cur_players > 3 then
  95.             join_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  96.         end
  97.         if team_play and cur_players > 3 and game_autobal == nil then
  98.             game_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  99.         end    
  100.     end
  101. end
  102.  
  103. function OnPlayerLeave(player)
  104.     if getplayer(player) then
  105.         cur_players = cur_players - 1
  106.         team_change[player] = {}
  107.         team_shuffle[player] = {}
  108.         if game_started and team_play and cur_players > 3 then
  109.             leave_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  110.         end    
  111.         if team_play and cur_players < 4 and game_autobal then
  112.             game_autobal = nil
  113.         elseif team_play and cur_players > 3 and game_autobal == nil then  
  114.             game_autobal = registertimer(autobal_delay * 1000, "AutoBalance")
  115.         end            
  116.     end
  117. end
  118.  
  119. function getteamplay()
  120.     if readbyte(gametype_base + 0x34) == 1 then
  121.         return true
  122.     else
  123.         return false
  124.     end
  125. end
  126.  
  127. function OnServerChat(player, type, message)
  128.     local response = nil
  129.     if player then 
  130.         if string.lower(message) == "balance" then
  131.             Balance_Teams()
  132.             response = false           
  133.         end
  134.         if string.lower(message) == "shuffle" then
  135.             response = false
  136.             if team_play then
  137.                 if cur_players > 3 then
  138.                     if isadmin(player) then
  139.                         for i=0,15 do
  140.                             if getplayer(i) then
  141.                                 privatesay(i, "Shuffling teams.")
  142.                                 local id = resolveplayer(i)
  143.                                 if getteam(i) == 0 then
  144.                                     svcmd("sv_changeteam " .. id)
  145.                                     team_shuffle[i] = true
  146.                                     team_change[i] = false
  147.                                     if TeamsAreUneven() then Balance_Teams() end   
  148.                                 end
  149.                                 if getteam(i) == 0 then
  150.                                     svcmd("sv_changeteam " .. id)
  151.                                     team_shuffle[i] = true
  152.                                     team_change[i] = false
  153.                                     if TeamsAreUneven() then Balance_Teams() end   
  154.                                 end                            
  155.                                 sendconsoletext(player, "Team shuffle completed.")
  156.                                 log_msg(1, getname(player) .. " used the shuffle teams command.")
  157.                             end
  158.                         end
  159.                     else
  160.                         response = true
  161.                         sendconsoletext(player, "You're not an admin. Logging attempt.")
  162.                         log_msg(1, getname(player) .. " attempted use of the shuffle command.")
  163.                     end
  164.                 else
  165.                     sendconsoletext(player, "Must have 4 or more players to shuffle teams.")
  166.                 end
  167.             else
  168.                 sendconsoletext(player, "You cannot shuffle during FFA games.")
  169.             end    
  170.             return response
  171.         end        
  172.     end
  173.     return response
  174. end    
  175.  
  176. function OnPlayerKill(killer, victim, mode)
  177.     local response = nil
  178.    
  179.     if game_started then
  180.         if mode == 1 then -- player was killed by falling or team-change
  181.             if getplayer(victim) then
  182.                 if team_shuffle[victim] and not team_change[victim] then
  183.                     response = false -- player was shuffled, don't show death message  
  184.                     team_shuffle[victim] = false   
  185.                 elseif not team_change[victim] and not team_shuffle[victim] then
  186.                     response = true  -- player fell and died, show death message
  187.                 else
  188.                     team_change[victim] = false
  189.                     response = false -- player changed teams, don't show death message             
  190.                 end
  191.             end
  192.         end
  193.     end
  194.    
  195.     return response
  196. end
  197.  
  198. function AutoBalance(id, count)
  199.     if game_started and team_play and cur_players > 3 then
  200.         Balance_Teams()
  201.         if join_autobal then join_autobal = nil end
  202.         if leave_autobal then leave_autobal = nil end
  203.         return true
  204.     elseif game_started and team_play and cur_players < 4 then 
  205.         return false
  206.     else
  207.         return false
  208.     end
  209. end
  210.  
  211. -- inspired by 002's team balance for Sapp
  212. function Balance_Teams()
  213.     if game_started and team_play then
  214.         local redteam = getteamsize(0)
  215.         local blueteam = getteamsize(1)
  216.         if redteam > blueteam then
  217.             while TeamsAreUneven() do
  218.                 while (getteamsize(0) > getteamsize(1)+1) do
  219.                     local randomred = SelectPlayer(0)
  220.                     if randomred ~= nil then
  221.                         changeteam(randomred, true)
  222.                     end
  223.                 end
  224.             end
  225.         elseif blueteam > redteam then
  226.             while TeamsAreUneven() do
  227.                 while (getteamsize(1) > getteamsize(0)+1) do
  228.                     local randomblu = SelectPlayer(1)
  229.                     if randomblu ~= nil then                           
  230.                         changeteam(randomblu, true)
  231.                     end
  232.                 end
  233.             end    
  234.         end
  235.     end
  236. end
  237.  
  238. -- inspired by 002's team balance for Sapp
  239. function TeamsAreUneven()
  240.     local red = getteamsize(0)
  241.     local blue = getteamsize(1)
  242.     if (red > blue + 1 or blue > red + 1) then return true end
  243.     return false
  244. end
  245.  
  246. function SelectPlayer(team)
  247.     local t = {}
  248.     for i=0,15 do
  249.         if getplayer(i) and getteam(i) == team then
  250.             table.insert(t, i)
  251.         end
  252.     end
  253.     if #t > 0 then
  254.         local r = getrandomnumber(1, #t+1)
  255.         return t[r]
  256.     end
  257.     return nil
  258. end
  259.  
  260. function OnTeamChange(player, old_team, new_team, relevant)
  261.     -- prevent unbalancing teams by team change
  262.     local response = nil
  263.     if getplayer(player) then
  264.    
  265.         local newteam = "New Team"
  266.         local oldteam = "Old Team"
  267.        
  268.         if not team_play then response = false return response end
  269.        
  270.         if new_team == 0 then
  271.             newteam = "Red Team"       
  272.         elseif new_team == 1 then
  273.             newteam = "Blue Team"      
  274.         end        
  275.        
  276.         if relevant == true or relevant == 1 then
  277.             if getteamsize(old_team) == getteamsize(new_team) then
  278.                 privatesay(player, "You cannot change teams.")
  279.                 response = false
  280.             elseif getteamsize(old_team) + 1 == getteamsize(new_team) then
  281.                 privatesay(player, "You cannot change teams.")
  282.                 response = false
  283.             elseif getteamsize(old_team) == getteamsize(new_team) + 1 then
  284.                 privatesay(player, "You cannot change teams.")
  285.                 response = false
  286.             elseif getteamsize(old_team) > getteamsize(new_team) then
  287.                 team_change[player] = true
  288.                 say(getname(player) .. " switched to the "  .. newteam)
  289.                 response = true
  290.             elseif getteamsize(old_team) < getteamsize(new_team) then
  291.                 team_change[player] = true
  292.                 say(getname(player) .. " switched to the "  .. newteam)
  293.                 response = true
  294.             end
  295.         elseif relevant == false or relevant == 0 then
  296.             if team_shuffle[player] then
  297.                 say(getname(player) .. " was team-shuffled to mix the teams.")
  298.                 team_shuffle[player] = false
  299.                 response = true
  300.             else
  301.                 team_change[player] = true
  302.                 say(getname(player) .. " was team-switched to balance the teams.")
  303.                 response = true
  304.             end
  305.         end
  306.        
  307.     end
  308.    
  309.     return response
  310. end
  311.  
  312. function OnServerCommand(player, command)
  313.     local allow = nil
  314.     local cmd = tokenizecmdstring(command)
  315.     local tokencount = #cmd
  316.     if tokencount > 0 then
  317.    
  318.         if cmd[1] == "sv_map_reset" then
  319.             map_reset = true       
  320.             ScriptLoad()                   
  321.             allow = true
  322.            
  323.         elseif cmd[1] == "sv_script_reload" then
  324.             map_reset = true
  325.             ScriptLoad()       
  326.             allow = true
  327.         end
  328.        
  329.     end
  330.     return allow
  331. end
  332.  
  333. function OnGameEnd(stage)
  334.     if stage == 1 then
  335.         game_started = false
  336.         if game_autobal then
  337.             game_autobal = nil
  338.         end
  339.         if join_autobal then
  340.             join_autobal = nil
  341.         end
  342.         if leave_autobal then
  343.             leave_autobal = nil
  344.         end    
  345.     end
  346. end
  347.  
  348. --[[ Created by H® Shaft.
  349. Thanks to Oxide, AelitePrime, Nugget & Wizard -- and 002
  350. Visit http://halorace.org/forum/index.php?topic=514.0 or
  351. Visit http://pastebin.com/u/HR_Shaft for more phasor scripts
  352. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement