Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 63.29 KB | None | 0 0
  1. #pragma semicolon 1
  2. #include <sourcemod>
  3. #include <sdktools>
  4. #include <sdkhooks>
  5.  
  6. #define PLUGIN_VERSION "0.1.36"
  7.  
  8. Handle g_GameData = null;
  9. ArrayList g_sQueue;
  10. ArrayList g_iQueue;
  11.  
  12. // menu parameters
  13. #define menuArgs g_menuItems[client] // Global argument tracking for the menu system
  14. #define menuArg0 g_menuItems[client][0] // GetItem(1...)
  15. #define menuArg1 g_menuItems[client][1] // GetItem(2...)
  16. g_menuItems[MAXPLAYERS + 1][2];
  17.  
  18. // menu tracking
  19. #define g_callBacks g_menuStack[client]
  20. ArrayStack g_menuStack[MAXPLAYERS + 1];
  21. new Function:callBack;
  22.  
  23. char g_QKey[64]; // holds players by STEAM_ID
  24. StringMap g_QDB; // holds player records linked by STEAM_ID
  25. StringMap g_QRecord; // changes to an individual STEAM_ID mapping
  26. StringMap g_Cvars;
  27.  
  28. char g_InfectedNames[11][] = {"Boomer", "Smoker", "Boomer", "Hunter", "Spitter", "Jockey", "Charger", "Boomer", "Tank", "Boomer", "Witch"};
  29. char g_SurvivorNames[8][] = {"Nick", "Rochelle", "Coach", "Ellis", "Bill", "Zoey", "Francis", "Louis"};
  30. char g_SurvivorPaths[8][] = {
  31. "models/survivors/survivor_gambler.mdl",
  32. "models/survivors/survivor_producer.mdl",
  33. "models/survivors/survivor_coach.mdl",
  34. "models/survivors/survivor_mechanic.mdl",
  35. "models/survivors/survivor_namvet.mdl",
  36. "models/survivors/survivor_teenangst.mdl",
  37. "models/survivors/survivor_biker.mdl",
  38. "models/survivors/survivor_manager.mdl",
  39. };
  40.  
  41. char g_sB[512]; // generic catch all string buffer
  42. char g_pN[128]; // a dedicated buffer to storing a players name
  43. int g_client; // g_QDB client id
  44. int g_target; // g_QDB player (human or bot) id
  45. int g_lastid; // g_QDB client's last known bot id
  46. int g_onteam = 1; // g_QDB client's team
  47. char g_model[64]; // g_QDB client's model
  48. char g_ghost[64]; // g_QDB client model backup (for activation)
  49. bool g_queued = false; // g_QDB client's takeover state
  50. float g_origin[3]; // g_QDB client's origin vector
  51. bool g_inspec = false; // g_QDB check client's specator mode
  52. char g_cisi[MAXPLAYERS + 1][64]; // g_QDB client Id to steam Id array
  53. Handle g_AD; // Assistant Director Timer
  54.  
  55. char g_GameMode[16];
  56. bool g_IsVs = false;
  57. bool g_IsCoop = false;
  58. bool g_AssistedSpawning = false;
  59. bool g_RemovedPlayers = false;
  60. bool g_AddedPlayers = false;
  61. bool g_ADFreeze = true;
  62. int g_ADInterval;
  63.  
  64. ConVar g_cvMinPlayers;
  65. ConVar g_cvPrimaryWeapon;
  66. ConVar g_cvSecondaryWeapon;
  67. ConVar g_cvThrowable;
  68. ConVar g_cvHealItem;
  69. ConVar g_cvConsumable;
  70. ConVar g_cvExtraPlayers;
  71. ConVar g_cvSpawnInterval;
  72. ConVar g_cvMaxSI;
  73. ConVar g_cvAutoHard;
  74. ConVar g_cvJoinMenu;
  75. ConVar g_cvTeamLimit;
  76. ConVar g_cvOfferTakeover;
  77.  
  78. int g_MinPlayers;
  79. char g_PrimaryWeapon[64];
  80. char g_SecondaryWeapon[64];
  81. char g_Throwable[64];
  82. char g_HealItem[64];
  83. char g_Consumable[64];
  84. int g_ExtraPlayers;
  85. int g_SpawnInterval;
  86. int g_MaxSI;
  87. int g_AutoHard;
  88. int g_JoinMenu;
  89. int g_TeamLimit;
  90. int g_OfferTakeover;
  91.  
  92. public Plugin myinfo= {
  93. name = "Advanced Bot Manager",
  94. author = "Victor \"NgBUCKWANGS\" Gonzalez",
  95. description = "A 5+ Player Enhancement Plugin for L4D2",
  96. version = PLUGIN_VERSION,
  97. url = "https://gitlab.com/vbgunz/ABM"
  98. }
  99.  
  100. public OnPluginStart() {
  101.  
  102. g_GameData = LoadGameConfigFile("advanced_bot_manager");
  103. if (g_GameData == null) {
  104. SetFailState("[ABM] Game data missing!");
  105. }
  106.  
  107. HookEvent("player_first_spawn", OnSpawnHook);
  108. HookEvent("player_death", OnDeathHook, EventHookMode_Pre);
  109. HookEvent("player_disconnect", CleanQDBHook);
  110. HookEvent("player_afk", GoIdleHook);
  111. HookEvent("player_team", QTeamHook);
  112. HookEvent("player_bot_replace", QAfkHook);
  113. HookEvent("bot_player_replace", QBakHook);
  114. HookEvent("player_activate", PlayerActivateHook, EventHookMode_Pre);
  115. HookEvent("player_connect", PlayerActivateHook, EventHookMode_Pre);
  116. HookEvent("round_end", RoundFreezeEndHook, EventHookMode_Pre);
  117. HookEvent("mission_lost", RoundFreezeEndHook, EventHookMode_Pre);
  118. HookEvent("round_freeze_end", RoundFreezeEndHook, EventHookMode_Pre);
  119. HookEvent("map_transition", RoundFreezeEndHook, EventHookMode_Pre);
  120. HookEvent("round_start", RoundStartHook, EventHookMode_Pre);
  121.  
  122. RegAdminCmd("abm", MainMenuCmd, ADMFLAG_ROOT);
  123. RegAdminCmd("abm-menu", MainMenuCmd, ADMFLAG_ROOT, "Menu: (Main ABM menu)");
  124. RegAdminCmd("abm-join", SwitchTeamCmd, ADMFLAG_ROOT, "Menu/Cmd: <TEAM> | <ID> <TEAM>");
  125. RegAdminCmd("abm-takeover", SwitchToBotCmd, ADMFLAG_ROOT, "Menu/Cmd: <ID> | <ID1> <ID2>");
  126. RegAdminCmd("abm-respawn", RespawnClientCmd, ADMFLAG_ROOT, "Menu/Cmd: <ID> [ID]");
  127. RegAdminCmd("abm-model", AssignModelCmd, ADMFLAG_ROOT, "Menu/Cmd: <MODEL> | <MODEL> <ID>");
  128. RegAdminCmd("abm-strip", StripClientCmd, ADMFLAG_ROOT, "Menu/Cmd: <ID> [SLOT]");
  129. RegAdminCmd("abm-teleport", TeleportClientCmd, ADMFLAG_ROOT, "Menu/Cmd: <ID1> <ID2>");
  130. RegAdminCmd("abm-cycle", CycleBotsCmd, ADMFLAG_ROOT, "Menu/Cmd: <TEAM> | <ID> <TEAM>");
  131. RegAdminCmd("abm-reset", ResetCmd, ADMFLAG_ROOT, "Cmd: (Use only in case of emergency)");
  132. RegAdminCmd("abm-info", QuickClientPrintCmd, ADMFLAG_ROOT, "Cmd: (Print some diagnostic information)");
  133. RegAdminCmd("abm-addbot", AddBotsCmd, ADMFLAG_ROOT, "Cmd: <N|-N> <TEAM>");
  134. RegAdminCmd("abm-rembot", RemBotsCmd, ADMFLAG_ROOT, "Cmd: <TEAM> | <N|-N> <TEAM>");
  135. RegConsoleCmd("takeover", SwitchToBotCmd, "Menu/Cmd: <ID> | <ID1> <ID2>");
  136. RegConsoleCmd("join", SwitchTeamCmd, "Menu/Cmd: <TEAM> | <ID> <TEAM>");
  137.  
  138. g_QDB = new StringMap();
  139. g_QRecord = new StringMap();
  140. g_Cvars = new StringMap();
  141. g_sQueue = new ArrayList(2);
  142. g_iQueue = new ArrayList(2);
  143.  
  144. for (int i = 1 ; i <= MaxClients ; i++) {
  145. g_menuStack[i] = new ArrayStack(128);
  146. }
  147.  
  148. // Register everyone that we can find
  149. for (int i = 1 ; i <= MaxClients ; i++) {
  150. if (!GetQRecord(i)) {
  151. if (SetQRecord(i) != -1) {
  152. g_cisi[i] = g_QKey;
  153. }
  154. }
  155. }
  156.  
  157. FindConVar("mp_gamemode").GetString(g_GameMode, sizeof(g_GameMode));
  158. g_IsVs = (StrEqual(g_GameMode, "versus") || StrEqual(g_GameMode, "scavenge"));
  159. g_IsCoop = StrEqual(g_GameMode, "coop");
  160.  
  161. CreateConVar("abm_version", PLUGIN_VERSION, "ABM plugin version", FCVAR_DONTRECORD);
  162. g_cvMinPlayers = CreateConVar("abm_minplayers", "4", "Pruning extra survivors stops at this size");
  163. g_cvPrimaryWeapon = CreateConVar("abm_primaryweapon", "autoshotgun", "5+ survivor primary weapon");
  164. g_cvSecondaryWeapon = CreateConVar("abm_secondaryweapon", "pistol_magnum", "5+ survivor secondary weapon");
  165. g_cvThrowable = CreateConVar("abm_throwable", "", "5+ survivor throwable item");
  166. g_cvHealItem = CreateConVar("abm_healitem", "", "5+ survivor healing item");
  167. g_cvConsumable = CreateConVar("abm_consumable", "adrenaline", "5+ survivor consumable item");
  168. g_cvExtraPlayers = CreateConVar("abm_extraplayers", "0", "Extra survivors to start the round with");
  169. g_cvSpawnInterval = CreateConVar("abm_spawninterval", "18", "SI full team spawn in (5 x N)");
  170. g_cvAutoHard = CreateConVar("abm_autohard", "0", "0: Off 1: Non-Vs > 4 2: Non-Vs >= 1");
  171. g_cvJoinMenu = CreateConVar("abm_joinmenu", "0", "0: Off 1: Admins only 2: Everyone");
  172. g_cvTeamLimit = CreateConVar("abm_teamlimit", "10", "Humans on team limit");
  173. g_cvOfferTakeover = CreateConVar("abm_offertakeover", "1", "0: Off 1: Survivors 2: Infected 3: All");
  174.  
  175. g_cvMaxSI = FindConVar("z_max_player_zombies");
  176. SetConVarBounds(g_cvMaxSI, ConVarBound_Lower, true, 1.0);
  177. SetConVarBounds(g_cvMaxSI, ConVarBound_Upper, true, 24.0);
  178.  
  179. HookConVarChange(g_cvMinPlayers, UpdateConVarsHook);
  180. HookConVarChange(g_cvPrimaryWeapon, UpdateConVarsHook);
  181. HookConVarChange(g_cvSecondaryWeapon, UpdateConVarsHook);
  182. HookConVarChange(g_cvThrowable, UpdateConVarsHook);
  183. HookConVarChange(g_cvHealItem, UpdateConVarsHook);
  184. HookConVarChange(g_cvConsumable, UpdateConVarsHook);
  185. HookConVarChange(g_cvExtraPlayers, UpdateConVarsHook);
  186. HookConVarChange(g_cvSpawnInterval, UpdateConVarsHook);
  187. HookConVarChange(g_cvAutoHard, UpdateConVarsHook);
  188. HookConVarChange(g_cvJoinMenu, UpdateConVarsHook);
  189. HookConVarChange(g_cvTeamLimit, UpdateConVarsHook);
  190. HookConVarChange(g_cvOfferTakeover, UpdateConVarsHook);
  191.  
  192. UpdateConVarsHook(g_cvMinPlayers, "4", "4");
  193. UpdateConVarsHook(g_cvPrimaryWeapon, "autoshotgun", "autoshotgun");
  194. UpdateConVarsHook(g_cvSecondaryWeapon, "pistol_magnum", "pistol_magnum");
  195. UpdateConVarsHook(g_cvThrowable, "", "");
  196. UpdateConVarsHook(g_cvHealItem, "", "");
  197. UpdateConVarsHook(g_cvConsumable, "adrenaline", "adrenaline");
  198. UpdateConVarsHook(g_cvExtraPlayers, "0", "0");
  199. UpdateConVarsHook(g_cvSpawnInterval, "18", "18");
  200. UpdateConVarsHook(g_cvAutoHard, "0", "0");
  201. UpdateConVarsHook(g_cvJoinMenu, "0", "0");
  202. UpdateConVarsHook(g_cvTeamLimit, "10", "10");
  203. UpdateConVarsHook(g_cvOfferTakeover, "1", "1");
  204.  
  205. AutoExecConfig(true, "advanced_bot_manager");
  206. StartAD();
  207. }
  208.  
  209. public OnEntityCreated(int ent, const char[] classname) {
  210.  
  211. if(classname[0] == 'f') {
  212. bool gClip = !StrEqual(classname, "func_playerghostinfected_clip", false);
  213. bool iClip = !StrEqual(classname, "func_playerinfected_clip", false);
  214.  
  215. if (!(gClip && iClip)) {
  216. CreateTimer(1.0, KillEntTimer, EntIndexToEntRef(ent));
  217. }
  218. }
  219. }
  220.  
  221. public Action KillEntTimer(Handle timer, any ref) {
  222.  
  223. int ent = EntRefToEntIndex(ref);
  224. if (ent != INVALID_ENT_REFERENCE || IsValidEntity(ent)) {
  225. AcceptEntityInput(ent, "kill");
  226. }
  227.  
  228. return Plugin_Stop;
  229. }
  230.  
  231. public Action L4D_OnGetScriptValueInt(const String:key[], &retVal) {
  232.  
  233. if (g_AutoHard > 0) {
  234. int val = retVal;
  235.  
  236. if (StrEqual(key, "ShouldIgnoreClearStateForSpawn")) val = 1;
  237. else if (StrEqual(key, "AlwaysAllowWanderers")) val = 1;
  238. else if (StrEqual(key, "ClearedWandererRespawnChance")) val = 1;
  239. else if (StrEqual(key, "EnforceFinaleNavSpawnRules")) val = 0;
  240. else if (StrEqual(key, "DisallowThreatType")) val = 0;
  241. else if (StrEqual(key, "ProhibitBosses")) val = 0;
  242. else if (StrEqual(key, "MaxSpecials")) val = g_MaxSI;
  243. else if (StrEqual(key, "DominatorLimit")) val = g_MaxSI;
  244. else if (StrEqual(key, "BoomerLimit")) val = 4;
  245. else if (StrEqual(key, "SmokerLimit")) val = 4;
  246. else if (StrEqual(key, "HunterLimit")) val = 4;
  247. else if (StrEqual(key, "ChargerLimit")) val = 4;
  248. else if (StrEqual(key, "SpitterLimit")) val = 4;
  249. else if (StrEqual(key, "JockeyLimit")) val = 4;
  250. else if (StrEqual(key, "ZombieDontClear")) val = 1;
  251. //else if (StrEqual(key, "CommonLimit")) val = 30;
  252.  
  253. if (val != retVal) {
  254. retVal = val;
  255. return Plugin_Handled;
  256. }
  257. }
  258.  
  259. return Plugin_Continue;
  260. }
  261.  
  262. public RoundFreezeEndHook(Handle event, const char[] name, bool dontBroadcast) {
  263.  
  264. if (g_ADFreeze) {
  265. return;
  266. }
  267.  
  268. StopAD();
  269. StringMapSnapshot keys = g_QDB.Snapshot();
  270. g_iQueue.Clear();
  271.  
  272. if (!g_IsVs) {
  273. for (int i ; i < keys.Length ; i++) {
  274. keys.GetKey(i, g_sB, sizeof(g_sB));
  275. g_QDB.GetValue(g_sB, g_QRecord);
  276. g_QRecord.GetValue("onteam", g_onteam);
  277. g_QRecord.GetValue("client", g_client);
  278. g_QRecord.GetString("model", g_model, sizeof(g_model));
  279. g_QRecord.SetString("ghost", g_model, true);
  280.  
  281. if (g_onteam == 3) {
  282. SwitchToSpec(g_client);
  283. g_QRecord.SetValue("queued", true, true);
  284. g_QRecord.SetValue("inspec", false, true);
  285. }
  286. }
  287. }
  288.  
  289. delete keys;
  290. }
  291.  
  292. public PlayerActivateHook(Handle event, const char[] name, bool dontBroadcast) {
  293.  
  294. int userid = GetEventInt(event, "userid");
  295. int client = GetClientOfUserId(userid);
  296. PlayerActivate(client);
  297. }
  298.  
  299. PlayerActivate(int client) {
  300.  
  301. if (GetQRecord(client)) {
  302. StartAD();
  303. AssignModel(client, g_ghost);
  304.  
  305. if (!g_IsVs) {
  306. if (g_onteam == 3) {
  307. SwitchTeam(client, 3);
  308. }
  309. }
  310. }
  311. }
  312.  
  313. public RoundStartHook(Handle event, const char[] name, bool dontBroadcast) {
  314. StartAD();
  315.  
  316. for (int i = 1 ; i <= MaxClients ; i++) {
  317. if (GetQRecord(i)) {
  318. if (!g_IsVs && g_onteam == 3) {
  319. SwitchTeam(i, 3);
  320. }
  321. }
  322. }
  323. }
  324.  
  325. bool StopAD() {
  326.  
  327. if (g_AD != null) {
  328. g_ADFreeze = true;
  329. g_AssistedSpawning = false;
  330. g_RemovedPlayers = false;
  331. g_AddedPlayers = false;
  332. g_ADInterval = 0;
  333.  
  334. delete g_AD;
  335. g_AD = null;
  336. }
  337.  
  338. return g_AD == null;
  339. }
  340.  
  341. bool StartAD() {
  342.  
  343. if (g_AD == null) {
  344. g_ADFreeze = true;
  345. g_AssistedSpawning = false;
  346. g_RemovedPlayers = false;
  347. g_AddedPlayers = false;
  348. g_ADInterval = 0;
  349.  
  350. g_AD = CreateTimer(
  351. 5.0, ADTimer, _, TIMER_REPEAT
  352. );
  353. }
  354.  
  355. return g_AD != null;
  356. }
  357.  
  358. public Action ADTimer(Handle timer) {
  359.  
  360. if (g_ADFreeze) {
  361. for (int i = 1 ; i <= MaxClients ; i++) {
  362. if (IsClientConnected(i)) {
  363. if (!IsClientInGame(i)) {
  364. return Plugin_Continue;
  365. }
  366.  
  367. else {
  368. if (!g_IsVs) {
  369. if (GetQRecord(i)) {
  370. if (g_onteam == 3 && g_queued) {
  371. SwitchTeam(i, 3);
  372. }
  373. }
  374. }
  375. }
  376. }
  377. }
  378.  
  379. g_ADFreeze = false;
  380. }
  381.  
  382. if (!g_RemovedPlayers && CountTeamMates(2) >= 1) {
  383. RemBots((g_MinPlayers + g_ExtraPlayers) * -1, 2);
  384. g_RemovedPlayers = true;
  385. }
  386.  
  387. if (g_RemovedPlayers) {
  388. if (!g_AddedPlayers && CountTeamMates(2) >= 1) {
  389. AddBots((g_MinPlayers + g_ExtraPlayers) * -1, 2);
  390. g_AddedPlayers = true;
  391. }
  392. }
  393.  
  394. g_ADInterval++;
  395. int teamSize = CountTeamMates(2);
  396.  
  397. if (teamSize == 0) {
  398. g_ADInterval = 0;
  399. return Plugin_Continue;
  400. }
  401.  
  402. static lastSize;
  403. bool autoWave;
  404.  
  405. if (g_IsCoop) {
  406. if (lastSize != teamSize) {
  407. lastSize = teamSize;
  408. }
  409. }
  410.  
  411. // Auto difficulty here will not spawn SI in competitive modes.
  412. // SI are unlocked (without spawn) see L4D_OnGetScriptValueInt.
  413.  
  414. switch (g_IsVs) {
  415. case 1: autoWave = false;
  416. case 0: autoWave = g_AutoHard == 2 || teamSize > 4 && g_AutoHard == 1;
  417. }
  418.  
  419. if (autoWave || g_AssistedSpawning) {
  420. if (g_ADInterval >= g_SpawnInterval) {
  421. if (g_ADInterval % g_SpawnInterval == 0) {
  422. AddBots(teamSize * -1, 3);
  423. }
  424.  
  425. else if (g_ADInterval % (g_SpawnInterval / 2) == 0) {
  426. AddBots((teamSize / 2) * -1, 3);
  427. }
  428. }
  429. }
  430.  
  431. int onteam;
  432. float nTakeover = 0.1;
  433. g_AssistedSpawning = false;
  434.  
  435. for (int i = 1 ; i <= MaxClients ; i++) {
  436. if (GetQRecord(i)) {
  437. if (g_onteam == 3) {
  438. if (!g_IsVs) {
  439. g_AssistedSpawning = true;
  440.  
  441. if (!IsPlayerAlive(i) && !g_queued && !g_inspec) {
  442. g_QRecord.SetValue("queued", true, true);
  443. QueueUp(i, 3);
  444. }
  445. }
  446.  
  447. continue;
  448. }
  449.  
  450. onteam = GetClientTeam(i);
  451. if (onteam == 3) {
  452. continue;
  453. }
  454.  
  455. if (!g_inspec && onteam <= 1) {
  456. CreateTimer(nTakeover, TakeoverTimer, i);
  457. nTakeover += 0.1;
  458. }
  459. }
  460. }
  461.  
  462. return Plugin_Continue;
  463. }
  464.  
  465. public UpdateConVarsHook(Handle convar, const char[] oldCv, const char[] newCv) {
  466. GetConVarName(convar, g_sB, sizeof(g_sB));
  467.  
  468. char name[32];
  469. char value[32];
  470.  
  471. Format(name, sizeof(name), g_sB);
  472. Format(value, sizeof(value), "%s", newCv);
  473.  
  474. if (StrContains(newCv, "-l") == 0) {
  475. ReplaceString(value, sizeof(value), "-l", "");
  476. g_Cvars.SetString(name, value, true);
  477. }
  478.  
  479. else if (StrContains(newCv, "-u") == 0) {
  480. ReplaceString(value, sizeof(value), "-u", "");
  481. g_Cvars.Remove(name);
  482. }
  483.  
  484. g_Cvars.GetString(name, value, sizeof(value));
  485. TrimString(value);
  486. if (value[0] == EOS) {
  487. Format(value, sizeof(value), oldCv);
  488. }
  489.  
  490. SetConVarString(convar, value);
  491.  
  492. if (StrEqual(name, "abm_extraplayers")) {
  493. g_ExtraPlayers = GetConVarInt(g_cvExtraPlayers);
  494. }
  495.  
  496. else if (StrEqual(name, "abm_spawninterval")) {
  497. g_SpawnInterval = GetConVarInt(g_cvSpawnInterval);
  498. }
  499.  
  500. else if (StrEqual(name, "abm_primaryweapon")) {
  501. GetConVarString(g_cvPrimaryWeapon, g_PrimaryWeapon, sizeof(g_PrimaryWeapon));
  502. }
  503.  
  504. else if (StrEqual(name, "abm_secondaryweapon")) {
  505. GetConVarString(g_cvSecondaryWeapon, g_SecondaryWeapon, sizeof(g_SecondaryWeapon));
  506. }
  507.  
  508. else if (StrEqual(name, "abm_throwable")) {
  509. GetConVarString(g_cvThrowable, g_Throwable, sizeof(g_Throwable));
  510. }
  511.  
  512. else if (StrEqual(name, "abm_healitem")) {
  513. GetConVarString(g_cvHealItem, g_HealItem, sizeof(g_HealItem));
  514. }
  515.  
  516. else if (StrEqual(name, "abm_consumable")) {
  517. GetConVarString(g_cvConsumable, g_Consumable, sizeof(g_Consumable));
  518. }
  519.  
  520. else if (StrEqual(name, "abm_minplayers")) {
  521. g_MinPlayers = GetConVarInt(g_cvMinPlayers);
  522. }
  523.  
  524. else if (StrEqual(name, "abm_autohard")) {
  525. g_AutoHard = GetConVarInt(g_cvAutoHard);
  526. }
  527.  
  528. else if (StrEqual(name, "abm_joinmenu")) {
  529. g_JoinMenu = GetConVarInt(g_cvJoinMenu);
  530. }
  531.  
  532. else if (StrEqual(name, "abm_teamlimit")) {
  533. g_TeamLimit = GetConVarInt(g_cvTeamLimit);
  534. }
  535.  
  536. else if (StrEqual(name, "abm_offertakeover")) {
  537. g_OfferTakeover = GetConVarInt(g_cvOfferTakeover);
  538. }
  539. }
  540.  
  541. public OnConfigsExecuted() {
  542. PrecacheModels();
  543. }
  544.  
  545. public OnClientPostAdminCheck(int client) {
  546.  
  547. if (!GetQRecord(client)) {
  548. if (SetQRecord(client) >= 0) {
  549. g_cisi[client] = g_QKey;
  550.  
  551. if (g_JoinMenu == 2 || g_JoinMenu == 1 && IsAdmin(client)) {
  552. GoIdle(client, 1);
  553. menuArg0 = client;
  554. SwitchTeamHandler(client, 1);
  555. }
  556.  
  557. else if (CountTeamMates(2) >= 1) {
  558. CreateTimer(0.1, TakeoverTimer, client);
  559. }
  560. }
  561. }
  562. }
  563.  
  564. public GoIdleHook(Handle event, const char[] name, bool dontBroadcast) {
  565. int player = GetEventInt(event, "player");
  566. int client = GetClientOfUserId(player);
  567.  
  568. if (GetQRecord(client)) {
  569. switch (g_onteam) {
  570. case 2: GoIdle(client);
  571. case 3: SwitchTeam(client, 3);
  572. }
  573. }
  574. }
  575.  
  576. GoIdle(int client, onteam=0) {
  577.  
  578. if (GetQRecord(client)) {
  579.  
  580. int spec_target;
  581.  
  582. if (g_onteam == 2) {
  583. SwitchToSpec(client);
  584. SetHumanSpecSig(g_target, client);
  585.  
  586. if (onteam == 1) {
  587. SwitchToSpec(client);
  588. Unqueue(client);
  589. }
  590.  
  591. AssignModel(g_target, g_model);
  592. }
  593.  
  594. else {
  595. SwitchToSpec(client);
  596. }
  597.  
  598. switch (IsClientValid(g_target) && IsFakeClient(g_target)) {
  599. case 1: spec_target = g_target;
  600. case 0: spec_target = GetSafeSurvivor(client);
  601. }
  602.  
  603. if (IsClientValid(spec_target)) {
  604. SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", spec_target);
  605. SetEntProp(client, Prop_Send, "m_iObserverMode", 5);
  606. }
  607. }
  608. }
  609.  
  610. public CleanQDBHook(Handle event, const char[] name, bool dontBroadcast) {
  611.  
  612. int userid = GetEventInt(event, "userid");
  613. int client = GetClientOfUserId(userid);
  614. RemoveQDBKey(client);
  615. }
  616.  
  617. RemoveQDBKey(int client) {
  618.  
  619. // during map change, GetQRecord is not reliable :'(
  620. Format(g_sB, sizeof(g_sB), "%s", g_cisi[client]);
  621.  
  622. if (g_QDB.Remove(g_sB)) {
  623. g_cisi[client] = "";
  624.  
  625. int survivors = CountTeamMates(2);
  626. if (survivors > (g_MinPlayers + g_ExtraPlayers)) {
  627. CreateTimer(1.0, RemBotsTimer, 1);
  628. }
  629. }
  630. }
  631.  
  632. public Action RemBotsTimer(Handle timer, any asmany) {
  633.  
  634. if (!g_IsVs) {
  635. RemBots(asmany, 2);
  636. }
  637. }
  638.  
  639. bool IsAdmin(int client) {
  640. return CheckCommandAccess(
  641. client, "generic_admin", ADMFLAG_ROOT, false
  642. );
  643. }
  644.  
  645. bool IsClientValid(int client) {
  646.  
  647. if (client >= 1 && client <= MaxClients) {
  648. if (IsClientConnected(client)) {
  649. if (IsClientInGame(client)) {
  650. return true;
  651. }
  652. }
  653. }
  654.  
  655. return false;
  656. }
  657.  
  658. bool CanClientTarget(int client, int target) {
  659.  
  660. if (client == target) {
  661. return true;
  662. }
  663.  
  664. else if (!IsClientValid(client) || !IsClientValid(target)) {
  665. return false;
  666. }
  667.  
  668. else if (IsFakeClient(target)) {
  669. int manager = GetClientManager(target);
  670.  
  671. if (manager != -1) {
  672. if (manager == 0) {
  673. return true;
  674. }
  675.  
  676. else {
  677. return CanClientTarget(client, manager);
  678. }
  679. }
  680. }
  681.  
  682. return CanUserTarget(client, target);
  683. }
  684.  
  685. int GetPlayClient(int client) {
  686.  
  687. if (GetQRecord(client)) {
  688. return g_target;
  689. }
  690.  
  691. else if (IsClientValid(client)) {
  692. return client;
  693. }
  694.  
  695. return -1;
  696. }
  697.  
  698. int ClientHomeTeam(int client) {
  699.  
  700. if (GetQRecord(client)) {
  701. return g_onteam;
  702. }
  703.  
  704. else if (IsClientValid(client)) {
  705. return GetClientTeam(client);
  706. }
  707.  
  708. return -1;
  709. }
  710.  
  711. // ================================================================== //
  712. // g_QDB MANAGEMENT
  713. // ================================================================== //
  714.  
  715. bool SetQKey(int client) {
  716.  
  717. if (IsClientValid(client) && !IsFakeClient(client)) {
  718. if (GetClientAuthId(client, AuthId_Steam2, g_QKey, sizeof(g_QKey), true)) {
  719. return true;
  720. }
  721. }
  722.  
  723. return false;
  724. }
  725.  
  726. bool GetQRecord(int client) {
  727.  
  728. if (SetQKey(client)) {
  729. if (g_QDB.GetValue(g_QKey, g_QRecord)) {
  730.  
  731. if (IsClientValid(client) && IsPlayerAlive(client)) {
  732. GetClientAbsOrigin(client, g_origin);
  733. g_QRecord.SetArray("origin", g_origin, sizeof(g_origin), true);
  734. }
  735.  
  736. g_QRecord.GetValue("client", g_client);
  737. g_QRecord.GetValue("target", g_target);
  738. g_QRecord.GetValue("lastid", g_lastid);
  739. g_QRecord.GetValue("onteam", g_onteam);
  740. g_QRecord.GetValue("queued", g_queued);
  741. g_QRecord.GetValue("inspec", g_inspec);
  742.  
  743. if (GetClientTeam(client) == 2) {
  744. int i = GetClientModelIndex(client);
  745. if (i >= 0) {
  746. Format(g_model, sizeof(g_model), "%s", g_SurvivorNames[i]);
  747. g_QRecord.SetString("model", g_model, true);
  748. }
  749. }
  750.  
  751. g_QRecord.GetString("model", g_model, sizeof(g_model));
  752. g_QRecord.GetString("ghost", g_ghost, sizeof(g_ghost));
  753. return true;
  754. }
  755. }
  756.  
  757. return false;
  758. }
  759.  
  760. bool NewQRecord(int client) {
  761.  
  762. g_QRecord = new StringMap();
  763.  
  764. GetClientAbsOrigin(client, g_origin);
  765. g_QRecord.SetArray("origin", g_origin, sizeof(g_origin), true);
  766. g_QRecord.SetValue("client", client, true);
  767. g_QRecord.SetValue("target", client, true);
  768. g_QRecord.SetValue("lastid", client, true);
  769. g_QRecord.SetValue("onteam", GetClientTeam(client), true);
  770. g_QRecord.SetValue("queued", false, true);
  771. g_QRecord.SetValue("inspec", false, true);
  772. g_QRecord.SetString("model", "", true);
  773. g_QRecord.SetString("ghost", "", true);
  774. return true;
  775. }
  776.  
  777. int SetQRecord(int client) {
  778.  
  779. int result = -1;
  780.  
  781. if (SetQKey(client)) {
  782. if (g_QDB.GetValue(g_QKey, g_QRecord)) {
  783. result = 0;
  784. }
  785.  
  786. else if (NewQRecord(client)) {
  787. g_QDB.SetValue(g_QKey, g_QRecord, true);
  788. result = 1;
  789. }
  790.  
  791. GetQRecord(client);
  792. }
  793.  
  794. return result;
  795. }
  796.  
  797. QueueUp(int client, int onteam) {
  798.  
  799. if (onteam >= 2 && GetQRecord(client)) {
  800. Unqueue(client);
  801.  
  802. switch (onteam) {
  803. case 2: g_sQueue.Push(client);
  804. case 3: g_iQueue.Push(client);
  805. }
  806.  
  807. g_QRecord.SetValue("queued", true, true);
  808. }
  809. }
  810.  
  811. Unqueue(int client) {
  812.  
  813. if (GetQRecord(client)) {
  814. g_QRecord.SetValue("queued", false, true);
  815.  
  816. int iLength = g_iQueue.Length;
  817. int sLength = g_sQueue.Length;
  818.  
  819. if (iLength > 0) {
  820. for (int i = iLength - 1 ; i > -1 ; i--) {
  821. if (g_iQueue.Get(i) == client) {
  822. g_iQueue.Erase(i);
  823. }
  824. }
  825. }
  826.  
  827. if (sLength > 0) {
  828. for (int i = sLength - 1 ; i > -1 ; i--) {
  829. if (g_sQueue.Get(i) == client) {
  830. g_sQueue.Erase(i);
  831. }
  832. }
  833. }
  834. }
  835. }
  836.  
  837. public OnSpawnHook(Handle event, const char[] name, bool dontBroadcast) {
  838.  
  839. int userid = GetEventInt(event, "userid");
  840. int target = GetClientOfUserId(userid);
  841. GetClientName(target, g_pN, sizeof(g_pN));
  842.  
  843. int flag1 = StrContains(g_pN, "SPECIAL");
  844. int flag2 = StrContains(g_pN, "SURVIVOR");
  845. if (flag1 >= 0 || flag2 >= 0) {
  846. return;
  847. }
  848.  
  849. static oldTank;
  850. int newTank;
  851. int onteam = GetClientTeam(target);
  852. static ghostTank; // this is the extra Tank that just ghosts and dies
  853. bool isTank = false;
  854.  
  855. if (!g_IsVs && onteam == 3) {
  856. if (g_AssistedSpawning) {
  857.  
  858. if (GetEntProp(target, Prop_Send, "m_zombieClass", target) == 8) {
  859. //if (StrContains(g_pN, "Tank") >= 0) {
  860. isTank = true;
  861.  
  862. for (int i = 1 ; i <= MaxClients ; i++) {
  863. if (GetQRecord(i) && g_onteam == 3 && !g_inspec) {
  864. if (GetEntProp(i, Prop_Send, "m_zombieClass", i) != 8) {
  865.  
  866. if (newTank == 0 || i > oldTank) {
  867. newTank = i;
  868. }
  869.  
  870. if (oldTank != i) {
  871. oldTank = i;
  872. SwitchToBot(i, target);
  873. return;
  874. }
  875. }
  876. }
  877. }
  878. }
  879.  
  880. if (IsClientValid(newTank)) {
  881. SwitchToBot(newTank, target);
  882. return;
  883. }
  884.  
  885. else if (isTank) {
  886. switch (IsClientValid(ghostTank)) {
  887. case 1: {
  888. ForcePlayerSuicide(ghostTank);
  889. ghostTank = 0;
  890. }
  891.  
  892. case 0: {
  893. AddInfected(0, "Tank");
  894. ghostTank = target;
  895. }
  896. }
  897. }
  898. }
  899.  
  900. if (g_iQueue.Length > 0) {
  901. SwitchToBot(g_iQueue.Get(0), target);
  902. return;
  903. }
  904. }
  905.  
  906. if (onteam == 2) {
  907. CreateTimer(0.2, AutoModelTimer, target);
  908. CreateTimer(0.4, OnSpawnHookTimer, target);
  909. }
  910. }
  911.  
  912. public Action OnSpawnHookTimer(Handle timer, any target) {
  913.  
  914. if (g_sQueue.Length > 0) {
  915. SwitchToBot(g_sQueue.Get(0), target);
  916. return;
  917. }
  918. }
  919.  
  920. public OnDeathHook(Handle event, const char[] name, bool dontBroadcast) {
  921.  
  922. int userid = GetEventInt(event, "userid");
  923. int client = GetClientOfUserId(userid);
  924.  
  925. if (GetQRecord(client)) {
  926. GetClientAbsOrigin(client, g_origin);
  927. g_QRecord.SetValue("target", client, true);
  928. g_QRecord.SetArray("origin", g_origin, sizeof(g_origin), true);
  929. bool offerTakeover;
  930.  
  931. switch (g_onteam) {
  932. case 3: {
  933. if (!g_IsVs) {
  934. switch (g_OfferTakeover) {
  935. case 2, 3: {
  936. QueueUp(client, 3);
  937. GoIdle(client, 1);
  938. offerTakeover = true;
  939. }
  940.  
  941. default: SwitchTeam(client, 3);
  942. }
  943. }
  944. }
  945.  
  946. case 2: {
  947. switch (g_OfferTakeover) {
  948. case 1, 3: offerTakeover = true;
  949. }
  950. }
  951. }
  952.  
  953. if (offerTakeover) {
  954. GenericMenuCleaner(client);
  955. menuArg0 = client;
  956. SwitchToBotHandler(client, 1);
  957. }
  958. }
  959. }
  960.  
  961. public QTeamHook(Handle event, const char[] name, bool dontBroadcast) {
  962.  
  963. int userid = GetEventInt(event, "userid");
  964. int client = GetClientOfUserId(userid);
  965. int onteam = GetEventInt(event, "team");
  966.  
  967. if (GetQRecord(client)) {
  968. if (onteam >= 2) {
  969. g_QRecord.SetValue("inspec", false, true);
  970. g_QRecord.SetValue("target", client, true);
  971. g_QRecord.SetValue("onteam", onteam, true);
  972. g_QRecord.SetValue("queued", false, true);
  973.  
  974. if (onteam == 3) {
  975. g_QRecord.SetString("model", "", true);
  976. return;
  977. }
  978. }
  979.  
  980. if (onteam <= 1) { // cycling requires 0.2 or higher?
  981. CreateTimer(0.2, QTeamHookTimer, client);
  982. }
  983. }
  984. }
  985.  
  986. public Action QTeamHookTimer(Handle timer, any client) {
  987.  
  988. if (GetQRecord(client) && !g_inspec) {
  989. if (g_onteam == 2) {
  990. if (IsClientValid(g_target) && g_target != client) {
  991. SetHumanSpecSig(g_target, client);
  992. }
  993. }
  994. }
  995. }
  996.  
  997. public QAfkHook(Handle event, const char[] name, bool dontBroadcast) {
  998.  
  999. int client = GetClientOfUserId(GetEventInt(event, "player"));
  1000. int target = GetClientOfUserId(GetEventInt(event, "bot"));
  1001. int clientTeam = GetClientTeam(client);
  1002. int targetTeam = GetClientTeam(target);
  1003.  
  1004. if (GetQRecord(client)) {
  1005. int onteam = GetClientTeam(client);
  1006.  
  1007. if (onteam == 2) {
  1008. g_QRecord.SetValue("target", target, true);
  1009. AssignModel(target, g_model);
  1010. }
  1011. }
  1012.  
  1013. if (targetTeam == 2 && IsClientValid(client)) {
  1014. if (IsClientInKickQueue(client)) {
  1015. if (client && target && clientTeam == targetTeam) {
  1016. int safeClient = GetSafeSurvivor(target);
  1017. RespawnClient(target, safeClient);
  1018. }
  1019. }
  1020. }
  1021. }
  1022.  
  1023. public QBakHook(Handle event, const char[] name, bool dontBroadcast) {
  1024.  
  1025. int client = GetClientOfUserId(GetEventInt(event, "player"));
  1026. int target = GetClientOfUserId(GetEventInt(event, "bot"));
  1027.  
  1028. if (GetQRecord(client)) {
  1029. if (g_target != target) {
  1030. g_QRecord.SetValue("lastid", target);
  1031. g_QRecord.SetValue("target", client);
  1032.  
  1033. GetClientName(target, g_pN, sizeof(g_pN));
  1034. int i = GetModelIndexByName(g_pN);
  1035.  
  1036. if (i != -1) {
  1037. Format(g_model, sizeof(g_model), "%s", g_SurvivorNames[i]);
  1038. g_QRecord.SetString("model", g_model, true);
  1039. }
  1040. }
  1041.  
  1042. if (GetClientTeam(client) == 2) {
  1043. AssignModel(client, g_model);
  1044. }
  1045. }
  1046. }
  1047.  
  1048. // ================================================================== //
  1049. // UNORGANIZED AS OF YET
  1050. // ================================================================== //
  1051.  
  1052. StripClient(int client) {
  1053.  
  1054. if (IsClientValid(client)) {
  1055. if (GetClientTeam(client) == 2) {
  1056. for (int i = 4 ; i >= 0 ; i--) {
  1057. StripClientSlot(client, i);
  1058. }
  1059. }
  1060. }
  1061. }
  1062.  
  1063. StripClientSlot(int client, int slot) {
  1064.  
  1065. client = GetPlayClient(client);
  1066.  
  1067. if (IsClientValid(client)) {
  1068. if (GetClientTeam(client) == 2) {
  1069. int ent = GetPlayerWeaponSlot(client, slot);
  1070. if (IsValidEntity(ent)) {
  1071. RemovePlayerItem(client, ent);
  1072. RemoveEdict(ent);
  1073. }
  1074. }
  1075. }
  1076. }
  1077.  
  1078. RespawnClient(int client, int target=0) {
  1079.  
  1080. if (!IsClientValid(client)) {
  1081. return;
  1082. }
  1083.  
  1084. else if (GetQRecord(client)) {
  1085. if (g_onteam == 3) {
  1086. Takeover(client, 3);
  1087. return;
  1088. }
  1089. }
  1090.  
  1091. float origin[3];
  1092. client = GetPlayClient(client);
  1093. target = GetPlayClient(target);
  1094.  
  1095. if (!IsClientValid(target)) {
  1096. target = client;
  1097. }
  1098.  
  1099. RoundRespawnSig(client);
  1100. GetClientAbsOrigin(target, origin);
  1101. QuickCheat(client, "give", g_PrimaryWeapon);
  1102. QuickCheat(client, "give", g_SecondaryWeapon);
  1103. QuickCheat(client, "give", g_Throwable);
  1104. QuickCheat(client, "give", g_HealItem);
  1105. QuickCheat(client, "give", g_Consumable);
  1106. TeleportEntity(client, origin, NULL_VECTOR, NULL_VECTOR);
  1107. }
  1108.  
  1109. TeleportClient(int client, int target) {
  1110.  
  1111. float origin[3];
  1112. client = GetPlayClient(client);
  1113. target = GetPlayClient(target);
  1114.  
  1115. if (IsClientValid(client) && IsClientValid(target)) {
  1116. GetClientAbsOrigin(target, origin);
  1117. TeleportEntity(client, origin, NULL_VECTOR, NULL_VECTOR);
  1118. }
  1119. }
  1120.  
  1121. int GetSafeSurvivor(int client) {
  1122.  
  1123. int last_survivor;
  1124.  
  1125. for (int i = 1 ; i <= MaxClients ; i++) {
  1126. if (IsClientValid(i) && i != client) {
  1127. if (IsPlayerAlive(i) && GetClientTeam(i) == 2) {
  1128. last_survivor = i;
  1129.  
  1130. if (GetEntProp(i, Prop_Send, "m_isHangingFromLedge") == 0) {
  1131. return i;
  1132. }
  1133. }
  1134. }
  1135. }
  1136.  
  1137. return last_survivor;
  1138. }
  1139.  
  1140. bool AddSurvivor() {
  1141.  
  1142. bool result = false;
  1143. int survivor = CreateFakeClient("SURVIVOR");
  1144.  
  1145. if (IsClientValid(survivor)) {
  1146. if (DispatchKeyValue(survivor, "classname", "SurvivorBot")) {
  1147. ChangeClientTeam(survivor, 2);
  1148.  
  1149. if (DispatchSpawn(survivor)) {
  1150. KickClient(survivor);
  1151. result = true;
  1152. }
  1153. }
  1154. }
  1155.  
  1156. return result;
  1157. }
  1158.  
  1159. GhostsModeProtector(int state) {
  1160. // CAREFUL: 0 starts this function and you must close it with 1 or
  1161. // risk breaking things. Close this with 1 immediately when done.
  1162.  
  1163. // e.g.,
  1164. // GhostsModeProtector(0);
  1165. // z_spawn_old tank auto;
  1166. // GhostsModeProtector(1);
  1167.  
  1168. if (CountTeamMates(3, 1) == 0) {
  1169. return;
  1170. }
  1171.  
  1172. static ghosts[MAXPLAYERS + 1];
  1173.  
  1174. switch (state) {
  1175. case 0: {
  1176. for (int i = 1 ; i <= MaxClients ; i++) {
  1177. if (GetQRecord(i) && g_onteam == 3) {
  1178. if (GetEntProp(i, Prop_Send, "m_isGhost") == 1) {
  1179. SetEntProp(i, Prop_Send, "m_isGhost", 0);
  1180. ghosts[i] = 1;
  1181. }
  1182. }
  1183. }
  1184. }
  1185.  
  1186. case 1: {
  1187. for (int i = 1 ; i <= MaxClients ; i++) {
  1188. if (ghosts[i] == 1) {
  1189. SetEntProp(i, Prop_Send, "m_isGhost", 1);
  1190. ghosts[i] = 0;
  1191. }
  1192. }
  1193. }
  1194. }
  1195. }
  1196.  
  1197. CleanSIName(char model[32], bool randomize=true) {
  1198.  
  1199. int i = GetModelIndexByName(model, 3);
  1200. static char infected[6][] = {"Boomer", "Smoker", "Hunter", "Spitter", "Jockey", "Charger"};
  1201.  
  1202.  
  1203. switch (model[0] != EOS && i >= 0) {
  1204. case 1: {
  1205. model = g_InfectedNames[i];
  1206. }
  1207.  
  1208. default: {
  1209. if (randomize) {
  1210. i = GetRandomInt(0, sizeof(infected) - 1);
  1211. model = infected[i];
  1212. }
  1213.  
  1214. else {
  1215. model = "";
  1216. }
  1217. }
  1218. }
  1219. }
  1220.  
  1221. bool AddInfected(int version=0, char model[32]="") {
  1222.  
  1223. // GetEntProp(i, Prop_Send, "m_ghostSpawnState");
  1224. // considering above in spawning all with z_spawn
  1225.  
  1226. bool result = false;
  1227. char cmd[12];
  1228. float i[3];
  1229.  
  1230. CleanSIName(model);
  1231. int special = CreateFakeClient("SPECIAL");
  1232.  
  1233. if (IsClientValid(special)) {
  1234.  
  1235. switch (version) {
  1236. case 0: cmd = "z_spawn_old";
  1237. case 1: cmd = "z_spawn";
  1238. }
  1239.  
  1240. ChangeClientTeam(special, 3);
  1241. Format(g_sB, sizeof(g_sB), "%s auto area", model);
  1242. GhostsModeProtector(0);
  1243. QuickCheat(special, cmd, g_sB);
  1244. KickClient(special);
  1245. GhostsModeProtector(1);
  1246.  
  1247. // use z_spawn for humans that request SI
  1248. // for all others, always use z_spawn_old
  1249. if (StrEqual(cmd, "z_spawn")) {
  1250. TeleportEntity(special, i, i, i);
  1251. }
  1252.  
  1253. result = true;
  1254. }
  1255.  
  1256. return result;
  1257. }
  1258.  
  1259. SwitchToSpec(int client, int onteam=1) {
  1260.  
  1261. if (GetQRecord(client)) {
  1262. g_QRecord.SetValue("inspec", true, true);
  1263. ChangeClientTeam(client, onteam);
  1264.  
  1265. if (client != g_target) {
  1266. SetEntProp(g_target, Prop_Send, "m_humanSpectatorUserID", 0);
  1267. }
  1268. }
  1269. }
  1270.  
  1271. QuickCheat(int client, char [] cmd, char [] arg) {
  1272.  
  1273. int flags = GetCommandFlags(cmd);
  1274. SetCommandFlags(cmd, flags & ~FCVAR_CHEAT);
  1275. FakeClientCommand(client, "%s %s", cmd, arg);
  1276. SetCommandFlags(cmd, flags);
  1277. }
  1278.  
  1279. SwitchToBot(int client, int bot, bool si_ghost=true) {
  1280.  
  1281. if (client != bot && IsClientValid(bot)) {
  1282. switch (GetClientTeam(bot)) {
  1283. case 2: TakeoverBotSig(client, bot);
  1284. case 3: TakeoverZombieBotSig(client, bot, si_ghost);
  1285. }
  1286. }
  1287. }
  1288.  
  1289. Takeover(int client, int onteam) {
  1290.  
  1291. if (GetQRecord(client)) {
  1292. if (IsClientValid(g_target) && IsFakeClient(g_target)) {
  1293. if (client != g_target && GetClientTeam(g_target) == onteam) {
  1294. SwitchToBot(client, g_target);
  1295. return;
  1296. }
  1297. }
  1298.  
  1299. g_QRecord.SetValue("target", client, true);
  1300. g_QRecord.SetValue("inspec", false, true);
  1301. g_QRecord.SetValue("onteam", onteam, true);
  1302. g_QRecord.SetValue("queued", true, true);
  1303.  
  1304. int nextBot;
  1305. nextBot = GetNextBot(onteam);
  1306.  
  1307. if (nextBot >= 1) {
  1308. SwitchToBot(client, nextBot);
  1309. return;
  1310. }
  1311.  
  1312. switch (onteam) {
  1313. case 2: {
  1314. QueueUp(client, 2);
  1315. AddSurvivor();
  1316. }
  1317.  
  1318. case 3: {
  1319. QueueUp(client, 3);
  1320. AddInfected();
  1321. }
  1322. }
  1323. }
  1324. }
  1325.  
  1326. public Action TakeoverTimer(Handle timer, any client) {
  1327.  
  1328. if (CountTeamMates(2) <= 0) {
  1329. return Plugin_Handled;
  1330. }
  1331.  
  1332. static team2;
  1333. static team3;
  1334. static teamX;
  1335.  
  1336. if (GetQRecord(client)) {
  1337. if (GetClientTeam(client) >= 2) {
  1338. return Plugin_Handled;
  1339. }
  1340.  
  1341. teamX = 2;
  1342. if (g_onteam == 3) {
  1343. teamX = 3;
  1344. }
  1345.  
  1346. if (g_IsVs && g_onteam <= 1) {
  1347. team2 = CountTeamMates(2, 1);
  1348. team3 = CountTeamMates(3, 1);
  1349.  
  1350. if (team3 < team2) {
  1351. teamX = 3;
  1352. }
  1353. }
  1354.  
  1355. if (CountTeamMates(teamX, 1) < g_TeamLimit) {
  1356. Takeover(client, teamX);
  1357. }
  1358. }
  1359.  
  1360. return Plugin_Handled;
  1361. }
  1362.  
  1363.  
  1364. int CountTeamMates(int onteam, int mtype=2) {
  1365.  
  1366. // mtype 0: counts only bots
  1367. // mtype 1: counts only humans
  1368. // mtype 2: counts all players on team
  1369.  
  1370. if (g_ADFreeze) {
  1371. return 0;
  1372. }
  1373.  
  1374. int result;
  1375.  
  1376. if (mtype == 2) {
  1377. static lastSize;
  1378. result = GetTeamClientCount(onteam);
  1379.  
  1380. if (result > 0 && onteam == 2) {
  1381. g_MaxSI = result;
  1382.  
  1383. if (g_MaxSI != lastSize) {
  1384. SetConVarFloat(g_cvMaxSI, float(result));
  1385. lastSize = g_MaxSI;
  1386. }
  1387. }
  1388.  
  1389. return result;
  1390. }
  1391.  
  1392. int j;
  1393. int humans;
  1394. int bots;
  1395.  
  1396. for (int i = 1 ; i <= MaxClients ; i++) {
  1397. j = GetClientManager(i);
  1398.  
  1399. if (j >= 0 && GetClientTeam(i) == onteam) {
  1400. switch (j) {
  1401. case 0: bots++;
  1402. default: humans++;
  1403. }
  1404. }
  1405. }
  1406.  
  1407. switch (mtype) {
  1408. case 0: result = bots;
  1409. case 1: result = humans;
  1410. }
  1411.  
  1412. return result;
  1413. }
  1414.  
  1415. int GetClientManager(int target) {
  1416.  
  1417. int result;
  1418. int userid;
  1419. int client;
  1420.  
  1421. if (GetQRecord(target)) {
  1422. return target;
  1423. }
  1424.  
  1425. else if (IsClientValid(target)) {
  1426. for (int i = 1 ; i <= MaxClients ; i++) {
  1427. if (IsClientValid(i) && IsFakeClient(i) && GetClientTeam(i) == 2) {
  1428.  
  1429. // let's really put a stop to the "idling 2 bots at once" problem
  1430. userid = GetEntData(i, FindSendPropInfo("SurvivorBot", "m_humanSpectatorUserID"));
  1431. client = GetClientOfUserId(userid);
  1432.  
  1433. if (GetQRecord(client) && i != g_target) {
  1434. if (HasEntProp(i, Prop_Send, "m_humanSpectatorUserID")) {
  1435. SetEntProp(i, Prop_Send, "m_humanSpectatorUserID", 0);
  1436. }
  1437. }
  1438. }
  1439. }
  1440.  
  1441. for (int i = 1 ; i <= MaxClients ; i++) {
  1442. if (GetQRecord(i)) {
  1443. if (IsClientValid(g_target) && g_target == target) {
  1444. result = i;
  1445. break;
  1446. }
  1447. }
  1448. }
  1449. }
  1450.  
  1451. else {
  1452. result = -1; // this target is NOT valid
  1453. }
  1454.  
  1455. return result; // target IS valid and NOT managed
  1456. }
  1457.  
  1458. int GetNextBot(int onteam, int skipIndex=0, alive=false) {
  1459.  
  1460. int bot;
  1461.  
  1462. for (int i = 1 ; i <= MaxClients ; i++) {
  1463. if (GetClientManager(i) == 0) {
  1464. if (GetClientTeam(i) == onteam) {
  1465. if (bot == 0) {
  1466. if (!alive || alive && IsPlayerAlive(i)) {
  1467. bot = i;
  1468. }
  1469. }
  1470.  
  1471. if (i > skipIndex) {
  1472. if (!alive || alive && IsPlayerAlive(i)) {
  1473. bot = i;
  1474. break;
  1475. }
  1476. }
  1477. }
  1478. }
  1479. }
  1480.  
  1481. return bot;
  1482. }
  1483.  
  1484. CycleBots(int client, int onteam) {
  1485.  
  1486. if (onteam <= 1) {
  1487. return;
  1488. }
  1489.  
  1490. if (GetQRecord(client)) {
  1491. int bot = GetNextBot(onteam, g_lastid, true);
  1492. if (GetClientManager(bot) == 0) {
  1493. SwitchToBot(client, bot, false);
  1494. }
  1495. }
  1496. }
  1497.  
  1498. SwitchTeam(int client, int onteam, char model[32]="") {
  1499.  
  1500. if (GetQRecord(client)) {
  1501. switch (onteam) {
  1502. case 0: GoIdle(client, 0);
  1503. case 1: GoIdle(client, 1);
  1504. //case 4: ChangeClientTeam(client, 4);
  1505. default: {
  1506. if (onteam <= 3 && onteam >= 2) {
  1507. if (g_onteam != onteam) {
  1508. GoIdle(client, 1);
  1509. }
  1510.  
  1511. g_QRecord.SetValue("queued", true, true);
  1512. g_QRecord.SetValue("onteam", onteam, true);
  1513.  
  1514. if (onteam == 3) {
  1515.  
  1516. if (g_IsVs) {
  1517. ChangeClientTeam(client, 3);
  1518. return;
  1519. }
  1520.  
  1521. switch (g_model[0] == EOS && model[0] != EOS) {
  1522. case 1: CleanSIName(model);
  1523. case 0: {
  1524. Format(model, sizeof(model), "%s", g_model);
  1525. CleanSIName(model);
  1526. }
  1527. }
  1528.  
  1529. g_QRecord.SetString("model", model, true);
  1530. QueueUp(client, 3);
  1531. AddInfected(1, model);
  1532. return;
  1533. }
  1534.  
  1535. Takeover(client, onteam);
  1536. }
  1537. }
  1538. }
  1539. }
  1540. }
  1541.  
  1542. public Action AddBotsCmd(int client, args) {
  1543.  
  1544. switch(args) {
  1545. case 2: {
  1546. GetCmdArg(1, g_sB, sizeof(g_sB));
  1547. int asmany = StringToInt(g_sB);
  1548. GetCmdArg(2, g_sB, sizeof(g_sB));
  1549. int onteam = StringToInt(g_sB);
  1550.  
  1551. if (onteam >= 2 || onteam <= 3) {
  1552. AddBots(asmany, onteam);
  1553. }
  1554. }
  1555. }
  1556. }
  1557.  
  1558. AddBots(int asmany, int onteam) {
  1559.  
  1560. if (asmany < 0) {
  1561. asmany = asmany * -1 - CountTeamMates(onteam);
  1562. }
  1563.  
  1564. float rate;
  1565. DataPack pack = new DataPack();
  1566.  
  1567. switch (onteam) {
  1568. case 2: rate = 0.2;
  1569. case 3: rate = 0.4;
  1570. }
  1571.  
  1572. CreateDataTimer(rate, AddBotsTimer, pack, TIMER_REPEAT);
  1573. pack.WriteCell(asmany);
  1574. pack.WriteCell(onteam);
  1575. }
  1576.  
  1577. public Action AddBotsTimer(Handle timer, Handle pack) {
  1578.  
  1579. static i;
  1580.  
  1581. ResetPack(pack);
  1582. int asmany = ReadPackCell(pack);
  1583. int onteam = ReadPackCell(pack);
  1584.  
  1585. if (i++ < asmany) {
  1586. switch (onteam) {
  1587. case 2: AddSurvivor();
  1588. case 3: AddInfected();
  1589. }
  1590.  
  1591. return Plugin_Continue;
  1592. }
  1593.  
  1594. i = 0;
  1595. return Plugin_Stop;
  1596. }
  1597.  
  1598. public Action RemBotsCmd(int client, args) {
  1599.  
  1600. int asmany;
  1601. int onteam;
  1602.  
  1603. switch(args) {
  1604. case 1: {
  1605. GetCmdArg(1, g_sB, sizeof(g_sB));
  1606. onteam = StringToInt(g_sB);
  1607. asmany = MaxClients;
  1608. }
  1609.  
  1610. case 2: {
  1611. GetCmdArg(1, g_sB, sizeof(g_sB));
  1612. asmany = StringToInt(g_sB);
  1613. GetCmdArg(2, g_sB, sizeof(g_sB));
  1614. onteam = StringToInt(g_sB);
  1615. }
  1616. }
  1617.  
  1618. if (onteam >= 2 || onteam <= 3) {
  1619. RemBots(asmany, onteam);
  1620. }
  1621. }
  1622.  
  1623. RemBots(int asmany, int onteam) {
  1624.  
  1625. int j;
  1626.  
  1627. if (onteam == 0) {
  1628. onteam = asmany;
  1629. asmany = MaxClients;
  1630. }
  1631.  
  1632. else if (asmany == -0) {
  1633. return;
  1634. }
  1635.  
  1636. else if (asmany < 0) {
  1637. asmany += CountTeamMates(onteam);
  1638. if (asmany <= 0) {
  1639. return;
  1640. }
  1641. }
  1642.  
  1643. for (int i = MaxClients ; i >= 1 ; i--) {
  1644. if (GetClientManager(i) == 0 && GetClientTeam(i) == onteam) {
  1645.  
  1646. j++;
  1647. StripClient(i);
  1648. KickClient(i);
  1649.  
  1650. if (j >= asmany) {
  1651. break;
  1652. }
  1653. }
  1654. }
  1655. }
  1656.  
  1657. // ================================================================== //
  1658. // MODEL FEATURES
  1659. // ================================================================== //
  1660.  
  1661. public Action AutoModelTimer(Handle timer, any client) {
  1662.  
  1663. if (!IsClientValid(client)) {
  1664. return Plugin_Handled;
  1665. }
  1666.  
  1667. int target = GetClientManager(client);
  1668. if (GetQRecord(target) && g_model[0] != EOS) {
  1669. return Plugin_Handled;
  1670. }
  1671.  
  1672. int smq[8]; // survivor model queue
  1673. int model;
  1674. int count;
  1675.  
  1676. for (int i = 1 ; i <= MaxClients ; i++) {
  1677. if (IsClientValid(i) && GetClientTeam(i) == 2) {
  1678. model = GetClientModelIndex(i);
  1679.  
  1680. if (model != -1) {
  1681. smq[model]++;
  1682. }
  1683. }
  1684. }
  1685.  
  1686. model = GetClientModelIndex(client);
  1687. if (model == -1) model = 0;
  1688. count = smq[model];
  1689.  
  1690. if (count <= 1 || count <= CountTeamMates(2) / 8) {
  1691. return Plugin_Handled;
  1692. }
  1693.  
  1694. for (int i = 1 ; i <= (MaxClients / 8) + 1 ; i++) {
  1695. for (model = 0 ; model < 8 ; model++) {
  1696. if (smq[model] < i) {
  1697. i = MaxClients;
  1698. break;
  1699. }
  1700. }
  1701. }
  1702.  
  1703. AssignModel(client, g_SurvivorNames[model]);
  1704. return Plugin_Handled;
  1705. }
  1706.  
  1707. PrecacheModels() {
  1708.  
  1709. for (int i = 0 ; i < sizeof(g_SurvivorPaths) ; i++) {
  1710. Format(g_sB, sizeof(g_sB), "%s", g_SurvivorPaths[i]);
  1711. if (!IsModelPrecached(g_sB)) {
  1712. PrecacheModel(g_sB);
  1713. }
  1714. }
  1715. }
  1716.  
  1717. AssignModel(int client, char [] model) {
  1718.  
  1719. if (GetClientTeam(client) != 2 || IsClientsModel(client, model)) {
  1720. return;
  1721. }
  1722.  
  1723. if (IsClientValid(client)) {
  1724. int i = GetModelIndexByName(model);
  1725.  
  1726. if (i >= 0 && i < sizeof(g_SurvivorPaths)) {
  1727.  
  1728. SetEntityModel(client, g_SurvivorPaths[i]);
  1729. Format(g_pN, sizeof(g_pN), "%s", g_SurvivorNames[i]);
  1730.  
  1731. if (IsFakeClient(client)) {
  1732. SetClientInfo(client, "name", g_pN);
  1733. int boss = GetClientManager(client);
  1734.  
  1735. if (boss > 0) {
  1736. client = boss;
  1737. }
  1738. }
  1739.  
  1740. if (GetQRecord(client)) {
  1741. g_QRecord.SetString("model", g_pN);
  1742. }
  1743. }
  1744. }
  1745. }
  1746.  
  1747. int GetClientModelIndex(int client) {
  1748.  
  1749. if (!IsClientValid(client)) {
  1750. return -2;
  1751. }
  1752.  
  1753. char modelName[64];
  1754.  
  1755. GetEntPropString(client, Prop_Data, "m_ModelName", modelName, sizeof(modelName));
  1756. for (int i = 0 ; i < sizeof(g_SurvivorPaths) ; i++) {
  1757. if (StrEqual(modelName, g_SurvivorPaths[i], false)) {
  1758. return i;
  1759. }
  1760. }
  1761.  
  1762. return -1;
  1763. }
  1764.  
  1765. int GetModelIndexByName(char [] name, int onteam=2) {
  1766.  
  1767. if (onteam == 2) {
  1768. for (int i ; i < sizeof(g_SurvivorNames) ; i ++) {
  1769. if (StrContains(name, g_SurvivorNames[i], false) != -1) {
  1770. return i;
  1771. }
  1772. }
  1773. }
  1774.  
  1775. else if (onteam == 3) {
  1776. for (int i ; i < sizeof(g_InfectedNames) ; i ++) {
  1777. if (StrContains(g_InfectedNames[i], name, false) != -1) {
  1778. return i;
  1779. }
  1780. }
  1781. }
  1782.  
  1783. return -1;
  1784. }
  1785.  
  1786. bool IsClientsModel(int client, char [] name) {
  1787.  
  1788. int modelIndex = GetClientModelIndex(client);
  1789. Format(g_sB, sizeof(g_sB), "%s", g_SurvivorNames[modelIndex]);
  1790. return StrEqual(name, g_sB);
  1791. }
  1792.  
  1793. // ================================================================== //
  1794. // BLACK MAGIC SIGNATURES. SOME SPOOKY SHIT.
  1795. // ================================================================== //
  1796.  
  1797. void RoundRespawnSig(int client) {
  1798.  
  1799. static Handle hRoundRespawn;
  1800. if (hRoundRespawn == null) {
  1801. StartPrepSDKCall(SDKCall_Player);
  1802. PrepSDKCall_SetFromConf(g_GameData, SDKConf_Signature, "RoundRespawn");
  1803. hRoundRespawn = EndPrepSDKCall();
  1804. }
  1805.  
  1806. if (hRoundRespawn != null) {
  1807. SDKCall(hRoundRespawn, client);
  1808. }
  1809.  
  1810. else {
  1811. PrintToChat(client, "[ABM] RoundRespawnSig Signature broken.");
  1812. SetFailState("[ABM] RoundRespawnSig Signature broken.");
  1813. }
  1814. }
  1815.  
  1816. void SetHumanSpecSig(int bot, int client) {
  1817.  
  1818. static Handle hSpec;
  1819. if (hSpec == null) {
  1820. StartPrepSDKCall(SDKCall_Player);
  1821. PrepSDKCall_SetFromConf(g_GameData, SDKConf_Signature, "SetHumanSpec");
  1822. PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
  1823. hSpec = EndPrepSDKCall();
  1824. }
  1825.  
  1826. if(hSpec != null) {
  1827. SDKCall(hSpec, bot, client);
  1828. }
  1829.  
  1830. else {
  1831. PrintToChat(client, "[ABM] SetHumanSpecSig Signature broken.");
  1832. SetFailState("[ABM] SetHumanSpecSig Signature broken.");
  1833. }
  1834. }
  1835.  
  1836. void State_TransitionSig(int client, int mode) {
  1837.  
  1838. static Handle hSpec;
  1839. if (hSpec == null) {
  1840. StartPrepSDKCall(SDKCall_Player);
  1841. PrepSDKCall_SetFromConf(g_GameData, SDKConf_Signature, "State_Transition");
  1842. PrepSDKCall_AddParameter(SDKType_PlainOldData , SDKPass_Plain);
  1843. hSpec = EndPrepSDKCall();
  1844. }
  1845.  
  1846. if(hSpec != null) {
  1847. SDKCall(hSpec, client, mode); // mode 8, press 8 to get closer
  1848. }
  1849.  
  1850. else {
  1851. PrintToChat(client, "[ABM] State_TransitionSig Signature broken.");
  1852. SetFailState("[ABM] State_TransitionSig Signature broken.");
  1853. }
  1854. }
  1855.  
  1856. bool TakeoverBotSig(int client, int bot) {
  1857.  
  1858. if (!GetQRecord(client)) {
  1859. return false;
  1860. }
  1861.  
  1862. static Handle hSwitch;
  1863. if (hSwitch == null) {
  1864. StartPrepSDKCall(SDKCall_Player);
  1865. PrepSDKCall_SetFromConf(g_GameData, SDKConf_Signature, "TakeOverBot");
  1866. PrepSDKCall_AddParameter(SDKType_Bool, SDKPass_Plain);
  1867. hSwitch = EndPrepSDKCall();
  1868. }
  1869.  
  1870. if (hSwitch != null) {
  1871. if (IsClientInKickQueue(bot)) {
  1872. KickClient(bot);
  1873. }
  1874.  
  1875. else if (IsClientValid(bot) && IsFakeClient(bot)) {
  1876. if (GetClientTeam(bot) == 2) {
  1877. SwitchToSpec(client);
  1878. SetHumanSpecSig(bot, client);
  1879. SDKCall(hSwitch, client, true);
  1880.  
  1881. Unqueue(client);
  1882. return true;
  1883. }
  1884. }
  1885. }
  1886.  
  1887. else {
  1888. PrintToChat(client, "[ABM] TakeoverBotSig Signature broken.");
  1889. SetFailState("[ABM] TakeoverBotSig Signature broken.");
  1890. }
  1891.  
  1892. g_QRecord.SetValue("lastid", bot, true);
  1893. if (GetClientTeam(client) == 1) {
  1894. g_QRecord.SetValue("queued", true, true);
  1895. QueueUp(client, 2);
  1896. }
  1897.  
  1898. return false;
  1899. }
  1900.  
  1901. bool TakeoverZombieBotSig(int client, int bot, bool si_ghost) {
  1902.  
  1903. if (!GetQRecord(client)) {
  1904. return false;
  1905. }
  1906.  
  1907. static Handle hSwitch;
  1908. if (hSwitch == null) {
  1909. StartPrepSDKCall(SDKCall_Player);
  1910. PrepSDKCall_SetFromConf(g_GameData, SDKConf_Signature, "TakeOverZombieBot");
  1911. PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
  1912. hSwitch = EndPrepSDKCall();
  1913. }
  1914.  
  1915. if (hSwitch != null) {
  1916. if (IsClientInKickQueue(bot)) {
  1917. KickClient(bot);
  1918. }
  1919.  
  1920. else if (IsClientValid(bot) && IsFakeClient(bot) && IsPlayerAlive(bot)) {
  1921. if (GetClientTeam(bot) == 3) {
  1922. SwitchToSpec(client);
  1923. SDKCall(hSwitch, client, bot);
  1924.  
  1925. if (si_ghost) {
  1926. State_TransitionSig(client, 8);
  1927. }
  1928.  
  1929. Unqueue(client);
  1930. g_AssistedSpawning = true;
  1931. return true;
  1932. }
  1933. }
  1934. }
  1935.  
  1936. else {
  1937. PrintToChat(client, "[ABM] TakeoverZombieBotSig Signature broken.");
  1938. SetFailState("[ABM] TakeoverZombieBotSig Signature broken.");
  1939. }
  1940.  
  1941. g_QRecord.SetValue("lastid", bot, true);
  1942. if (GetClientTeam(client) == 1) {
  1943. g_QRecord.SetValue("queued", true, true);
  1944. QueueUp(client, 3);
  1945. }
  1946.  
  1947. return false;
  1948. }
  1949.  
  1950. // ================================================================== //
  1951. // PUBLIC INTERFACE AND MENU HANDLERS
  1952. // ================================================================== //
  1953.  
  1954. public Action TeleportClientCmd(int client, args) {
  1955.  
  1956. int level;
  1957.  
  1958. switch(args) {
  1959. case 1: {
  1960. GetCmdArg(1, g_sB, sizeof(g_sB));
  1961. menuArg1 = StringToInt(g_sB);
  1962. }
  1963.  
  1964. case 2: {
  1965. GetCmdArg(1, g_sB, sizeof(g_sB));
  1966. menuArg0 = StringToInt(g_sB);
  1967. GetCmdArg(2, g_sB, sizeof(g_sB));
  1968. menuArg1 = StringToInt(g_sB);
  1969. }
  1970. }
  1971.  
  1972. if (args) {
  1973. level = 2;
  1974. }
  1975.  
  1976. TeleportClientHandler(client, level);
  1977. return Plugin_Handled;
  1978. }
  1979.  
  1980. public TeleportClientHandler(int client, int level) {
  1981.  
  1982. if (!RegMenuHandler(client, "TeleportClientHandler", level, 0)) {
  1983. return;
  1984. }
  1985.  
  1986. switch(level) {
  1987. case 0: TeamMatesMenu(client, "Teleport Client", 2, 1);
  1988. case 1: {
  1989. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  1990. Format(g_sB, sizeof(g_sB), "%s: Teleporting", g_sB);
  1991. TeamMatesMenu(client, g_sB, 2, 1);
  1992. }
  1993.  
  1994. case 2: {
  1995. if (CanClientTarget(client, menuArg0)) {
  1996. if (GetClientTeam(menuArg0) <= 1) {
  1997. menuArg0 = GetPlayClient(menuArg0);
  1998. }
  1999.  
  2000. TeleportClient(menuArg0, menuArg1);
  2001. }
  2002.  
  2003. GenericMenuCleaner(client);
  2004. }
  2005. }
  2006. }
  2007.  
  2008. public Action SwitchTeamCmd(int client, args) {
  2009.  
  2010. int level;
  2011.  
  2012. char model[32];
  2013. GetCmdArg(args, model, sizeof(model));
  2014. int result = StringToInt(model);
  2015.  
  2016. if (args == 1 || args == 2 && result == 0) {
  2017. menuArg0 = client;
  2018. GetCmdArg(1, g_sB, sizeof(g_sB));
  2019. menuArg1 = StringToInt(g_sB);
  2020. }
  2021.  
  2022. else if (args >= 2) {
  2023. GetCmdArg(1, g_sB, sizeof(g_sB));
  2024. menuArg0 = StringToInt(g_sB);
  2025. GetCmdArg(2, g_sB, sizeof(g_sB));
  2026. menuArg1 = StringToInt(g_sB);
  2027. }
  2028.  
  2029. if (args) {
  2030. level = 2;
  2031. }
  2032.  
  2033. else if (!IsAdmin(client)) {
  2034. menuArg0 = client;
  2035. level = 1;
  2036. }
  2037.  
  2038. if (menuArg1 == 3 && GetQRecord(menuArg0)) {
  2039. g_QRecord.SetString("model", model);
  2040. }
  2041.  
  2042. SwitchTeamHandler(client, level);
  2043. return Plugin_Handled;
  2044. }
  2045.  
  2046. public SwitchTeamHandler(int client, int level) {
  2047.  
  2048. if (!RegMenuHandler(client, "SwitchTeamHandler", level, 0)) {
  2049. return;
  2050. }
  2051.  
  2052. switch(level) {
  2053. case 0: TeamMatesMenu(client, "Switch Client's Team", 1);
  2054. case 1: {
  2055. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  2056. Format(g_sB, sizeof(g_sB), "%s: Switching", g_sB);
  2057. TeamsMenu(client, g_sB);
  2058. }
  2059.  
  2060. case 2: {
  2061. if (CanClientTarget(client, menuArg0)) {
  2062. if (!IsAdmin(client) && menuArg1 == 3) {
  2063. GenericMenuCleaner(client);
  2064. return;
  2065. }
  2066.  
  2067. SwitchTeam(menuArg0, menuArg1);
  2068. }
  2069.  
  2070. GenericMenuCleaner(client);
  2071. }
  2072. }
  2073. }
  2074.  
  2075. public Action AssignModelCmd(int client, args) {
  2076.  
  2077. int level;
  2078.  
  2079. switch(args) {
  2080. case 1: {
  2081. menuArg0 = client;
  2082. GetCmdArg(1, g_sB, sizeof(g_sB));
  2083. menuArg1 = GetModelIndexByName(g_sB);
  2084. }
  2085.  
  2086. case 2: {
  2087. GetCmdArg(1, g_sB, sizeof(g_sB));
  2088. menuArg1 = GetModelIndexByName(g_sB);
  2089. GetCmdArg(2, g_sB, sizeof(g_sB));
  2090. menuArg0 = StringToInt(g_sB);
  2091. }
  2092. }
  2093.  
  2094. if (args) {
  2095. level = 2;
  2096. }
  2097.  
  2098. AssignModelHandler(client, level);
  2099. return Plugin_Handled;
  2100. }
  2101.  
  2102. public AssignModelHandler(int client, int level) {
  2103.  
  2104. if (!RegMenuHandler(client, "AssignModelHandler", level, 0)) {
  2105. return;
  2106. }
  2107.  
  2108. switch(level) {
  2109. case 0: TeamMatesMenu(client, "Change Client's Model", 2, 0, false);
  2110. case 1: {
  2111. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  2112. Format(g_sB, sizeof(g_sB), "%s: Modeling", g_sB);
  2113. ModelsMenu(client, g_sB);
  2114. }
  2115.  
  2116. case 2: {
  2117. if (CanClientTarget(client, menuArg0)) {
  2118. if (GetClientTeam(menuArg0) <= 1) {
  2119. menuArg0 = GetPlayClient(menuArg0);
  2120. }
  2121.  
  2122. AssignModel(menuArg0, g_SurvivorNames[menuArg1]);
  2123. }
  2124.  
  2125. GenericMenuCleaner(client);
  2126. }
  2127. }
  2128. }
  2129.  
  2130. public Action SwitchToBotCmd(int client, args) {
  2131.  
  2132. int level;
  2133.  
  2134. switch(args) {
  2135. case 1: {
  2136. menuArg0 = client;
  2137. GetCmdArg(1, g_sB, sizeof(g_sB));
  2138. menuArg1 = StringToInt(g_sB);
  2139. }
  2140.  
  2141. case 2: {
  2142. GetCmdArg(1, g_sB, sizeof(g_sB));
  2143. menuArg0 = StringToInt(g_sB);
  2144. GetCmdArg(2, g_sB, sizeof(g_sB));
  2145. menuArg1 = StringToInt(g_sB);
  2146. }
  2147. }
  2148.  
  2149. if (args) {
  2150. level = 2;
  2151. }
  2152.  
  2153. else if (!IsAdmin(client)) {
  2154. menuArg0 = client;
  2155. level = 1;
  2156. }
  2157.  
  2158. SwitchToBotHandler(client, level);
  2159. return Plugin_Handled;
  2160. }
  2161.  
  2162. public SwitchToBotHandler(int client, int level) {
  2163.  
  2164. int homeTeam = ClientHomeTeam(client);
  2165. if (!RegMenuHandler(client, "SwitchToBotHandler", level, 0)) {
  2166. return;
  2167. }
  2168.  
  2169. switch(level) {
  2170. case 0: TeamMatesMenu(client, "Takeover Bot", 1);
  2171. case 1: {
  2172. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  2173. Format(g_sB, sizeof(g_sB), "%s: Takeover", g_sB);
  2174. TeamMatesMenu(client, g_sB, 0, 0, true, false, homeTeam);
  2175. }
  2176.  
  2177. case 2: {
  2178. if (CanClientTarget(client, menuArg0)) {
  2179. if (IsClientValid(menuArg1)) {
  2180. if (homeTeam != 3 && GetClientTeam(menuArg1) == 3) {
  2181. if (!IsAdmin(client)) {
  2182. GenericMenuCleaner(client);
  2183. return;
  2184. }
  2185. }
  2186.  
  2187. if (GetClientManager(menuArg1) == 0) {
  2188. SwitchToBot(menuArg0, menuArg1, false);
  2189. }
  2190. }
  2191. }
  2192.  
  2193. GenericMenuCleaner(client);
  2194. }
  2195. }
  2196. }
  2197.  
  2198. public Action RespawnClientCmd(int client, args) {
  2199.  
  2200. int level;
  2201.  
  2202. switch(args) {
  2203. case 1: {
  2204. GetCmdArg(1, g_sB, sizeof(g_sB));
  2205. menuArg0 = StringToInt(g_sB);
  2206. menuArg1 = menuArg0;
  2207. }
  2208.  
  2209. case 2: {
  2210. GetCmdArg(1, g_sB, sizeof(g_sB));
  2211. menuArg0 = StringToInt(g_sB);
  2212. GetCmdArg(2, g_sB, sizeof(g_sB));
  2213. menuArg1 = StringToInt(g_sB);
  2214. }
  2215. }
  2216.  
  2217. if (args) {
  2218. level = 2;
  2219. }
  2220.  
  2221. RespawnClientHandler(client, level);
  2222. return Plugin_Handled;
  2223. }
  2224.  
  2225. public RespawnClientHandler(int client, int level) {
  2226.  
  2227. if (!RegMenuHandler(client, "RespawnClientHandler", level, 0)) {
  2228. return;
  2229. }
  2230.  
  2231. switch(level) {
  2232. case 0: TeamMatesMenu(client, "Respawn Client");
  2233. case 1: {
  2234. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  2235. Format(g_sB, sizeof(g_sB), "%s: Respawning", g_sB);
  2236. TeamMatesMenu(client, g_sB);
  2237. }
  2238.  
  2239. case 2: {
  2240. if (CanClientTarget(client, menuArg0)) {
  2241. if (GetClientTeam(menuArg0) <= 1) {
  2242. menuArg0 = GetPlayClient(menuArg0);
  2243. }
  2244.  
  2245. RespawnClient(menuArg0, menuArg1);
  2246. }
  2247.  
  2248. GenericMenuCleaner(client);
  2249. }
  2250. }
  2251. }
  2252.  
  2253. public Action CycleBotsCmd(int client, args) {
  2254.  
  2255. int level;
  2256.  
  2257. switch(args) {
  2258. case 1: {
  2259. menuArg0 = client;
  2260. GetCmdArg(1, g_sB, sizeof(g_sB));
  2261. menuArg1 = StringToInt(g_sB);
  2262. }
  2263.  
  2264. case 2: {
  2265. GetCmdArg(1, g_sB, sizeof(g_sB));
  2266. menuArg0 = StringToInt(g_sB);
  2267. GetCmdArg(2, g_sB, sizeof(g_sB));
  2268. menuArg1 = StringToInt(g_sB);
  2269. }
  2270. }
  2271.  
  2272. if (args) {
  2273. if (menuArg1 > 3 || menuArg1 < 2) {
  2274. return Plugin_Handled;
  2275. }
  2276.  
  2277. level = 2;
  2278. }
  2279.  
  2280. CycleBotsHandler(client, level);
  2281. return Plugin_Handled;
  2282. }
  2283.  
  2284. public CycleBotsHandler(int client, int level) {
  2285.  
  2286. if (!RegMenuHandler(client, "CycleBotsHandler", level, 0)) {
  2287. return;
  2288. }
  2289.  
  2290. switch(level) {
  2291. case 0: TeamMatesMenu(client, "Cycle Client", 1);
  2292. case 1: {
  2293. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  2294. Format(g_sB, sizeof(g_sB), "%s: Cycling", g_sB);
  2295. TeamsMenu(client, g_sB, false);
  2296. }
  2297.  
  2298. case 2: {
  2299. if (CanClientTarget(client, menuArg0)) {
  2300. if (!IsAdmin(client) && menuArg1 == 3) {
  2301. GenericMenuCleaner(client);
  2302. return;
  2303. }
  2304.  
  2305. CycleBots(menuArg0, menuArg1);
  2306. menuArg1 = 0;
  2307. }
  2308.  
  2309. CycleBotsHandler(client, 1);
  2310. }
  2311. }
  2312. }
  2313.  
  2314. public Action StripClientCmd(int client, args) {
  2315.  
  2316. int target;
  2317. int level;
  2318.  
  2319. switch(args) {
  2320. case 1: {
  2321. GetCmdArg(1, g_sB, sizeof(g_sB));
  2322. target = StringToInt(g_sB);
  2323. target = GetPlayClient(target);
  2324.  
  2325. if (CanClientTarget(client, target)) {
  2326. StripClient(target);
  2327. }
  2328.  
  2329. return Plugin_Handled;
  2330. }
  2331.  
  2332. case 2: {
  2333. GetCmdArg(1, g_sB, sizeof(g_sB));
  2334. menuArg0 = StringToInt(g_sB);
  2335. GetCmdArg(2, g_sB, sizeof(g_sB));
  2336. menuArg1 = StringToInt(g_sB);
  2337. }
  2338. }
  2339.  
  2340. if (args) {
  2341. level = 2;
  2342. }
  2343.  
  2344. StripClientHandler(client, level);
  2345. return Plugin_Handled;
  2346. }
  2347.  
  2348. public StripClientHandler(int client, int level) {
  2349.  
  2350. if (!RegMenuHandler(client, "StripClientHandler", level, 0)) {
  2351. return;
  2352. }
  2353.  
  2354. switch(level) {
  2355. case 0: TeamMatesMenu(client, "Strip Client", 2, 1);
  2356. case 1: {
  2357. GetClientName(menuArg0, g_sB, sizeof(g_sB));
  2358. Format(g_sB, sizeof(g_sB), "%s: Stripping", g_sB);
  2359. InvSlotsMenu(client, menuArg0, g_sB);
  2360. }
  2361.  
  2362. case 2: {
  2363. if (CanClientTarget(client, menuArg0)) {
  2364. if (GetClientTeam(menuArg0) <= 1) {
  2365. menuArg0 = GetPlayClient(menuArg0);
  2366. }
  2367.  
  2368. StripClientSlot(menuArg0, menuArg1);
  2369. menuArg1 = 0;
  2370. StripClientHandler(client, 1);
  2371. }
  2372. }
  2373. }
  2374. }
  2375.  
  2376. public Action ResetCmd(int client, args) {
  2377.  
  2378. for (int i = 1 ; i <= MaxClients ; i++) {
  2379. GenericMenuCleaner(i);
  2380. if (GetQRecord(i)) {
  2381. CancelClientMenu(i, true, null);
  2382. }
  2383. }
  2384. }
  2385.  
  2386. bool RegMenuHandler(int client, char [] handler, int level, int clearance=0) {
  2387.  
  2388. g_callBacks.PushString(handler);
  2389. if (!IsAdmin(client) && level <= clearance) {
  2390. GenericMenuCleaner(client);
  2391. return false;
  2392. }
  2393.  
  2394. return true;
  2395. }
  2396.  
  2397. public Action MainMenuCmd(int client, args) {
  2398.  
  2399. GenericMenuCleaner(client);
  2400. MainMenuHandler(client, 0);
  2401. return Plugin_Handled;
  2402. }
  2403.  
  2404. public MainMenuHandler(int client, int level) {
  2405.  
  2406. if (!RegMenuHandler(client, "MainMenuHandler", level, 0)) {
  2407. return;
  2408. }
  2409.  
  2410. int cmd = menuArg0;
  2411. menuArg0 = 0;
  2412.  
  2413. char title[32];
  2414. Format(title, sizeof(title), "ABM Menu %s", PLUGIN_VERSION);
  2415.  
  2416. switch(level) {
  2417. case 0: MainMenu(client, title);
  2418. case 1: {
  2419. switch(cmd) {
  2420. case 0: TeleportClientCmd(client, 0);
  2421. case 1: SwitchTeamCmd(client, 0);
  2422. case 2: AssignModelCmd(client, 0);
  2423. case 3: SwitchToBotCmd(client, 0);
  2424. case 4: RespawnClientCmd(client, 0);
  2425. case 5: CycleBotsCmd(client, 0);
  2426. case 6: StripClientCmd(client, 0);
  2427. }
  2428. }
  2429. }
  2430. }
  2431.  
  2432. // ================================================================== //
  2433. // MENUS BACKBONE
  2434. // ================================================================== //
  2435.  
  2436. GenericMenuCleaner(int client, bool clearStack=true) {
  2437.  
  2438. for (int i = 0 ; i < sizeof(g_menuItems[]) ; i++) {
  2439. g_menuItems[client][i] = 0;
  2440. }
  2441.  
  2442. if (clearStack == true) {
  2443. if (g_callBacks != null) {
  2444. delete g_callBacks;
  2445. }
  2446.  
  2447. g_callBacks = new ArrayStack(128);
  2448. }
  2449. }
  2450.  
  2451. public GenericMenuHandler(Menu menu, MenuAction action, int param1, int param2) {
  2452.  
  2453. int client = param1;
  2454. int i; // -1;
  2455. char sB[128];
  2456.  
  2457. if (IsClientValid(param1)) {
  2458. for (i = 0 ; i < sizeof(g_menuItems[]) ; i++) {
  2459. if (menuArgs[i] == 0) {
  2460. break;
  2461. }
  2462. }
  2463. }
  2464.  
  2465. switch(action) {
  2466. case MenuAction_Select: {
  2467. menu.GetItem(param2, g_sB, sizeof(g_sB));
  2468. menuArgs[i] = StringToInt(g_sB);
  2469. i = i + 1;
  2470. }
  2471.  
  2472. case MenuAction_Cancel: {
  2473. if (param2 == MenuCancel_ExitBack) {
  2474. if (i > 0) {
  2475. i = i - 1;
  2476. menuArgs[i] = 0;
  2477. }
  2478.  
  2479. else if (i == 0) {
  2480.  
  2481. if (g_callBacks.Empty) {
  2482. GenericMenuCleaner(param1);
  2483. return;
  2484. }
  2485.  
  2486. g_callBacks.PopString(g_sB, sizeof(g_sB));
  2487. GenericMenuCleaner(param1, false);
  2488.  
  2489. while (!g_callBacks.Empty) {
  2490. g_callBacks.PopString(sB, sizeof(sB));
  2491.  
  2492. if (!StrEqual(g_sB, sB)) {
  2493. g_callBacks.PushString(sB);
  2494. break;
  2495. }
  2496. }
  2497.  
  2498. if (g_callBacks.Empty) {
  2499. GenericMenuCleaner(param1);
  2500. return;
  2501. }
  2502. }
  2503. }
  2504.  
  2505. else {
  2506. return;
  2507. }
  2508. }
  2509.  
  2510. case MenuAction_End: {
  2511. delete menu;
  2512. return;
  2513. }
  2514. }
  2515.  
  2516. if (g_callBacks == null || g_callBacks.Empty) {
  2517. GenericMenuCleaner(param1);
  2518. return;
  2519. }
  2520.  
  2521. g_callBacks.PopString(g_sB, sizeof(g_sB));
  2522. callBack = GetFunctionByName(null, g_sB);
  2523.  
  2524. Call_StartFunction(null, callBack);
  2525. Call_PushCell(param1);
  2526. Call_PushCell(i);
  2527. Call_Finish();
  2528. }
  2529.  
  2530. // ================================================================== //
  2531. // MENUS
  2532. // ================================================================== //
  2533.  
  2534. MainMenu(int client, char [] title) {
  2535.  
  2536. Menu menu = new Menu(GenericMenuHandler);
  2537. menu.SetTitle(title);
  2538. menu.AddItem("0", "Teleport Client"); // "Telespiznat"); // teleport
  2539. menu.AddItem("1", "Switch Client Team"); //"Swintootle"); // switch team
  2540. menu.AddItem("2", "Change Client Model"); //"Changdangle"); // makeover
  2541. menu.AddItem("3", "Switch Client Bot"); //"Inbosnachup"); // takeover
  2542. menu.AddItem("4", "Respawn Client"); //"Respiggle"); // respawn
  2543. menu.AddItem("5", "Cycle Client"); //"Cycolicoo"); // cycle
  2544. menu.AddItem("6", "Strip Client"); //"Upsticky"); // strip
  2545. menu.ExitBackButton = true;
  2546. menu.ExitButton = true;
  2547. menu.Display(client, 120);
  2548. }
  2549.  
  2550. InvSlotsMenu(int client, int target, char [] title) {
  2551.  
  2552. int ent;
  2553. char weapon[64];
  2554. Menu menu = new Menu(GenericMenuHandler);
  2555. menu.SetTitle(title);
  2556.  
  2557. for (int i ; i < 5 ; i++) {
  2558. IntToString(i, g_sB, sizeof(g_sB));
  2559. ent = GetPlayerWeaponSlot(target, i);
  2560.  
  2561. if (IsValidEntity(ent)) {
  2562. GetEntityClassname(ent, weapon, sizeof(weapon));
  2563. menu.AddItem(g_sB, weapon);
  2564. }
  2565. }
  2566.  
  2567. menu.ExitBackButton = true;
  2568. menu.ExitButton = true;
  2569. menu.Display(client, 120);
  2570. }
  2571.  
  2572. ModelsMenu(int client, char [] title) {
  2573.  
  2574. Menu menu = new Menu(GenericMenuHandler);
  2575. menu.SetTitle(title);
  2576.  
  2577. for (int i ; i < sizeof(g_SurvivorNames) ; i++) {
  2578. IntToString(i, g_sB, sizeof(g_sB));
  2579. menu.AddItem(g_sB, g_SurvivorNames[i]);
  2580. }
  2581.  
  2582. menu.ExitBackButton = true;
  2583. menu.ExitButton = true;
  2584. menu.Display(client, 120);
  2585. }
  2586.  
  2587. TeamsMenu(int client, char [] title, bool all=true) {
  2588.  
  2589. Menu menu = new Menu(GenericMenuHandler);
  2590. menu.SetTitle(title);
  2591.  
  2592. if (all) {
  2593. menu.AddItem("0", "Idler");
  2594. menu.AddItem("1", "Spectator");
  2595. }
  2596.  
  2597. menu.AddItem("2", "Survivor");
  2598. if (IsAdmin(client)) {
  2599. menu.AddItem("3", "Infected");
  2600. }
  2601.  
  2602. menu.ExitBackButton = true;
  2603. menu.ExitButton = true;
  2604. menu.Display(client, 120);
  2605. }
  2606.  
  2607. TeamMatesMenu(int client, char [] title, int mtype=2, int target=0, bool incDead=true,
  2608. bool repeat=false, int homeTeam=0) {
  2609.  
  2610. Menu menu = new Menu(GenericMenuHandler);
  2611. menu.SetTitle(title);
  2612. int isAdmin = IsAdmin(client);
  2613. char health[32];
  2614. bool mflag = false;
  2615. int isAlive;
  2616. int playClient;
  2617. int bossClient;
  2618. int targetClient;
  2619. int manager;
  2620.  
  2621. for (int i = 1 ; i <= MaxClients ; i++) {
  2622. bossClient = i;
  2623. playClient = i;
  2624.  
  2625. if (GetQRecord(i)) {
  2626.  
  2627. if (mtype == 0) {
  2628. continue;
  2629. }
  2630.  
  2631. if (mtype == 1 || mtype == 2) {
  2632. mflag = true;
  2633. }
  2634.  
  2635. if (IsClientValid(g_target) && g_target != i) {
  2636. isAlive = IsPlayerAlive(g_target);
  2637. playClient = g_target;
  2638. }
  2639.  
  2640. else {
  2641. isAlive = IsPlayerAlive(i);
  2642. }
  2643. }
  2644.  
  2645. else if (IsClientValid(i)) {
  2646. isAlive = IsPlayerAlive(i);
  2647.  
  2648. if (mtype == 0 || mtype == 2) {
  2649. mflag = true;
  2650. }
  2651.  
  2652. manager = GetClientManager(i);
  2653.  
  2654. if (manager != 0) {
  2655. if (target == 0 || !repeat) {
  2656. mflag = false;
  2657. continue;
  2658. }
  2659.  
  2660. bossClient = manager;
  2661. }
  2662. }
  2663.  
  2664. else {
  2665. continue;
  2666. }
  2667.  
  2668. // at this point the client is valid.
  2669. // bossClient is the human (if there is one)
  2670. // playClient is the bot (or human if not idle)
  2671.  
  2672. if (!isAlive && !incDead) {
  2673. continue;
  2674. }
  2675.  
  2676. if (GetClientTeam(playClient) != homeTeam && !isAdmin) {
  2677. continue;
  2678. }
  2679.  
  2680. switch(target) {
  2681. case 0: targetClient = bossClient;
  2682. case 1: targetClient = playClient;
  2683. }
  2684.  
  2685. if (mflag) {
  2686. mflag = false;
  2687.  
  2688. Format(health, sizeof(health), "%d", GetClientHealth(playClient));
  2689. if (!IsPlayerAlive(playClient)) {
  2690. Format(health, sizeof(health), "DEAD");
  2691. }
  2692.  
  2693. else if (GetEntProp(playClient, Prop_Send, "m_isIncapacitated")) {
  2694. Format(health, sizeof(health), "DOWN");
  2695. }
  2696.  
  2697. GetClientName(bossClient, g_pN, sizeof(g_pN));
  2698. Format(g_pN, sizeof(g_pN), "%s (%s)", g_pN, health);
  2699. IntToString(targetClient, g_sB, sizeof(g_sB));
  2700.  
  2701. switch(bossClient == client && menu.ItemCount > 0) {
  2702. case 0: menu.AddItem(g_sB, g_pN);
  2703. case 1: menu.InsertItem(0, g_sB, g_pN);
  2704. }
  2705. }
  2706. }
  2707.  
  2708. menu.ExitBackButton = true;
  2709. menu.ExitButton = true;
  2710. menu.Display(client, 120);
  2711. }
  2712.  
  2713. // ================================================================== //
  2714. // MISC STUFF USEFUL FOR TROUBLESHOOTING
  2715. // ================================================================== //
  2716.  
  2717. QDBCheckCmd(client) {
  2718.  
  2719. PrintToConsole(client, "-- STAT: QDB Size is %d", g_QDB.Size);
  2720. PrintToConsole(client, "-- MinPlayers is %d", g_MinPlayers);
  2721.  
  2722. for (int i = 1 ; i <= MaxClients ; i++) {
  2723. if (GetQRecord(i)) {
  2724. PrintToConsole(client, "\n -");
  2725. GetClientName(i, g_pN, sizeof(g_pN));
  2726.  
  2727. float x = g_origin[0];
  2728. float y = g_origin[1];
  2729. float z = g_origin[2];
  2730.  
  2731. PrintToConsole(client, " - Name: %s", g_pN);
  2732. PrintToConsole(client, " - Origin: {%d.0, %d.0, %d.0}", x, y, z);
  2733. PrintToConsole(client, " - Status: %d", IsPlayerAlive(i));
  2734. PrintToConsole(client, " - Client: %d", g_client);
  2735. PrintToConsole(client, " - Target: %d", g_target);
  2736. PrintToConsole(client, " - LastId: %d", g_lastid);
  2737. PrintToConsole(client, " - OnTeam: %d", g_onteam);
  2738. PrintToConsole(client, " - Queued: %d", g_queued);
  2739. PrintToConsole(client, " - InSpec: %d", g_inspec);
  2740.  
  2741. if (GetClientTeam(i) == 2) {
  2742. int j = GetClientModelIndex(i);
  2743. if (j != -1) {
  2744. PrintToConsole(client, " - Initialized Model: %s", g_SurvivorNames[j]);
  2745. }
  2746. }
  2747.  
  2748. PrintToConsole(client, " - Model: %s", g_model);
  2749. PrintToConsole(client, " -\n");
  2750. }
  2751. }
  2752. }
  2753.  
  2754. public Action QuickClientPrintCmd(int client, args) {
  2755.  
  2756. int onteam;
  2757. int state;
  2758. int manager;
  2759.  
  2760. PrintToConsole(client, "\nTeam\tState\tId\tManager\tName");
  2761.  
  2762. for (int i = 1 ; i <= MaxClients ; i++) {
  2763. if (IsClientValid(i)) {
  2764. manager = i;
  2765. GetClientName(i, g_pN, sizeof(g_pN));
  2766. onteam = GetClientTeam(i);
  2767. state = IsPlayerAlive(i);
  2768.  
  2769.  
  2770. if (IsFakeClient(i)) {
  2771. manager = GetClientManager(i);
  2772. }
  2773.  
  2774. PrintToConsole(client,
  2775. "%d, \t%d, \t%d, \t%d, \t%s", onteam, state, i, manager, g_pN
  2776. );
  2777. }
  2778. }
  2779.  
  2780. QDBCheckCmd(client);
  2781. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement