Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Team Balance Plus v1.1 by H® Shaft 7/23/2016 -- corrected 2 logical errors which affected delays
- -- a variant version of 002's team balancer with new and re-witten functions, and modified
- -- When teams have been unbalanced for 5 seconds, it will warn players that teams are unbalanced, then
- -- the next player to die on the bigger team will change teams, OR
- -- if no player switches or dies and the auto balance timer (editable time) expires, randomly selected members of bigger team will be switched, OR
- -- If players manually switch teams - via the lobby, they will not get a death, and will respawn instantly, OR
- -- If players volunteer to switch by typing "switch", they will not get a death, and will respawn instantly - AND keep their score, OR
- -- the next player on the bigger team who kills a smaller team member will change teams, OR
- -- the next player to suicide or betray will switch teams, but they keep their score, OR
- -- when the following commands are used:
- -- type "switch" allow players to volunteer to switch teams (if they are on the bigger team) [any player]
- -- type "balance" to balance teams immediately [admin only]
- -- type "swap" to swap current admin with random player on opposite team [admin only]
- -- type "shuffle" to shuffle teams games (is not automatic) [admin only]
- -- * re-wrote switch for betrayals and suicide (sometimes caused server exception), and added additional functions
- -- incorporated a portion of shuffler script written by 002
- -- === NOTE === gametypes should have >> Team Play Options >> Auto Team Balance set to YES for best results - (but is not required)
- -- Player switched message
- -- Variables: $PLAYER for the player, $TEAM for destination team
- PLAYER_SWITCHED = "$PLAYER switched to the $TEAM team!"
- -- Number of seconds before teams will be auto-balanced if teams are still uneven after message a and b have been displayed
- AUTO_BAL_DELAY = 60
- -- Number of seconds for the teams to be unbalanced to display message A then wait til AUTO_BAL_DELAY time expires, then show B.
- TEAMS_ARE_UNBALANCED_DELAY = 5
- -- Teams are unbalanced message A - notification that teams are unbalanced
- -- Variables: $TEAM_SMALL = the name of the smaller team. $TEAM_BIG = the name of the bigger team.
- TEAMS_ARE_UNBALANCED_A = "Teams are Unbalanced: The next to die on $TEAM_BIG team will be switched to $TEAM_SMALL team."
- -- Teams are unbalanced message B - notification when auto-balance will begin if teams are still unbalanced
- -- Variables: $TEAM_SMALL = the name of the smaller team. $TEAM_BIG = the name of the bigger team.
- TEAMS_ARE_UNBALANCED_B = "Random $TEAM_BIG team player selection begins in " .. TEAMS_ARE_UNBALANCED_DELAY .. " seconds."
- -- End of configuration
- api_version = "1.8.0.0"
- delay = nil
- warning_a_shown = false
- warning_b_shown = false
- killed_by_nothing = {}
- function OnScriptLoad()
- register_callback(cb['EVENT_TICK'],"OnTick")
- register_callback(cb['EVENT_TEAM_SWITCH'],"OnTeamSwitch")
- register_callback(cb['EVENT_DIE'],"OnPlayerDie")
- register_callback(cb['EVENT_PRESPAWN'],"OnPlayerPreSpawn")
- register_callback(cb['EVENT_CHAT'], "OnPlayerChat")
- register_callback(cb['EVENT_GAME_START'],"OnNewGame")
- register_callback(cb['EVENT_GAME_END'], "OnGameEnd")
- if get_var(0, "$gt") ~= "n/a" then
- game_started = true
- team_play = getteamplay()
- for i=1,16 do
- if player_alive(i) then
- killed_by_nothing[i] = false
- end
- end
- end
- end
- function OnScriptUnload()
- killed_by_nothing = {}
- switchplayertimer = nil
- gametimer = nil
- autobalancetimer = nil
- manualbalancetimer = nil
- balancenow = nil
- end
- function OnNewGame()
- gametimer = timer(5000, "GameTimer")
- end
- function GameTimer()
- game_started = true
- team_play = getteamplay()
- if team_play then
- for i=1,16 do
- if player_alive(i) then
- killed_by_nothing[i] = false
- end
- end
- end
- return false
- end
- function AutoBalanceTimer()
- if TeamsAreUneven() then
- balancenow = timer(800, "BalanceNow")
- end
- return false
- end
- function OnGameEnd()
- game_started = false
- gametimer = nil
- team_play = getteamplay()
- killed_by_nothing = {}
- end
- function OnPlayerChat(PlayerIndex, Message)
- local response = nil
- if Message == nil then
- return true
- end
- local Message = string.lower(Message)
- if Message ~= nil then
- -- balance teams
- if (Message == "balance") then
- response = false
- if team_play then
- if tonumber(get_var(PlayerIndex,"$lvl")) > 0 then
- if tonumber(get_var(0,"$pn")) >= 2 then
- manualbalancetimer = timer(500, "AutoBalanceTimer")
- else
- say(PlayerIndex, "**TEAM-BALANCE** You must have 2 or more players to balance the teams.")
- end
- else
- say(PlayerIndex, "**ADMIN ONLY** You are not an admin, thanks anyway.")
- end
- else
- say(PlayerIndex, "**TEAM-BALANCE** This command is disabled during FFA games.")
- end
- -- swap current admin with random player on opposite team
- elseif (Message == "swap") or (Message == "/swap") then
- response = false
- if team_play then
- if tonumber(get_var(PlayerIndex,"$lvl")) > 0 then
- local opp_team = get_var(PlayerIndex,"$oteam")
- local opp_team_count = nil
- local reds = tonumber(get_var(0,"$reds"))
- local blues = tonumber(get_var(0,"$blues"))
- if opp_team == "red" then
- opp_team_count = reds
- elseif opp_team == "blue" then
- opp_team_count = blues
- end
- if opp_team_count > 0 then
- execute_command("st rand" .. opp_team)
- switchplayertimer = timer(1500, "SwitchPlayer", PlayerIndex)
- else
- say(PlayerIndex, "**SWAP** No players to swap with on " .. opp_team .. " team.")
- end
- end
- else
- say(PlayerIndex, "**SWAP** You can only use SWAP on team games.")
- end
- elseif (Message == "shuffle") or (Message == "/shuffle") then
- response = false
- if team_play then
- if tonumber(get_var(0,"$pn")) >= 2 then
- say_all("... shuffling teams ...")
- ShuffleTeams()
- else
- say(PlayerIndex, "**SHUFFLE** You can only use SHUFFLE with 2 or more players.")
- end
- else
- say(PlayerIndex, "**SHUFFLE** You can only use SHUFFLE on team games.")
- end
- elseif (Message == "switch") or (Message == "/switch") then
- response = false
- if team_play then
- if TeamsAreUneven() then
- if warning_a_shown then
- local reds = tonumber(get_var(1,"$reds"))
- local blues = tonumber(get_var(1,"$blues"))
- local bigger_team = nil
- if (reds > blues + 1) then
- bigger_team = "red"
- elseif (blues > reds + 1) then
- bigger_team = "blue"
- end
- if (get_var(PlayerIndex,"$team") == bigger_team) then
- switchplayertimer = timer(50, "SwitchPlayer", PlayerIndex)
- else
- say(PlayerIndex, "**SWITCH** You are NOT on the bigger team, you cannot switch.")
- end
- else
- say(PlayerIndex, "**SWITCH** You cannot switch teams at this time, sorry.")
- end
- else
- say(PlayerIndex, "**SWITCH** You can only switch when teams are uneven.")
- end
- else
- say(PlayerIndex, "**SWITCH** You can only switch during team games, when teams are uneven.")
- end
- end
- end
- return response
- end
- function SwitchPlayer(PlayerIndex)
- if (player_present(PlayerIndex) == false) then return end
- local opp_team = get_var(PlayerIndex,"$oteam")
- execute_command("st me " ..opp_team, PlayerIndex)
- say(PlayerIndex, "**TEAM-BALANCE** You were automatically team-switched!")
- return false
- end
- function BalanceNow()
- local reds = tonumber(get_var(0,"$reds"))
- local blues = tonumber(get_var(0,"$blues"))
- local bigger_team = nil
- while TeamsAreUneven() do
- if (reds > blues + 1) then
- bigger_team = "red"
- teams_uneven = true
- execute_command("st rand" .. bigger_team)
- elseif (blues > reds + 1) then
- bigger_team = "blue"
- teams_uneven = true
- execute_command("st rand" .. bigger_team)
- end
- if (reds == blues) or (reds == blues + 1) or (blues == reds + 1) then break end
- end
- teams_uneven = false
- autobalancetimer = nil
- manualbalancetimer = nil
- return false
- end
- function TeamsAreUneven()
- local red = tonumber(get_var(0,"$reds"))
- local blue = tonumber(get_var(0,"$blues"))
- if (red > blue + 1) or (blue > red + 1) then
- return true
- else
- return false
- end
- end
- function getteamplay()
- if get_var(0,"$ffa") == "0" then
- return true
- else
- return false
- end
- end
- function OnTick()
- if (team_play == true) then
- local reds = tonumber(get_var(1,"$reds"))
- local blues = tonumber(get_var(1,"$blues"))
- local bigger_team = nil
- local smaller_team = nil
- if (reds > blues + 1) then
- bigger_team = "red"
- smaller_team = "blue"
- elseif (blues > reds + 1) then
- bigger_team = "blue"
- smaller_team = "red"
- else
- delay = nil
- warning_a_shown = false
- warning_b_shown = false
- return
- end
- if (delay == nil) then delay = os.clock() + TEAMS_ARE_UNBALANCED_DELAY end
- if (os.clock() > delay and warning_a_shown == false) then
- say_all(string.gsub(string.gsub(TEAMS_ARE_UNBALANCED_A,"$TEAM_BIG",string.upper(bigger_team)),"$TEAM_SMALL",smaller_team))
- say_all(string.upper(bigger_team) .. " TEAM: Type \"SWITCH\" to voluntarily switch teams now AND keep your score.")
- warning_a_shown = true
- delay = os.clock() + AUTO_BAL_DELAY
- elseif (os.clock() > delay and warning_b_shown == false) then
- say_all(string.gsub(string.gsub(TEAMS_ARE_UNBALANCED_B,"$TEAM_BIG",string.upper(bigger_team)),"$TEAM_SMALL",smaller_team))
- warning_b_shown = true
- delay = os.clock() + TEAMS_ARE_UNBALANCED_DELAY
- elseif (os.clock() > delay and warning_b_shown == true) then
- autobalancetimer = timer(500, "AutoBalanceTimer")
- end
- end
- end
- function OnTeamSwitch(PlayerIndex)
- if (team_play == true) then
- if (killed_by_nothing[PlayerIndex] == true) then
- execute_command("deaths " .. PlayerIndex .. " -1")
- write_dword(get_player(PlayerIndex) + 0x2C, 0)
- killed_by_nothing[PlayerIndex] = nil
- end
- say_all(string.gsub(string.gsub(PLAYER_SWITCHED,"$TEAM",get_var(PlayerIndex,"$team")),"$PLAYER",get_var(PlayerIndex,"$name")))
- end
- end
- function OnPlayerPreSpawn(PlayerIndex)
- killed_by_nothing[PlayerIndex] = false
- end
- function OnPlayerDie(PlayerIndex, KillerIndex)
- if (team_play == true) then
- if (tonumber(KillerIndex) == -1) and warning_a_shown then
- killed_by_nothing[PlayerIndex] = true
- end
- -- determine if to proceed with balance checks
- if (warning_b_shown == false) then return end
- -- check team balances
- local reds = tonumber(get_var(1,"$reds"))
- local blues = tonumber(get_var(1,"$blues"))
- local bigger_team = nil
- local smaller_team = nil
- -- if killer or victim is on the bigger team, switch them to smaller team
- if (reds > blues + 1) then
- bigger_team = "red"
- smaller_team = "blue"
- -- if killer is a player (not server, not fall damage, not killed by vehicle, not team change)
- if (tonumber(KillerIndex) > 0) then
- -- betrayer on bigger team
- if get_var(PlayerIndex,"$team") == get_var(KillerIndex,"$team") then
- if (PlayerIndex ~= KillerIndex) then
- if (get_var(KillerIndex,"$team") == bigger_team) then
- if (player_present(KillerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", KillerIndex)
- end
- end
- end
- -- suicider on bigger team
- elseif get_var(PlayerIndex,"$team") == get_var(KillerIndex,"$team") then
- if (PlayerIndex == KillerIndex) then
- if (get_var(KillerIndex,"$team") == bigger_team) then
- if (player_present(PlayerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", PlayerIndex)
- end
- end
- end
- -- smaller team kills a bigger team member, switch victim
- elseif (get_var(KillerIndex,"$team") == smaller_team) and (get_var(PlayerIndex,"$team") == bigger_team) then
- if (player_present(PlayerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", PlayerIndex)
- end
- -- bigger team kills a smaller team member, switch killer
- elseif (get_var(KillerIndex,"$team") == bigger_team) and (get_var(PlayerIndex,"$team") == smaller_team) then
- if (player_present(KillerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", KillerIndex)
- end
- end
- end
- elseif (blues > reds + 1) then
- bigger_team = "blue"
- smaller_team = "red"
- -- if killer is a player (not server, not fall damage, not killed by vehicle, not team change)
- if (tonumber(KillerIndex) > 0) then
- -- betrayer on bigger team
- if get_var(PlayerIndex,"$team") == get_var(KillerIndex,"$team") then
- if (PlayerIndex ~= KillerIndex) then
- if (get_var(KillerIndex,"$team") == bigger_team) then
- if (player_present(KillerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", KillerIndex)
- end
- end
- end
- -- suicider on bigger team
- elseif get_var(PlayerIndex,"$team") == get_var(KillerIndex,"$team") then
- if (PlayerIndex == KillerIndex) then
- if (get_var(KillerIndex,"$team") == bigger_team) then
- if (player_present(PlayerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", PlayerIndex)
- end
- end
- end
- -- smaller team kills a bigger team member, switch victim
- elseif (get_var(KillerIndex,"$team") == smaller_team) and (get_var(PlayerIndex,"$team") == bigger_team) then
- if (player_present(PlayerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", PlayerIndex)
- end
- -- bigger team kills a smaller team member, switch killer
- elseif (get_var(KillerIndex,"$team") == bigger_team) and (get_var(PlayerIndex,"$team") == smaller_team) then
- if (player_present(KillerIndex) == true) then
- switchplayertimer = timer(1500, "SwitchPlayer", KillerIndex)
- end
- end
- end
- else
- return
- end
- end
- end
- function ShuffleTeams() -- written by 002
- if(get_var(1,"$ffa") == "1") then return end
- local players = {}
- for i=1,16 do
- if(player_present(i)) then
- local player = get_player(i)
- local old_value = read_word(player + 0xD4)
- if(player_alive(i) == true) then
- write_word(player + 0xD4, 0xFFFF)
- kill(i)
- write_word(player + 0xD4, old_value)
- write_word(player + 0xAE, read_word(player + 0xAE) - 1)
- end
- players[table.getn(players) + 1] = i
- write_dword(player + 0x2C, 0)
- execute_command("st " .. i .. " red")
- end
- end
- local players_count = table.getn(players)
- while true do
- local red = tonumber(get_var(1,"$reds"))
- local blue = tonumber(get_var(1,"$blues"))
- if (red > blue + 1) then
- while true do
- local i = players[rand(1,players_count+1)]
- local player = get_player(i)
- if (read_word(player + 0x20) == 0) then
- execute_command("st " .. i .. " blue")
- break
- end
- end
- else
- break
- end
- end
- say_all("Teams have been shuffled.")
- end
- function OnError(Message)
- print(debug.traceback())
- end
- -- Created by H® Shaft (Holy Phuckeroo! - this was a lot of work!)
- -- Visit http://halorace.org
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement