/** * [CSRD] `jointeam` Fix */ #pragma semicolon 1 #include #include #pragma newdecls required #define PLUGIN_VERSION "1.0.0" public Plugin myinfo = { name = "[CSRD] `jointeam` Fix", author = "nosoop", description = "Redisplays the team selection panel if the player is on cooldown while " ... "unassigned.", version = PLUGIN_VERSION, url = "https://git.csrd.science/" } any offs_CTFPlayer_flNextTimeAllowTeamChange; ConVar tf_arena_use_queue; public void OnPluginStart() { // cross-reference against the offset assigned a few blocks above the inlined // CTFPlayer::HandleCommand_JoinTeam() call in ::ClientCommand() offs_CTFPlayer_flNextTimeAllowTeamChange = FindSendPropInfo("CTFPlayer", "m_hItem") + 0x18; tf_arena_use_queue = FindConVar("tf_arena_use_queue"); AddCommandListener(OnClientJoinTeam, "jointeam"); } /** * Intercepts attempts to join team; if the player is on cooldown, then wait a bit before * redisplaying the team select panel. */ Action OnClientJoinTeam(int client, const char[] command, int argc) { if (!client || GetClientTeam(client)) { return Plugin_Continue; } float flNextAllowedTeamChange = GetEntDataFloat(client, offs_CTFPlayer_flNextTimeAllowTeamChange); if (flNextAllowedTeamChange > GetGameTime()) { // we're not allowed to change teams right now -- // silently block the attempt then redisplay once the cooldown is over CreateTimer(0.1 + flNextAllowedTeamChange - GetGameTime(), RedisplayTeamSelectMenu, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE); return Plugin_Handled; } return Plugin_Continue; } /** * Redisplay the team select panel. */ Action RedisplayTeamSelectMenu(Handle timer, int clientserial) { int client = GetClientFromSerial(clientserial); if (!client) { return Plugin_Handled; } if (IsInArenaMode() && tf_arena_use_queue.BoolValue) { ShowVGUIPanel(client, "arenateampanel"); } else { ShowVGUIPanel(client, "team"); } return Plugin_Handled; } bool IsInArenaMode() { return GameRules_GetProp("m_nGameType") == 4; }