csrd_jointeam_fix.sp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * [CSRD] `jointeam` Fix
  3. */
  4. #pragma semicolon 1
  5. #include <sourcemod>
  6. #include <sdktools>
  7. #pragma newdecls required
  8. #define PLUGIN_VERSION "1.0.0"
  9. public Plugin myinfo = {
  10. name = "[CSRD] `jointeam` Fix",
  11. author = "nosoop",
  12. description = "Redisplays the team selection panel if the player is on cooldown while "
  13. ... "unassigned.",
  14. version = PLUGIN_VERSION,
  15. url = "https://git.csrd.science/"
  16. }
  17. any offs_CTFPlayer_flNextTimeAllowTeamChange;
  18. ConVar tf_arena_use_queue;
  19. public void OnPluginStart() {
  20. // cross-reference against the offset assigned a few blocks above the inlined
  21. // CTFPlayer::HandleCommand_JoinTeam() call in ::ClientCommand()
  22. offs_CTFPlayer_flNextTimeAllowTeamChange = FindSendPropInfo("CTFPlayer", "m_hItem") + 0x18;
  23. tf_arena_use_queue = FindConVar("tf_arena_use_queue");
  24. AddCommandListener(OnClientJoinTeam, "jointeam");
  25. }
  26. /**
  27. * Intercepts attempts to join team; if the player is on cooldown, then wait a bit before
  28. * redisplaying the team select panel.
  29. */
  30. Action OnClientJoinTeam(int client, const char[] command, int argc) {
  31. if (!client || GetClientTeam(client)) {
  32. return Plugin_Continue;
  33. }
  34. float flNextAllowedTeamChange = GetEntDataFloat(client,
  35. offs_CTFPlayer_flNextTimeAllowTeamChange);
  36. if (flNextAllowedTeamChange > GetGameTime()) {
  37. // we're not allowed to change teams right now --
  38. // silently block the attempt then redisplay once the cooldown is over
  39. CreateTimer(0.1 + flNextAllowedTeamChange - GetGameTime(), RedisplayTeamSelectMenu,
  40. GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
  41. return Plugin_Handled;
  42. }
  43. return Plugin_Continue;
  44. }
  45. /**
  46. * Redisplay the team select panel.
  47. */
  48. Action RedisplayTeamSelectMenu(Handle timer, int clientserial) {
  49. int client = GetClientFromSerial(clientserial);
  50. if (!client) {
  51. return Plugin_Handled;
  52. }
  53. if (IsInArenaMode() && tf_arena_use_queue.BoolValue) {
  54. ShowVGUIPanel(client, "arenateampanel");
  55. } else {
  56. ShowVGUIPanel(client, "team");
  57. }
  58. return Plugin_Handled;
  59. }
  60. bool IsInArenaMode() {
  61. return GameRules_GetProp("m_nGameType") == 4;
  62. }