| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | /** * [CSRD] `jointeam` Fix */#pragma semicolon 1#include <sourcemod>#include <sdktools>#pragma newdecls required#define PLUGIN_VERSION "1.1.1"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");		UserMsg vguiMessage = GetUserMessageId("VGUIMenu");	HookUserMessage(vguiMessage, OnVGUIMenuPreSent, true);}/** * 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) {	// block the command if we're resending on a `jointeam` cooldown	return client && QueueResendTeamChangePanel(client)? Plugin_Handled : Plugin_Continue;}/** * Intercepts attempts to transmit the team select panel to a client, delaying transmission if * the player is unassigned and on cooldown. */Action OnVGUIMenuPreSent(UserMsg vguiMessage, BfRead buffer, const int[] players,		int nPlayers, bool reliable, bool init) {	// vgui usermessages are expected to only have a single recipient	if (nPlayers != 1) {		return Plugin_Continue;	}		char name[128];	buffer.ReadString(name, sizeof(name));		if (!StrEqual(name, "arenateampanel") && !StrEqual(name, "team")) {		return Plugin_Continue;	}		int client = players[0];		// block the message if we're resending on a `jointeam` cooldown	return QueueResendTeamChangePanel(client)? Plugin_Handled : Plugin_Continue;}bool QueueResendTeamChangePanel(int client) {	// return early if client is assigned to a team	if (GetClientTeam(client)) {		return false;	}		float flNextAllowedTeamChange = GetEntDataFloat(client,			offs_CTFPlayer_flNextTimeAllowTeamChange);	if (flNextAllowedTeamChange > GetGameTime()) {		// we're not allowed to change teams right now, so set a timer to redisplay		CreateTimer(0.1 + flNextAllowedTeamChange - GetGameTime(), RedisplayTeamSelectMenu,				GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);		return true;	}		return false;}/** * 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;}
 |