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;
- }
|