Skip to content

Commit

Permalink
Updated to 0.3.2-beta version
Browse files Browse the repository at this point in the history
- Delete unused .inc-file hamsanwich.
- Added cvars and auto-cfg.
- Added an another way to move players between teams.
- Added more debug info.
- Added immunity from balance.
- Added ML-support.
- Added a pause before player has been switched to another team.
  • Loading branch information
Nord1cWarr1or committed Oct 22, 2019
1 parent db94849 commit 387c0c7
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 40 deletions.
21 changes: 21 additions & 0 deletions data/lang/dm_autobalance.txt
@@ -0,0 +1,21 @@
[en]
DMTB_CVAR_MAX_DIFF = Maximum allowable difference between teams
DMTB_CVAR_MODE = Transfer mode^n1 - simple player's respawn^n2 - teleport to spawnspot
DMTB_CVAR_TIME = Time before switching a player for another team
DMTB_CVAR_IMMUNITY = A flag that gives immunity from balance
DMTB_DHUD_WILL_BALANCED = You will be switched to opposite team via %.0f sec.
DMTB_DHUD_BALANCED_CT = You've been switched to team ct
DMTB_DHUD_BALANCED_TE = You've been switched to team terrorists
DMTB_CHAT_BALANCED_CT = ^4* ^3%n ^1has been moved to ^3team ct^1.
DMTB_CHAT_BALANCED_TE = ^4* ^3%n ^1has been moved to ^3team terrorists^1.

[ru]
DMTB_CVAR_MAX_DIFF = Максимально допустимая разница между командами
DMTB_CVAR_MODE = Режим работы переноса^n1 - простой респавн игрока^n2 - телепорт на спавн
DMTB_CVAR_TIME = Время перед перемещением игрока за другую команду
DMTB_CVAR_IMMUNITY = Флаг, дающий иммунитет от баланса
DMTB_DHUD_WILL_BALANCED = Вы будете перемещены за другую команду через %.0f сек.
DMTB_DHUD_BALANCED_CT = Вы были перемещены за контр-террористов
DMTB_DHUD_BALANCED_TE = Вы были перемещены за террористов
DMTB_CHAT_BALANCED_CT = ^4* ^3%n ^1был перемещён за ^3контр-террористов^1.
DMTB_CHAT_BALANCED_TE = ^4* ^3%n ^1был перемещён за ^3террористов^1.
155 changes: 115 additions & 40 deletions scripting/AutoBalance.sma
@@ -1,62 +1,105 @@
#include <amxmodx>
#include <amxmisc>
#include <reapi>
#include <hamsandwich>
#include <xs>
#include <screenfade_util>

new const PLUGIN_VERSION[] = "0.2.0";
new const PLUGIN_VERSION[] = "0.3.2-beta";

#define GetCvarDesc(%0) fmt("%L", LANG_SERVER, %0)

#define GetBit(%1,%2) (%1 & (1 << (%2 & 31)))
#define SetBit(%1,%2) %1 |= (1 << (%2 & 31))
#define ClrBit(%1,%2) %1 &= ~(1 << (%2 & 31))

//#define DEBUG

#define AUTO_CFG // Comment out if you don't want the plugin config to be created automatically in "configs/plugins"

enum _:Cvars
{
MAX_DIFF,
MODE,
Float:TIME_TO_PREPARE,
IMMUNITY_FLAG[2]
};

new g_iCvar[Cvars];

new TeamName:g_iNewPlayerTeam[MAX_PLAYERS + 1];

new g_iBlueColor[3] = { 0, 0, 255 };
new g_iRedColor[3] = { 255, 0, 0 };

const TASKID__SHOW_HUD = 991;
new const TE_SPAWN[] = "info_player_deathmatch";
new const CT_SPAWN[] = "info_player_start";

const TASKID__BALANCE_PLAYER = 991;
const TASKID__SHOW_HUD = 992;

new g_bitIsUserConnected;
new g_bitIsUserBalanced;

new g_iCvarMaxDifference;

#define get_bit(%1,%2) (%1 & (1 << (%2 & 31)))
#define set_bit(%1,%2) %1 |= (1 << (%2 & 31))
#define clr_bit(%1,%2) %1 &= ~(1 << (%2 & 31))
new Float:g_flSpawnCT[3], Float:g_flSpawnTE[3];

public plugin_init()
{
register_plugin("DM AutoBalance", PLUGIN_VERSION, "Nordic Warrior");

RegisterHookChain(RG_CBasePlayer_Spawn, "OnPlayerSpawnPost", true);
register_dictionary("dm_autobalance.txt");

RegisterHookChain(RG_CBasePlayer_Killed, "OnPlayerKilledPost", true);

new pCvar = create_cvar("dmtb_max_diff", "1");
bind_pcvar_num(pCvar, g_iCvarMaxDifference);
CreateCvars();

#if defined AUTO_CFG
AutoExecConfig(true);
#endif

FindSpawnEntities();

#if defined DEBUG
register_clcmd("say /ct", "CheckTeams");
#endif
}

public FindSpawnEntities()
{
new iSpawnEntCT = rg_find_ent_by_class(-1, CT_SPAWN, true);
new iSpawnEntTE = rg_find_ent_by_class(-1, TE_SPAWN, true);

if(!iSpawnEntCT || !iSpawnEntTE)
{
log_amx("Couldn't find default spawn etities. Plugin automatucally switched to first mode.");
set_pcvar_bounds(g_iCvar[MODE], CvarBound_Upper, true, 1.0);
return;
}

get_entvar(iSpawnEntCT, var_origin, g_flSpawnCT);
get_entvar(iSpawnEntTE, var_origin, g_flSpawnTE);
}

public client_putinserver(id)
{
set_bit(g_bitIsUserConnected, id);
SetBit(g_bitIsUserConnected, id);
}

public client_disconnected(id)
{
if(get_bit(g_bitIsUserConnected, id))
if(GetBit(g_bitIsUserConnected, id))
{
#if defined DEBUG
log_amx("Player <%n> disconnected", id);
#endif

CheckTeams();
clr_bit(g_bitIsUserConnected, id);
ClrBit(g_bitIsUserConnected, id);
}
}

public OnPlayerKilledPost(victim, killer)
{
if(!get_bit(g_bitIsUserConnected, killer) || killer == victim)
if(!GetBit(g_bitIsUserConnected, killer) || killer == victim)
return;

#if defined DEBUG
Expand All @@ -68,6 +111,9 @@ public OnPlayerKilledPost(victim, killer)

public CheckTeams()
{
if(task_exists(TASKID__BALANCE_PLAYER))
return;

new iPlayers[MAX_PLAYERS], iPlayersNum;

get_players_ex(iPlayers, iPlayersNum, GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV);
Expand All @@ -89,7 +135,7 @@ public CheckTeams()
log_amx("TE = %i, CT = %i", iCountInTeam[TEAM_TERRORIST], iCountInTeam[TEAM_CT]);
#endif

if(xs_abs(iCountInTeam[TEAM_TERRORIST] - iCountInTeam[TEAM_CT]) > g_iCvarMaxDifference)
if(xs_abs(iCountInTeam[TEAM_TERRORIST] - iCountInTeam[TEAM_CT]) > g_iCvar[MAX_DIFF])
{
new iTeamToBalance = xs_sign(iCountInTeam[TEAM_TERRORIST] - iCountInTeam[TEAM_CT]);
new iRandomPlayer;
Expand All @@ -109,47 +155,76 @@ public CheckTeams()
log_amx("Balanced player: <%n>, ID: %i", iRandomPlayer, iRandomPlayer);
#endif

set_bit(g_bitIsUserBalanced, iRandomPlayer);
if(has_flag(iRandomPlayer, g_iCvar[IMMUNITY_FLAG]))
{
#if defined DEBUG
log_amx("Player <%n> has immunity", iRandomPlayer);
#endif

RequestFrame("CheckTeams");
return;
}

SetBit(g_bitIsUserBalanced, iRandomPlayer);

rg_switch_team(iRandomPlayer);
rg_round_respawn(iRandomPlayer);
set_task(g_iCvar[TIME_TO_PREPARE], "BalancePlayer", iRandomPlayer + TASKID__BALANCE_PLAYER);

set_dhudmessage(255, 255, 255, -1.0, 0.42, 0, 0.0, 3.0, 0.1, 0.1);
show_dhudmessage(iRandomPlayer, "%l", "DMTB_DHUD_WILL_BALANCED", g_iCvar[TIME_TO_PREPARE]);
}
}

public OnPlayerSpawnPost(id)
public BalancePlayer(id)
{
if(!is_user_alive(id))
return;
id -= TASKID__BALANCE_PLAYER;

if(!get_bit(g_bitIsUserBalanced, id))
return;
if(user_has_weapon(id, CSW_C4))
rg_drop_items_by_slot(id, C4_SLOT);

UTIL_ScreenFade(id, g_iNewPlayerTeam[id] == TEAM_CT ? g_iRedColor : g_iBlueColor, 0.3, 1.5, 100);
rg_switch_team(id);

set_task(0.1, "ShowHud", id + TASKID__SHOW_HUD);
switch(g_iCvar[MODE])
{
case 1: rg_round_respawn(id);
case 2: set_entvar(id, var_origin, g_iNewPlayerTeam[id] == TEAM_CT ? g_flSpawnTE : g_flSpawnCT);
}

clr_bit(g_bitIsUserBalanced, id);
UTIL_ScreenFade(id, g_iNewPlayerTeam[id] == TEAM_CT ? g_iRedColor : g_iBlueColor, 0.5, 2.5, 100);

#if defined DEBUG
log_amx("Player's ID: %i", id);
#endif
set_task(0.1, "ShowHud", TASKID__SHOW_HUD + id);

ClrBit(g_bitIsUserBalanced, id);
}

public ShowHud(id)
{
id -= TASKID__SHOW_HUD;

if(!get_bit(g_bitIsUserConnected, id))
return;

#if defined DEBUG
log_amx("Player's ID on ShowHud: %i", id);
#endif


set_dhudmessage(255, 255, 255, -1.0, 0.42, 0, 0.0, 3.0, 0.1, 0.1);
show_dhudmessage(id, "Вы были перемещены за %s", g_iNewPlayerTeam[id] == TEAM_CT ? "террористов" : "контр-террористов");
show_dhudmessage(id, "%l", g_iNewPlayerTeam[id] == TEAM_CT ? "DMTB_DHUD_BALANCED_TE" : "DMTB_DHUD_BALANCED_CT");

ClientPrintToAllExcludeOne(id, id, "^4* ^3%n ^1был перемещён за ^3%s", id, g_iNewPlayerTeam[id] == TEAM_CT ? "террористов" : "контр-террористов");
ClientPrintToAllExcludeOne(id, id, "%l", id, g_iNewPlayerTeam[id] == TEAM_CT ? "DMTB_CHAT_BALANCED_TE" : "DMTB_CHAT_BALANCED_CT");
}

public CreateCvars()
{
bind_pcvar_num(create_cvar("dmtb_max_diff", "1",
.description = GetCvarDesc("DMTB_CVAR_MAX_DIFF"),
.has_min = true, .min_val = 1.0),
g_iCvar[MAX_DIFF]);

bind_pcvar_num(create_cvar("dmtb_mode", "1",
.description = GetCvarDesc("DMTB_CVAR_MODE")),
g_iCvar[MODE]);

bind_pcvar_float(create_cvar("dmtb_time", "3.0",
.description = GetCvarDesc("DMTB_CVAR_TIME"),
.has_min = true, .min_val = 1.0),
g_iCvar[TIME_TO_PREPARE]);

bind_pcvar_string(create_cvar("dmtb_immunity", "a",
.description = GetCvarDesc("DMTB_CVAR_IMMUNITY")),
g_iCvar[IMMUNITY_FLAG], charsmax(g_iCvar[IMMUNITY_FLAG]));
}

stock ClientPrintToAllExcludeOne(const iExcludePlayer, const iSender, const szMessage[], any:...)
Expand Down

0 comments on commit 387c0c7

Please sign in to comment.