ETMods.net

N!tmod, a Wolfenstein: Enemy Territory Modification!

You are not logged in.

Announcement

You can donate to help us keeping services online.

#1 15-Feb-25 15:46:10

Drago
Member
Registered: 07-May-23
Posts: 22

balance the teams

hello!
To balance the teams I use the following options in my server configuration:

bot minbots 0
bot maxbots 7
set g_teamForceBalance 1
set g_noTeamSwitching 1
set lua_modules "balance.lua"
set lua_allowedModules ""

This prevents players from switching from one team to another and therefore ensures a balance of the teams.
on the other hand it often happens that players disconnect during a game and this can seriously unbalance the teams (sometimes there can be 2 or 3 more players in a team).
I know that a lua file can solve this problem, but the one I found (Balance.lua) does not work. I put the script to you hoping that an expert can solve this problem for "nitmod".

Kind regards.

unevenDiff = 2
max_unevenTime = 20
max_unevenDiff = 4

axisPlayers = {}
alliedPlayers = {}
unevenTime = -1

function et_RunFrame( levelTime )
    local numAlliedPlayers = #alliedPlayers
    local numAxisPlayers = #axisPlayers
    if numAlliedPlayers >= numAxisPlayers + max_unevenDiff then
        local clientNum = alliedPlayers[ numAlliedPlayers ]
        et.trap_SendConsoleCommand( et.EXEC_APPEND, "put " .. clientNum .. " r ; qsay balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^1AXIS" )
    elseif numAxisPlayers >= numAlliedPlayers + max_unevenDiff then
        local clientNum = axisPlayers[ numAxisPlayers ]
        et.trap_SendConsoleCommand( et.EXEC_APPEND, "put " .. clientNum .. " b ; qsay balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^4ALLIES" )
    elseif numAlliedPlayers >= numAxisPlayers + unevenDiff then
        if unevenTime > 0 then
            if tonumber( levelTime ) - unevenTime >= max_unevenTime * 1000 then
                local clientNum = alliedPlayers[ numAlliedPlayers ]
                et.trap_SendConsoleCommand( et.EXEC_APPEND, "put " .. clientNum .. " r ; qsay balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^1AXIS" )
            end
        else
            unevenTime = tonumber( levelTime )
        end
    elseif numAxisPlayers >= numAlliedPlayers + unevenDiff then
        if unevenTime > 0 then
            if tonumber( levelTime ) - unevenTime >= max_unevenTime * 1000 then
                local clientNum = axisPlayers[ numAxisPlayers ]
                et.trap_SendConsoleCommand( et.EXEC_APPEND, "put " .. clientNum .. " b ; qsay balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^4ALLIES" )
            end
        else
            unevenTime = tonumber( levelTime )
        end
    else
        unevenTime = -1
    end
end

function et_ClientSpawn( clientNum, revived, teamChange, restoreHealth )
    if teamChange ~= 0 then
        local team = tonumber( et.gentity_get( clientNum, "sess.sessionTeam" ) )
        -- these were the teamnumbers prior to the move
        local numAlliedPlayers = #alliedPlayers
        local numAxisPlayers = #axisPlayers
        if team == 1 then
            for i, num in ipairs( alliedPlayers ) do
                if num == clientNum then
                    table.remove( alliedPlayers, i )
                    break
                end
            end
            -- this should not happen but still check for it to avoid doubles
            for i, num in ipairs( axisPlayers ) do
                if num == clientNum then
                    return
                end
            end
            -- make sure a player who (got) moved when teams were uneven doesnt get moved right back
            if numAlliedPlayers >= numAxisPlayers + unevenDiff then
                table.insert( axisPlayers, 1, clientNum )
            else
                table.insert( axisPlayers, clientNum )
            end
        elseif team == 2 then
            for i, num in ipairs( axisPlayers ) do
                if num == clientNum then
                    table.remove( axisPlayers, i )
                    break
                end
            end
            for i, num in ipairs( alliedPlayers ) do
                if num == clientNum then
                    return
                end
            end
            if numAxisPlayers >= numAlliedPlayers + unevenDiff then
                table.insert( alliedPlayers, 1, clientNum )
            else
                table.insert( alliedPlayers, clientNum )
            end
        else
            for i, num in ipairs( alliedPlayers ) do
                if num == clientNum then
                    table.remove( alliedPlayers, i )
                    return
                end
            end
            for i, num in ipairs( axisPlayers ) do
                if num == clientNum then
                    table.remove( axisPlayers, i )
                    return
                end
            end
        end
    end

Offline

#2 18-Feb-25 07:37:36

mazak
Member
From: Poland
Registered: 11-Jun-13
Posts: 39

Re: balance the teams

Use a script that has a disconnect function.
Example:

Lua 1

--[[ 

original script by .harald 		http://etpub.org/viewtopic.php?f=10&t=45
modified by Micha!

http://www.teammuppet.eu


Tested under etpub 1.0.0

Contact: 
Xfire: gore16


Note:
	true = on
	false = off

--]]---------------------------------------------------------------------------------
---------------------------------CONFIG START----------------------------------------
-------------------------------------------------------------------------------------

unevenDiff = 2
max_unevenTime = 30
max_unevenDiff = 4

putteam_cmd =					"!putteam"		--shrubbots !putteam command (called !put on some mods)

blockswitchteamautobalance = 	true		--block the client to switch back to other team after he got auto switched

useswitchaftertime =			true		--auto lift the switch team block after switchtime
switchtime =					180			--time needs to pass before the client is allowed to switch to other team again (in seconds)
											--60 = 1 minute, 120 = 2 minutes, 180 = 3 minutes, ...
											
execptputteam =					true		--don't include admin switch (putteam_cmd) in useswitchaftertime

-------------------------------------------------------------------------------------
--------------------------------END OF CONFIG----------------------------------------
-------------------------------------------------------------------------------------

Modname = 			"balance"
Version = 			"0.1"

axisPlayers = 		{}
alliedPlayers = 	{}
unevenTime = 		-1

AXIS = 				1
ALLIES = 			2
blockswitchteam = 	{}
noswitchback = 		{}
samplerate =		200
switchtime1 = 		(switchtime * 10)

-------//---------------------Start of functions----------------------------
function et_InitGame(levelTime,randomSeed,restart)
    et.G_Print("["..Modname.."] Version:"..Version.." Loaded\n")
    et.RegisterModname(Modname .. " " .. Version)
	
	maxclients = tonumber( et.trap_Cvar_Get( "sv_maxClients" ) )
	
	blocktimer = 1
	
	for cno = 0, (maxclients - 1) do
		blockswitchteam[cno] = false
		noswitchback[cno] = false
	end
	
end

function et_RunFrame( levelTime )
	local numAlliedPlayers = ( #alliedPlayers )
	local numAxisPlayers = ( #axisPlayers )
	if numAlliedPlayers >= numAxisPlayers + max_unevenDiff then
		local clientNum = alliedPlayers[ numAlliedPlayers ]
		et.trap_SendConsoleCommand( et.EXEC_APPEND, ""..putteam_cmd.." " .. clientNum .. " r ; qsay balancing teams... " .. playerName(clientNum) .. "^7 moved to ^1AXIS" )
	elseif numAxisPlayers >= numAlliedPlayers + max_unevenDiff then
		local clientNum = axisPlayers[ numAxisPlayers ]
		et.trap_SendConsoleCommand( et.EXEC_APPEND, ""..putteam_cmd.." " .. clientNum .. " b ; qsay balancing teams... " .. playerName(clientNum) .. "^7 moved to ^4ALLIES" )
	elseif numAlliedPlayers >= numAxisPlayers + unevenDiff then
		if unevenTime > 0 then
			if tonumber( levelTime ) - unevenTime >= max_unevenTime * 1000 then
				local clientNum = alliedPlayers[ numAlliedPlayers ]
				et.trap_SendConsoleCommand( et.EXEC_APPEND, ""..putteam_cmd.." " .. clientNum .. " r ; qsay balancing teams... " .. playerName(clientNum) .. "^7 moved to ^1AXIS" )
				if blockswitchteamautobalance then
					blockswitchteam[clientNum] = true
				end
			end
		else
			unevenTime = tonumber( levelTime )
		end
	elseif numAxisPlayers >= numAlliedPlayers + unevenDiff then
		if unevenTime > 0 then
			if tonumber( levelTime ) - unevenTime >= max_unevenTime * 1000 then
				local clientNum = axisPlayers[ numAxisPlayers ]
				et.trap_SendConsoleCommand( et.EXEC_APPEND, ""..putteam_cmd.." " .. clientNum .. " b ; qsay balancing teams... " .. playerName(clientNum) .. "^7 moved to ^4ALLIES" )
				if blockswitchteamautobalance then
					blockswitchteam[clientNum] = true
				end
			end
		else
			unevenTime = tonumber( levelTime )
		end
	else
		unevenTime = -1
	end
	
	-------//--------------------blocktimer----------------------------
	if math.mod(levelTime, samplerate) ~= 0 then return end
	if blocktimer > 0 then
		blocktimer = blocktimer + 1
	end
	if blocktimer == switchtime1 then
		blocktimer = 0 
	end
end

function et_ClientSpawn( clientNum, revived, teamChange, restoreHealth )
	if teamChange ~= 0 then
		local team = checkteam(clientNum)
		-- these were the teamnumbers prior to the move
		local numAlliedPlayers = ( #alliedPlayers )
		local numAxisPlayers = ( #axisPlayers )
		if team == AXIS then
			for i, num in ipairs( alliedPlayers ) do
				if num == clientNum then
					table.remove( alliedPlayers, i )
					break
				end
			end
			-- this should not happen but still check for it to avoid doubles
			for i, num in ipairs( axisPlayers ) do
				if num == clientNum then
					return
				end
			end
			-- make sure a player who (got) moved when teams were uneven doesn't get moved right back
			if numAlliedPlayers >= numAxisPlayers + unevenDiff then
				table.insert( axisPlayers, 1, clientNum )
			else
				table.insert( axisPlayers, clientNum )
			end
		elseif team == ALLIES then
			for i, num in ipairs( axisPlayers ) do
				if num == clientNum then
					table.remove( axisPlayers, i )
					break
				end
			end
			for i, num in ipairs( alliedPlayers ) do
				if num == clientNum then
					return
				end
			end
			if numAxisPlayers >= numAlliedPlayers + unevenDiff then
				table.insert( alliedPlayers, 1, clientNum )
			else
				table.insert( alliedPlayers, clientNum )
			end
		else
			for i, num in ipairs( alliedPlayers ) do
				if num == clientNum then
					table.remove( alliedPlayers, i )
					return
				end
			end
			for i, num in ipairs( axisPlayers ) do
				if num == clientNum then
					table.remove( axisPlayers, i )
					return
				end
			end
		end
	end
end

function et_ClientDisconnect( clientNum )
	for i, num in ipairs( alliedPlayers ) do
		if num == clientNum then
			table.remove( alliedPlayers, i )
			return
		end
	end
	for i, num in ipairs( axisPlayers ) do
		if num == clientNum then
			table.remove( axisPlayers, i )
			return
		end
	end
end

function et_ClientCommand(client, command)
    local cmd = string.lower(command)
    local argv1 = string.lower(et.trap_Argv(1))
	
	local byte = string.byte(argv1,1)
	
	-------//--------------------team switch block after !putteam----------------------------
	if argv1 == putteam_cmd and et.G_shrubbot_permission(client, "p") == 1 then
		if et.trap_Argv(2) then
			local getplayer = getPlayerId(et.trap_Argv(2))
			blockswitchteam[getplayer] = true
			if execptputteam then
				noswitchback[getplayer] = true
			end
		end
	end
	
	-------//--------------------team switch block after silent !putteam----------------------------
	if cmd == putteam_cmd and et.G_shrubbot_permission(client, "p") == 1 then
		if et.trap_Argv(1) then
			local getplayer = getPlayerId(et.trap_Argv(1))
			blockswitchteam[getplayer] = true
			if execptputteam then
				noswitchback[getplayer] = true
			end
		end
	end
	
	-------//--------------------team switch block----------------------------
	if cmd == "team" or cmd == "nextteam" then
		if string.len(argv1) > 1 then
			et.trap_SendServerCommand( client , "print \"Invalid team join command.\n\"" )
			return 1
		end
        if argv1 ~= "" and byte ~= 98 and byte ~= 114 and byte ~= 115 then 
			et.trap_SendServerCommand( client , "print \"Invalid team join command.\n\"" )
			return 1
		end
		if argv1 == "b" and blockswitchteam[client] then
			if checkteam(client) == ALLIES then return end
			if checkteam(client) == AXIS then 
				if useswitchaftertime and noswitchback[client] == false then
					if blocktimer > 0 then
						rblocktimer = math.floor((switchtime1 - blocktimer) /5)
						et.trap_SendServerCommand( client , "chat \"^3BADBALANCE^7: ^7You may not switch teams ^n(^z"..rblocktimer.." ^7seconds left^n)^7.\"" )
						return 1
					end
				else
					et.trap_SendServerCommand( client , "chat \"^3BADBALANCE^7: ^7You may not switch teams this round.\"" )
					return 1	
				end
			end		 
		end
		
		if argv1 == "r" and blockswitchteam[client] then
			if checkteam(client) == AXIS then return end
			if checkteam(client) == ALLIES then 
				if useswitchaftertime and noswitchback[client] == false then
					if blocktimer > 0 then
						rblocktimer = math.floor((switchtime1 - blocktimer) /5)
						et.trap_SendServerCommand( client , "chat \"^3BADBALANCE^7: ^7You may not switch teams ^n(^z"..rblocktimer.." ^7seconds left^n)^7.\"" )
						return 1
					end
				else
					et.trap_SendServerCommand( client , "chat \"^3BADBALANCE^7: ^7You may not switch teams this round.\"" )
					return 1	
				end	
			end	
		end
	end
end

--------------------------HELPER FUNCTIONS------------------------------------------------------------------

function playerName(id) -- return a player's name
  local name = et.Info_ValueForKey(et.trap_GetUserinfo(id), "name")
  if name == "" then
    return "*unknown*"
  end
  return name
end

function checkteam(client)
   local cs = et.trap_GetConfigstring(et.CS_PLAYERS + client)
	return tonumber(et.Info_ValueForKey(cs, "t"))
end

function getPlayerId(name, clientID)
    local i
    -- if it's nil, return nil and throw error
    if (name == "") then
        return
    end
    -- if it's a number, interpret as slot number
    local clientnum = tonumber(name)
    if clientnum then
        if (clientnum <= tonumber(et.trap_Cvar_Get("sv_maxclients"))) and et.gentity_get(clientnum,"inuse") then
            return clientnum
        else
            return
        end
    end
    for i=0,et.trap_Cvar_Get("sv_maxclients"),1 do
		playeri = et.Info_ValueForKey(et.trap_GetUserinfo(i), "name")
		--if playeri == nil or playeri == "" then return "unknown" end
        if playeri then
			-- exact match first
            if et.Q_CleanStr( playeri ) == et.Q_CleanStr( name ) then
                return i
			-- partial match
            elseif (string.find(string.lower(et.Q_CleanStr( playeri )), string.lower(et.Q_CleanStr( name )), 1, true)) then
                return i
            end
        end
    end
end

Lua 2

modname = "balance"
version = "0.1"

function et_InitGame(levelTime,randomSeed,restart)
	et.RegisterModname(modname .. " " .. version)
end

unevenDiff = 2
max_unevenTime = 30
max_unevenDiff = 4

axisPlayers = {}
alliedPlayers = {}
unevenTime = -1

function et_RunFrame( levelTime )
   local numAlliedPlayers = table.getn( alliedPlayers )
   local numAxisPlayers = table.getn( axisPlayers )
   if numAlliedPlayers >= numAxisPlayers + max_unevenDiff then
      local clientNum = alliedPlayers[ numAlliedPlayers ]
      et.trap_SendConsoleCommand( et.EXEC_APPEND, "ref putaxis " .. clientNum .. " r" )
	  et.trap_SendServerCommand(-1, "chat \"balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^1AXIS\"" ) 
   elseif numAxisPlayers >= numAlliedPlayers + max_unevenDiff then
      local clientNum = axisPlayers[ numAxisPlayers ]
      et.trap_SendConsoleCommand( et.EXEC_APPEND, "ref putallies " .. clientNum .. " b" )
	  et.trap_SendServerCommand(-1, "chat \"balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^4ALLIES\"" ) 
   elseif numAlliedPlayers >= numAxisPlayers + unevenDiff then
      if unevenTime > 0 then
         if tonumber( levelTime ) - unevenTime >= max_unevenTime * 1000 then
            local clientNum = alliedPlayers[ numAlliedPlayers ]
            et.trap_SendConsoleCommand( et.EXEC_APPEND, "ref putaxis " .. clientNum .. " r" )
			et.trap_SendServerCommand(-1, "chat \"balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^1AXIS\"" ) 
         end
      else
         unevenTime = tonumber( levelTime )
      end
   elseif numAxisPlayers >= numAlliedPlayers + unevenDiff then
      if unevenTime > 0 then
         if tonumber( levelTime ) - unevenTime >= max_unevenTime * 1000 then
            local clientNum = axisPlayers[ numAxisPlayers ]
            et.trap_SendConsoleCommand( et.EXEC_APPEND, "ref putallies " .. clientNum .. " b" )
			et.trap_SendServerCommand(-1, "chat \"balancing teams... " .. et.gentity_get( clientNum, "pers.netname" ) .. "^7 moved to ^4ALLIES\"" ) 
         end
      else
         unevenTime = tonumber( levelTime )
      end
   else
      unevenTime = -1
   end
end

function et_ClientSpawn( clientNum, revived, teamChange, restoreHealth )
   if teamChange ~= 0 then
      local team = tonumber( et.gentity_get( clientNum, "sess.sessionTeam" ) )
      -- these were the teamnumbers prior to the move
      local numAlliedPlayers = table.getn( alliedPlayers )
      local numAxisPlayers = table.getn( axisPlayers )
      if team == 1 then
         for i, num in ipairs( alliedPlayers ) do
            if num == clientNum then
               table.remove( alliedPlayers, i )
               break
            end
         end
         -- this should not happen but still check for it to avoid doubles
         for i, num in ipairs( axisPlayers ) do
            if num == clientNum then
               return
            end
         end
         -- make sure a player who (got) moved when teams were uneven doesn't get moved right back
         if numAlliedPlayers >= numAxisPlayers + unevenDiff then
            table.insert( axisPlayers, 1, clientNum )
         else
            table.insert( axisPlayers, clientNum )
         end
      elseif team == 2 then
         for i, num in ipairs( axisPlayers ) do
            if num == clientNum then
               table.remove( axisPlayers, i )
               break
            end
         end
         for i, num in ipairs( alliedPlayers ) do
            if num == clientNum then
               return
            end
         end
         if numAxisPlayers >= numAlliedPlayers + unevenDiff then
            table.insert( alliedPlayers, 1, clientNum )
         else
            table.insert( alliedPlayers, clientNum )
         end
      else
         for i, num in ipairs( alliedPlayers ) do
            if num == clientNum then
               table.remove( alliedPlayers, i )
               return
            end
         end
         for i, num in ipairs( axisPlayers ) do
            if num == clientNum then
               table.remove( axisPlayers, i )
               return
            end
         end
      end
   end
end

function et_ClientDisconnect( clientNum )
   for i, num in ipairs( alliedPlayers ) do
      if num == clientNum then
         table.remove( alliedPlayers, i )
         return
      end
   end
   for i, num in ipairs( axisPlayers ) do
      if num == clientNum then
         table.remove( axisPlayers, i )
         return
      end
   end
end

Last edited by mazak (18-Feb-25 07:39:12)


4385074.png

et.png

Offline

#3 20-Feb-25 08:45:58

Drago
Member
Registered: 07-May-23
Posts: 22

Re: balance the teams

Hello Mazak.

Thank you for taking the time to answer me, it's nice of you.
Unfortunately I couldn't get your LUA scripts to work on my server. Are they compatible with "nitmod"?
I deliberately unbalanced the teams composed of bots on my test server. I put 8 bots on one side and 10 on the other, there was no balancing action.
I then put myself as the 11th player in the largest team but still no balancing of the teams.

Kind regards!

Offline

#4 20-Feb-25 14:47:58

mazak
Member
From: Poland
Registered: 11-Jun-13
Posts: 39

Re: balance the teams

Lua 1

putteam_cmd = "!putteam"

change to

!put

Check with more bots example 10v6
Check here:

unevenDiff = 2
max_unevenTime = 30
max_unevenDiff = 4

I have more scripts like this, I can send them if it still doesn't work

Last edited by mazak (20-Feb-25 14:50:45)


4385074.png

et.png

Offline

#5 21-Feb-25 08:37:01

Drago
Member
Registered: 07-May-23
Posts: 22

Re: balance the teams

Hi Mazak!

I just want to thank you from the bottom of my heart. Your script works wonderfully.
I hope I can help you one day too. Thank you very much my friend!

Kind regards!

Offline

Board footer

Powered by FluxBB