Raised This Month: $32 Target: $400
 8% 

Half-Life Auto Team Balancer Does Not Work Correctly


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
AN0TH3R
Junior Member
Join Date: Feb 2020
Old 05-15-2020 , 06:55   Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #1

I found an auto team balancer plugin for my new Half-Life TDM server. But plugin does not work correctly on my server. Teams were not balancing when 1v1. I tried different cvars like mp_teamplay 1 and mp_teamplay 2. (I already wrote mp_teamlist "gman;gordon") I hope you can help me.

Code:
/*	AMX Mod X script.

	http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community

	AutoTeam Blancer plugin for Half-Life by Lev.

	URL: http://aghl.ru/forum/viewtopic.php?f=19&t=638

	Info:
		Plugin balances teams trying to keep teams equals by players counts.
		Takes into account: players counts, spectators, hltv.
		Transfers last connected player or player with least score.
		Plugin works only if mp_teamplay is 1 and mp_teamlist is set.
		Correctly works with any amount of teams and any team names.
		
	CVARs:
		teambalancer_exclude "abc" // (default = "c") Flags that excludes player from being transferred by auto team balancing. Flags on bots are ignored.
		teambalancer_balancebots "1" // (default = "1") Bots are allowed to be transfered in balancing process.
		teambalancer_botsfirst "1" // (default = "1") Bots are preffered before players to transfer.

	Installation:
		put hl_auto_team_balancer.amxx to plugins folder;
		add hl_auto_team_balancer.amxx to config\plugins.ini file.

	Thanks to:
		koko76 for bug reporting.

	Change Log:
		v1.1 [2012.01.30]
			Initial release.
		v1.2 [2012.02.04]
			[!] Change: access flags on bots are ignored.
			[+] Added: new cvars to regulate bots transferring.
			[!] Fixed: possible crash with 32 players.
		v1.3 [2012.02.05]
			[!] Fixed: bug in balancer code (thanks to koko76).
		v1.4 [2012.02.06]
			[!] Fixed: minor bug in balancer code.

*/

#pragma semicolon 1
#pragma ctrlchar '\'

#include <amxmodx>
#include <amxmisc>
#include <fakemeta_util>

#define AUTHOR "Lev"
#define PLUGIN "HL Auto Team Balancer"
#define VERSION "1.4"
#define VERSION_CVAR "hlautoteambalancer_version"

// Compilation options
//#define _DEBUG		// Enable debug output at server console.

#define MAX_TEAMS		32
#define MAX_TEAMNAME	16
#define MAX_PLAYERS		32

enum PlayerInfo
{
	PiId,
	PiIsBot,
	PiTeamId,
	PiFrags,
	PiDeaths
}

new _playerInfo[MAX_PLAYERS + 1][PlayerInfo];
new _teamNames[MAX_TEAMS][MAX_TEAMNAME + 1];
new _teams;
new _counts[MAX_TEAMS], _frags[MAX_TEAMS], _deaths[MAX_TEAMS];
new pcvar_teambalancer_exclude, pcvar_teambalancer_balancebots, pcvar_teambalancer_botsfirst;

public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);
	register_cvar(VERSION_CVAR, VERSION, FCVAR_SPONLY | FCVAR_SERVER | FCVAR_UNLOGGED);

	pcvar_teambalancer_exclude		= register_cvar("teambalancer_exclude", "c");		// Flags that excludes player from being transferred by auto team balancing. Flags on bots are ignored.
	pcvar_teambalancer_balancebots	= register_cvar("teambalancer_balancebots", "1");	// Bots are allowed to be transfered in balancing process.
	pcvar_teambalancer_botsfirst	= register_cvar("teambalancer_botsfirst", "1");		// Bots are preffered before players to transfer.

#if defined _DEBUG
	register_concmd("bal", "BalanceTeamsByCount");
#endif

	GetTeamNames();

	if (!get_cvar_num("mp_teamplay") || _teams == 0)
	{
		log_amx("Current mode is not team play or team list is not limited. Plugin is paused...");
		pause("ad");
		return;
	}
}

public client_putinserver(id)
{
	set_task(0.2, "BalanceTeamsByCount", id);
}

public client_command(id)
{
	new cmd[33];
	read_argv(0, cmd, charsmax(cmd));

	if (equal(cmd, "spectate"))
		set_task(0.2, "BalanceTeamsByCount");

	return PLUGIN_CONTINUE;
}

public client_infochanged(id)
{
	new teamId = get_user_team(id) - 1;
	new i = 0;
	// Find previous player team
	while(_playerInfo[i][PiId])
	{
		if (_playerInfo[i][PiId] == id)
		{
			if (_playerInfo[i][PiTeamId] != teamId)
			{
#if defined _DEBUG
				server_print("Team change detected: player %i, prev team: %i, new team: %i", id, _playerInfo[i][PiTeamId], teamId);
#endif
				BalanceTeamsByCount(id);
			}
			break;
		}
		i++;
	}
}

public client_disconnect(id)
{
	set_task(0.2, "BalanceTeamsByCount", 0);
}

public BalanceTeamsByCount(idLast)
{
#if defined _DEBUG
	server_print("idLast: %i", idLast);
#endif
	RecountTeams();

	static i, id, j, selected, maxPlayers, minPlayers, largestTeamId, smallestTeamId, minFrags, minFragsSet, flagsStr[33], flags, teambalancer_balancebots, teambalancer_botsfirst;
	maxPlayers = 0;
	minPlayers = MAX_PLAYERS;
	largestTeamId = 0;
	smallestTeamId = 0;
	for (j = 0; j < _teams; j++)
	{
		if (_counts[j] > maxPlayers)
		{
			maxPlayers = _counts[j];
			largestTeamId = j;
		}
		if (_counts[j] < minPlayers)
		{
			minPlayers = _counts[j];
			smallestTeamId = j;
		}
	}
#if defined _DEBUG
	server_print("Largest team %i %s: count: %i", largestTeamId, _teamNames[largestTeamId], maxPlayers);
	server_print("Smallest team %i %s: count: %i", smallestTeamId, _teamNames[smallestTeamId], minPlayers);
#endif

	if (maxPlayers - minPlayers > 1)
	{
#if defined _DEBUG
		server_print("Going to find player to transfer...");
#endif
		get_pcvar_string(pcvar_teambalancer_exclude, flagsStr, charsmax(flagsStr));
		flags = read_flags_fixed(flagsStr);
		i = 0;
		id = 0;
		selected = 0;
		minFrags = 0;
		minFragsSet = 0;
		teambalancer_balancebots = get_pcvar_num(pcvar_teambalancer_balancebots);
		teambalancer_botsfirst = get_pcvar_num(pcvar_teambalancer_botsfirst);
		// Select player from largest team to transfer
		while(_playerInfo[i][PiId])
		{
			if (!teambalancer_balancebots && _playerInfo[i][PiIsBot]) continue;	// Skip bots
			if (_playerInfo[i][PiTeamId] == largestTeamId)
			{
#if defined _DEBUG
				server_print("Testing player %i, flags: %i, %i, is bot: %i, selected: %i, minFragsSet: %i, minFrags: %i", _playerInfo[i][PiId], get_user_flags(_playerInfo[i][PiId]), get_user_flags(_playerInfo[i][PiId]) & flags, _playerInfo[i][PiIsBot], selected, minFragsSet, minFrags);
#endif
				// If bots are first we will pick bot regardless of the score and who was last
				if (teambalancer_botsfirst && _playerInfo[i][PiIsBot])
				{
					id = _playerInfo[i][PiId];
#if defined _DEBUG
					server_print("Selected %i: because bots are first", id);
#endif
					break;
				}
				if (selected) { i++; continue; }	// We have found last player within the largest team so we will need to check others only if a bot can be found
				// If last player is within largest team we will transfer him
				if (_playerInfo[i][PiId] == idLast && get_user_flags(idLast) & flags == 0)
				{
					id = idLast;
					selected = 1;
#if defined _DEBUG
					server_print("Selected %i: cos was last", id);
#endif
					if (!teambalancer_botsfirst) break;	// If don't need to find a bot - break
					i++;
					continue;
				}
				// Select player from largest team with lowest frags
				if ((!minFragsSet || _playerInfo[i][PiFrags] < minFrags) &&
					(_playerInfo[i][PiIsBot] || get_user_flags(_playerInfo[i][PiId]) & flags == 0))	// Ignore access flags on bots
				{
					minFragsSet = 1;
					minFrags = _playerInfo[i][PiFrags];
					id = _playerInfo[i][PiId];
#if defined _DEBUG
					server_print("Selected %i: with %i frags", id, minFrags);
#endif
				}
			}
			i++;
		}
		if (id)
		{
#if defined _DEBUG
			server_print("Transferring %i to %s", id, _teamNames[smallestTeamId]);
#endif
			set_user_info(id, "model", _teamNames[smallestTeamId]);
			client_cmd(id,"model \"%s\"", _teamNames[smallestTeamId]);
		}
	}
}

RecountTeams()
{
	static players[MAX_PLAYERS], num;
	static i, j, id, teamId;
	get_players(players, num);
	for (j = 0; j < _teams; j++)
	{
		_counts[j] = 0;
		_frags[j] = 0;
		_deaths[j] = 0;
	}
	for (i = 0; i < num; i++)
	{
		id = players[i];
		teamId = get_user_team(id) - 1;
		_playerInfo[i][PiId] = id;
		_playerInfo[i][PiIsBot] = is_user_bot(id);
		_playerInfo[i][PiTeamId] = teamId;
		_playerInfo[i][PiFrags] = get_user_frags(id);
		_playerInfo[i][PiDeaths] = get_user_deaths(id);
#if defined _DEBUG
		server_print("PlayerInfo %i: id: %i, team id: %i, frags: %i, death: %i", i, _playerInfo[i][PiId], _playerInfo[i][PiTeamId], _playerInfo[i][PiFrags], _playerInfo[i][PiDeaths]);
#endif
		if (pev(id, pev_iuser1)) continue;				// Spectator.
		if (teamId < 0 || teamId >= _teams) continue;	// Team not set yet.
		_counts[teamId]++;
		_frags[teamId] += get_user_frags(id);
		_deaths[teamId] += get_user_deaths(id);
	}
	_playerInfo[i][PiId] = 0;	// End of the list
#if defined _DEBUG
	server_print("Stats:");
	for (j = 0; j < _teams; j++)
		server_print("Team %i: %s, counts: %i, frags: %i, deaths: %i", j, _teamNames[j], _counts[j], _frags[j], _deaths[j]);
#endif
}

GetTeamNames()
{
	new j, teams[MAX_TEAMS * MAX_TEAMNAME + 1], team[MAX_TEAMNAME + 1];
	get_cvar_string("mp_teamlist", teams, charsmax(teams));
	for (j = 0; j < MAX_TEAMS; j++)
	{
		strtok(teams, team, charsmax(team), teams, charsmax(teams), ';');
		if (team[0] == 0) break;
		copy(_teamNames[j], MAX_TEAMNAME, team);
		_teams++;
	}
#if defined _DEBUG
	server_print("Teams count: %i", _teams);
	for (j = 0; j < _teams; j++)
		server_print("Team %i name: %s", j, _teamNames[j]);
#endif
}

/// Converts string of flags into int.
/// Only chars from 'a' to 'z' are converted, others are skipped.
stock read_flags_fixed(const flags[])
{
	new result, i = 0;
	while (flags[i] != 0)
	{
		if (flags[i] >= 'a' && flags[i] <= 'z')
			result |= 1 << (flags[i] - 'a');
		i++;	
	}
	return result;
}
Attached Files
File Type: sma Get Plugin or Get Source (hl_auto_team_balancer.sma - 161 views - 9.1 KB)
AN0TH3R is offline
abdobiskra
Veteran Member
Join Date: Jul 2014
Location: Algeria
Old 05-17-2020 , 11:49   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #2

Your problem is unclear.
the plugin running?
__________________
abdobiskra is offline
Send a message via Skype™ to abdobiskra
AN0TH3R
Junior Member
Join Date: Feb 2020
Old 05-19-2020 , 04:55   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #3

Plugin seems running but teams are not balancing actually. We are stucking in 2v0 after my "model gordon" command. But it should be 1v1 immediatly after my console command. So plugin does not balance when we use console commands. I'll be very happy if someone fix this problem.

Last edited by AN0TH3R; 05-19-2020 at 04:55.
AN0TH3R is offline
abdobiskra
Veteran Member
Join Date: Jul 2014
Location: Algeria
Old 05-19-2020 , 06:22   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #4

are you using Bugfixed by Lev?
__________________

Last edited by abdobiskra; 05-19-2020 at 06:24.
abdobiskra is offline
Send a message via Skype™ to abdobiskra
AN0TH3R
Junior Member
Join Date: Feb 2020
Old 05-19-2020 , 09:35   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #5

Quote:
AutoTeam Blancer plugin for Half-Life by Lev.
I'm not sure there is an another version of this plugin. All I can say is this plugin has problems. Plugin does not work healthy when player use model change command on console.
AN0TH3R is offline
abdobiskra
Veteran Member
Join Date: Jul 2014
Location: Algeria
Old 05-19-2020 , 12:01   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #6

It's ok for me but I'm using Bugfixed
Yes, this is the last version here original topic: HL AutoTeam Balancer
__________________
abdobiskra is offline
Send a message via Skype™ to abdobiskra
AN0TH3R
Junior Member
Join Date: Feb 2020
Old 05-20-2020 , 10:58   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #7

But it should be work without "Bugfixed"?
AN0TH3R is offline
abdobiskra
Veteran Member
Join Date: Jul 2014
Location: Algeria
Old 05-20-2020 , 13:07   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #8

I think so on condition:
Quote:
Info:
Plugin balances teams trying to keep teams equals by players counts.
Takes into account: players counts, spectators, hltv.
Transfers last connected player or player with least score.
Plugin works only if mp_teamplay is 1 and mp_teamlist is set.
Correctly
works with any amount of teams and any team names.
If it's ok, try to add in this line:
PHP Code:
if (equal(cmd"spectate")) 
to
PHP Code:
if (equal(cmd"spectate") || equal(cmd"model")) 
__________________
abdobiskra is offline
Send a message via Skype™ to abdobiskra
AN0TH3R
Junior Member
Join Date: Feb 2020
Old 05-28-2020 , 21:53   Re: Half-Life Auto Team Balancer Does Not Work Correctly
Reply With Quote #9

I tried this plugin with BugFixed HL on my friend's server. Plugin is working on windows but it did not work on my linux server. Also I decided to give up on this plugin. I don't have time to check. Maybe I can change my mind in future. Thank you for your reply.
AN0TH3R is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 18:53.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode