Advertisement
Guest User

teammanager.sp

a guest
May 17th, 2013
355
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.81 KB | None | 0 0
  1. #define TEAM_SPECTATOR 1
  2. #define TEAM_SURVIVORS 2
  3. #define TEAM_INFECTED 3
  4.  
  5. #define ZOMBIECLASS_SMOKER 1
  6. #define ZOMBIECLASS_BOOMER 2
  7. #define ZOMBIECLASS_HUNTER 3
  8. #define ZOMBIECLASS_SPITTER 4
  9. #define ZOMBIECLASS_JOCKEY 5
  10. #define ZOMBIECLASS_CHARGER 6
  11. #define ZOMBIECLASS_TANK 8
  12.  
  13. #define PLUGIN_VERSION "2.3.4"
  14. #define PLAYERPLUS_VERSION "1.2"
  15. #define EAVESDROP_VERSION "1.1"
  16.  
  17. #define CVAR_SHOW FCVAR_NOTIFY | FCVAR_PLUGIN
  18. #define MAX_CHAT_LENGTH 1024
  19.  
  20. #define CAMPAIGN_ENABLED "Whether or not this campaign shows as a vote-able option in the vote menu."
  21. #define LOGFILE "addons/sourcemod/logs/teammanager/teammanager.log"
  22. #define STEAM_ID_LENGTH 64
  23.  
  24. #define NICK_NET 0
  25. #define ROCHELLE_NET 1
  26. #define COACH_NET 2
  27. #define ELLIS_NET 3
  28. #define ZOEY_NET 5
  29. #define FRANCIS_NET 6
  30. #define LOUIS_NET 7
  31.  
  32. #define NICK_MODEL "models/survivors/survivor_gambler.mdl"
  33. #define ROCHELLE_MODEL "models/survivors/survivor_producer.mdl"
  34. #define COACH_MODEL "models/survivors/survivor_coach.mdl"
  35. #define ELLIS_MODEL "models/survivors/survivor_mechanic.mdl"
  36. #define ZOEY_MODEL "models/survivors/survivor_teenangst.mdl"
  37. #define FRANCIS_MODEL "models/survivors/survivor_biker.mdl"
  38. #define LOUIS_MODEL "models/survivors/survivor_manager.mdl"
  39.  
  40. #include <sourcemod>
  41. #include <sdkhooks>
  42. #include <sdktools>
  43. #include <adminmenu>
  44. #include "left4downtown.inc"
  45. #include <l4d2_direct>
  46. #include "gamemode.inc"
  47. #include "l4d_stocks.inc"
  48. #include "wrap.inc"
  49. #include "readyup.inc"
  50. #include "teammanager/definitions.sp"
  51.  
  52. public Plugin:myinfo = {
  53. name = "Teams Manager",
  54. author = "Sky",
  55. description = "steamcommunity.com/groups/skyrpg",
  56. version = PLUGIN_VERSION,
  57. url = "skyrpg.donations@gmail.com"
  58. }
  59.  
  60. public OnPluginStart()
  61. {
  62. g_SteamgroupCvar = FindConVar("sv_steamgroup");
  63. SetConVarFlags(g_SteamgroupCvar, GetConVarFlags(g_SteamgroupCvar) & ~FCVAR_NOTIFY);
  64.  
  65. g_Module_AFK_Enabled = CreateConVar("teammanager_afk_enabled","1","If enabled, the idle cycle will run, otherwise it won\'t.");
  66. g_Module_AFK_CycleWarn = CreateConVar("teammanager_afk_cyclewarn","30","How many cycles a player must fail before being warned about being kicked.");
  67. g_Module_AFK_CycleKick = CreateConVar("teammanager_afk_cyclekick","45","How many cycles a player must fail to be kicked from the server.");
  68. g_Module_Fly_Enabled = CreateConVar("teammanager_fly_enabled","1","If enabled, infected players will be able to toggle ghost fly with their reload key.");
  69. g_Module_InfectedRotation_Enabled = CreateConVar("teammanager_infectedrotation_enabled","1","If enabled, infected players will have a new infected class assigned to them when they enter ghost mode.");
  70. g_Module_InfectedRotation_Random = CreateConVar("teammanager_infectedrotation_random","1","If enabled, the infected class assigned to infected players will be random. If not, it will follow the order: smoker, boomer, hunter, spitter, jockey, charger.");
  71. g_Module_BlockVote_Enabled = CreateConVar("teammanager_blockvote_enabled","1","If enabled, players will not be able to issue votes outside of the plugin.");
  72. g_Module_Campaign_Enabled = CreateConVar("teammanager_campaign_enabled","1","If enabled, a new campaign will load when one completes, otherwise it will return players to the lobby.");
  73. g_Module_Campaign_Rounds = CreateConVar("teammanager_campaign_rounds","2","The number of rounds before the map changes on a qualifying map.");
  74. g_Module_Campaign_MapchangeDelay = CreateConVar("teammanager_campaign_mapchangedelay","10","The time in seconds before a map changes.");
  75. g_Module_ReserveSettings_TotalSlots = CreateConVar("teammanager_reservesettings_totalslots","8","The total amount of slots on the server.");
  76. g_Module_ReserveSettings_ReserveSlots = CreateConVar("teammanager_reservesettings_reserveslots","0","The total amount of reserve slots on the server.");
  77. g_Module_ReserveSettings_HideReserveSlots = CreateConVar("teammanager_reservesettings_hidereserveslots","1","If enabled, total slots - reserve slots is the value of total slots displayed.");
  78. g_Module_ReserveSettings_AutomatedSlots = CreateConVar("teammanager_reservesettings_automatedslots","1","If enabled, slots are automated. If disabled, slot settings must be defined in this config.");
  79. g_Module_ReserveSettings_SurvivorLimit = CreateConVar("teammanager_reservesettings_survivorlimit","4","If automated slots is disabled, the number of survivor slots.");
  80. g_Module_ReserveSettings_InfectedLimit = CreateConVar("teammanager_reservesettings_infectedlimit","4","If automated slots is disabled, the number of infected slots.");
  81. g_Module_Teams_MaintainTeams = CreateConVar("teammanager_teams_maintainteams","1","Whether or not to make sure players are always on their appropriate team when a new map loads.");
  82. g_Module_Teams_Scramble = CreateConVar("teammanager_teams_scramble","400","The point difference that must exist for teams to be scrambled.");
  83. g_Module_Teams_SmartScramble = CreateConVar("teammanager_teams_smartscramble","1","Smart scramble is based on player rankings, otherwise it\'s completely random.");
  84. g_Module_Teams_ScrambleRequirement = CreateConVar("teammanager_teams_scramblerequirement","8","The number of players required for a scramble to occur.");
  85. g_Module_Teams_SpectatorAllowed = CreateConVar("teammanager_teams_spectatorallowed","1","If enabled, anyone can join the spectator team.");
  86. g_Module_Teams_SpectatorSlots = CreateConVar("teammanager_teams_spectatorslots","1","If enabled, server slots will be automated based on the number of spectators.");
  87. g_Control_FriendlyFire = CreateConVar("teammanager_control_friendlyfire","0","Whether or not friendly fire deals damage.");
  88. g_Control_FriendlyFire_PenaltyAmount = CreateConVar("teammanager_control_friendlyfire_penalty","1","The amount of damage a player takes if they shoot a teammate.");
  89. g_Control_FriendlyFireLimit[0] = CreateConVar("teammanager_friendlyfire_limit_survivor","200","Survivor team friendly fire limit.");
  90. g_Control_FriendlyFireLimit[1] = CreateConVar("teammanager_friendlyfire_limit_infected","1000","Infected team friendly fire limit.");
  91. g_Control_FriendlyFireResponse = CreateConVar("teammanager_control_friendlyfire_response","0","If 0, no response is taken. If 1, the player is kicked. If 2, the player is banned.");
  92. g_Control_FriendlyFireBanTime = CreateConVar("teammanager_control_friendlyfire_bantime","180.0","The amount of time (in minutes) to ban a player for friendly fire, if banning is enabled.");
  93. g_Module_Configs_Enabled = CreateConVar("teammanager_configs_enabled","0","If enabled, team manager will allow gametypevoting and require a default config file.");
  94. g_Module_Configs_Voting = CreateConVar("teammanager_configs_voting_enabled","1","If disabled, gametypevote cannot be called, even if configs are enabled.");
  95. g_Module_Configs_CoopConfig = CreateConVar("teammanager_configs_coopconfig","server_coop.cfg","The config for coop game modes. Changing this in the config will not have any effect.");
  96. g_Module_Configs_VersusConfig = CreateConVar("teammanager_configs_versusconfig","server_versus.cfg","The config for versus game modes. Changing this in the config will not have any effect.");
  97. g_Module_Configs_SurvivalConfig = CreateConVar("teammanager_configs_survivalconfig","server_survival.cfg","The config for survival game modes. Changing this in the config will not have any effect.");
  98. g_Module_Configs_VoteCooldown = CreateConVar("teammanager_configs_votecooldown","900","The amount of time players must wait, in seconds, between gametype votes.");
  99. g_Module_Configs_VoteTime = CreateConVar("teammanager_configs_votetime","30","The amount of time players can vote, in seconds, for a gametype vote.");
  100. g_Survivors = CreateConVar("teammanager_survivor_limit","4","Survivor limit.");
  101. g_Infected = CreateConVar("teammanager_infected_limit","4","Infected limit.");
  102. g_Debug = CreateConVar("teammanager_debug","0","Whether we run debug mode.");
  103. g_CheckTeams_PlayerRequirement = CreateConVar("teammanager_checkteams_requirement","4","The amount of players that must be on both teams for player team count check to occur when a player disconnects or changes teams.");
  104. g_SurvivorBots_KickOnDisconnect = CreateConVar("teammanager_survivorbots_kickondisconnect","0","If enabled, bots are kicked before teams are checked to see if any players need to be team-swapped. Only functions in versus.");
  105. g_Survivors_BotsRequireHumans = CreateConVar("teammanager_survivorbots_requirehumans","1","Extra survivor bots will only be spawned if there is at least one human player on either survivor or infected.");
  106. g_Survivors_MinimumRequired = CreateConVar("teammanager_survivorbots_playersrequired","4","If the criteria are met, there must be at least this many survivors, humans and bots combined.");
  107. g_CoopAllowed = CreateConVar("teammanager_coop_allowed","1","If coop is allowed. This is added since the server seems to crash in coop on the credit screen and not in other game modes.");
  108. g_SmartScrambleCountdown = CreateConVar("teammanager_smartscramble_countdown","5","How long to notify players before smart team scramble occurs.");
  109. g_PingRestriction = CreateConVar("teammanager_restriction_ping","300.0","The maximum ping a player can have on the server.");
  110. g_PackRestriction = CreateConVar("teammanager_restriction_packetloss","30.0","The maximum packet loss a player can have on the server.");
  111. g_LatencyFailure = CreateConVar("teammanager_restriction_latency_failure","15","The amount of latency failures a player must accrue to be removed from the server. Does not affect players with the admin or reserve flags.");
  112.  
  113. HookEvent("player_death", Event_PlayerDeath);
  114. HookEvent("player_hurt", Event_PlayerHurt);
  115. HookEvent("infected_death", Event_InfectedDeath);
  116. HookEvent("player_incapacitated", Event_PlayerIncapacitated);
  117. HookEvent("choke_stopped", Event_ChokeStopped);
  118. HookEvent("jockey_ride_end", Event_JockeyRideEnd);
  119. HookEvent("pounce_stopped", Event_PounceStopped);
  120. HookEvent("revive_success", Event_ReviveSuccess);
  121. HookEvent("lunge_pounce", Event_EnsnareBegin);
  122. HookEvent("jockey_ride", Event_EnsnareBegin);
  123. HookEvent("tongue_grab", Event_EnsnareBegin);
  124. HookEvent("tongue_release", Event_EnsnareEnd);
  125. HookEvent("choke_start", Event_EnsnareBegin);
  126. HookEvent("tongue_pull_stopped", Event_EnsnareEnd);
  127. HookEvent("charger_carry_start", Event_EnsnareBegin);
  128. HookEvent("charger_carry_end", Event_EnsnareEnd);
  129. HookEvent("charger_pummel_start", Event_EnsnareBegin);
  130. HookEvent("charger_pummel_end", Event_EnsnareEnd);
  131.  
  132. RegConsoleCmd("go_away_from_keyboard", BlockIdle);
  133. RegConsoleCmd("score", CMD_ShowScoreboard);
  134. RegConsoleCmd("top10", CMD_Top10Players);
  135. RegConsoleCmd("ff", CMD_FriendlyFireTotal);
  136. RegConsoleCmd("team", CMD_Teams);
  137. RegConsoleCmd("teams", CMD_Teams);
  138. RegConsoleCmd("callvote", CMD_BlockVotes);
  139. RegConsoleCmd("vote", CMD_BlockVotes);
  140. RegConsoleCmd("gametypevote", CMD_GameTypeVote);
  141. RegConsoleCmd("eavesdrop", CMDEavesdrop);
  142. RegAdminCmd("teleport", CMDTeleport, ADMFLAG_KICK);
  143. RegAdminCmd("swap", CMD_SwapPlayer, ADMFLAG_KICK);
  144.  
  145. Format(white, sizeof(white), "\x01");
  146. Format(blue, sizeof(blue), "\x03");
  147. Format(orange, sizeof(orange), "\x04");
  148. Format(green, sizeof(green), "\x05");
  149.  
  150. Database_OnPluginStart();
  151. SetAndMaintainSlots();
  152.  
  153. LoadTranslations("common.phrases");
  154. LoadTranslations("teammanager.phrases");
  155.  
  156. g_sGameConf = LoadGameConfigFile("skyrpg_v2");
  157. if (g_sGameConf != INVALID_HANDLE)
  158. {
  159. StartPrepSDKCall(SDKCall_Player);
  160. PrepSDKCall_SetFromConf(g_sGameConf, SDKConf_Signature, "RoundRespawn");
  161. hRoundRespawn = EndPrepSDKCall();
  162.  
  163. StartPrepSDKCall(SDKCall_Player);
  164. PrepSDKCall_SetFromConf(g_sGameConf, SDKConf_Signature, "SetHumanSpec");
  165. PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
  166. hSetHumanSpec = EndPrepSDKCall();
  167.  
  168. StartPrepSDKCall(SDKCall_Player);
  169. PrepSDKCall_SetFromConf(g_sGameConf, SDKConf_Signature, "TakeOverBot");
  170. PrepSDKCall_AddParameter(SDKType_Bool, SDKPass_Plain);
  171. hTakeOverBot = EndPrepSDKCall();
  172.  
  173. StartPrepSDKCall(SDKCall_Player);
  174. PrepSDKCall_SetFromConf(g_sGameConf, SDKConf_Signature, "SetClass");
  175. PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
  176. g_hSetClass = EndPrepSDKCall();
  177.  
  178. StartPrepSDKCall(SDKCall_Static);
  179. PrepSDKCall_SetFromConf(g_sGameConf, SDKConf_Signature, "CreateAbility");
  180. PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
  181. PrepSDKCall_SetReturnInfo(SDKType_CBaseEntity, SDKPass_Pointer);
  182. g_hCreateAbility = EndPrepSDKCall();
  183.  
  184. g_oAbility = GameConfGetOffset(g_sGameConf, "oAbility");
  185. }
  186.  
  187.  
  188. AutoExecConfig(true, "teammanager");
  189. }
  190.  
  191. public Action:BlockIdle(client, args) { return Plugin_Handled; }
  192.  
  193. public Action:CMD_ShowScoreboard(client, args)
  194. {
  195. if (IsVersus()) SendPanelToClientAndClose(Scoreboard_Menu(client), client, Scoreboard_Menu_Init, MENU_TIME_FOREVER);
  196. return Plugin_Handled;
  197. }
  198.  
  199. public Action:CMD_Top10Players(client, args)
  200. {
  201. SendPanelToClientAndClose(Top10Players(client), client, Top10Players_Init, MENU_TIME_FOREVER);
  202. return Plugin_Handled;
  203. }
  204.  
  205. public Action:CMD_FriendlyFireTotal(client, args)
  206. {
  207. if (GetClientTeam(client) == TEAM_SURVIVORS) PrintToChat(client, "%T", "Friendly Fire Amount", client, white, blue, white, orange, FriendlyFire[client], GetConVarInt(g_Control_FriendlyFireLimit[0]));
  208. else if (GetClientTeam(client) == TEAM_INFECTED) PrintToChat(client, "%T", "Friendly Fire Amount", client, white, blue, white, orange, FriendlyFire[client], GetConVarInt(g_Control_FriendlyFireLimit[1]));
  209. return Plugin_Handled;
  210. }
  211.  
  212. public Action:CMD_GameTypeVote(client, args)
  213. {
  214. if (GetConVarInt(g_Module_Configs_Enabled) == 0 || GetConVarInt(g_Module_Configs_Voting) == 0 ||
  215. bRoundOver || (args < 1 && !bIsVoteExisting))
  216. {
  217. if (args < 1 && !bIsVoteExisting) PrintToChat(client, "!gametypevote <coop | versus | survival>");
  218. return Plugin_Handled;
  219. }
  220. decl String:GameType[128];
  221. GetConVarString(FindConVar("mp_gamemode"), GameType, 128);
  222.  
  223.  
  224. decl String:arg1[MAX_NAME_LENGTH];
  225. GetCmdArg(1, arg1, sizeof(arg1));
  226.  
  227. if (StrEqual(GameType, "versus") && StrEqual(arg1, "versus") ||
  228. StrEqual(GameType, "coop") && StrEqual(arg1, "coop") ||
  229. StrEqual(GameType, "survival") && StrEqual(arg1, "survival") ||
  230. (StrEqual(arg1, "coop") && GetConVarInt(g_CoopAllowed) == 0) ||
  231. (!StrEqual(arg1, "versus") && !StrEqual(arg1, "coop") && !StrEqual(arg1, "survival"))) return Plugin_Handled;
  232.  
  233. if (bIsVoteCooldown)
  234. {
  235. new seconds = VoteTimeCooldown;
  236. new minutes = 0;
  237. while (seconds > 60)
  238. {
  239. minutes++;
  240. seconds -= 60;
  241. }
  242. PrintToChat(client, "%T", "Gametype Vote Cooldown", client, white, blue, minutes, seconds, white);
  243. return Plugin_Handled;
  244. }
  245. bIsVoteCooldown = true;
  246. bIsVoteExisting = true;
  247. VoteType[client] = 0;
  248. for (new i = 1; i <= MaxClients; i++)
  249. {
  250. if (IsClientHuman(i) && i != client) VoteType[i] = 0;
  251. }
  252. decl String:caller[MAX_NAME_LENGTH];
  253. GetClientName(client, caller, sizeof(caller));
  254. Format(GameTypeVote, sizeof(GameTypeVote), "%s", arg1);
  255. PrintToChatAll("%t", "Gametype Vote", white, green, caller, white, green, white, blue, GetConVarInt(g_Module_Configs_VoteTime), white);
  256. VoteTimeCooldown = GetConVarInt(g_Module_Configs_VoteCooldown);
  257. VoteTimeRemaining = -1;
  258. CreateTimer(1.0, Timer_VoteCooldown, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  259. CreateTimer(1.0, Timer_VoteTime, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  260. return Plugin_Handled;
  261. }
  262.  
  263. public FirstClientLoaded()
  264. {
  265. IsChangingGametype = false;
  266. CheckLobbyConnection();
  267. CreateTimer(1.0, Timer_PingValidation, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  268. }
  269.  
  270. stock CheckLobbyConnection()
  271. {
  272. decl String:ServerGametype[128];
  273. GetConVarString(FindConVar("mp_gamemode"), ServerGametype, sizeof(ServerGametype));
  274.  
  275. if (!IsGametypeSet) return;
  276.  
  277. if (IsGametypeVote)
  278. {
  279. // If the gametype and map changed as the result of a vote, we change the CurrentGametype to match it
  280. // so this function doesn't override the vote.
  281. GetConVarString(FindConVar("mp_gamemode"), CurrentGametype, sizeof(CurrentGametype));
  282. LogToFile(LOGFILE, "Locking gametype to %s via vote.", CurrentGametype);
  283. IsGametypeVote = false;
  284. return;
  285. }
  286.  
  287. if (!StrEqual(CurrentGametype, ServerGametype))
  288. {
  289. LogToFile(LOGFILE, "Gametype doesn't match the config, executing %s", CurrentGametype);
  290.  
  291. if (StrEqual(CurrentGametype, "versus")) GetConVarString(g_Module_Configs_VersusConfig, GameTypeVote, sizeof(GameTypeVote));
  292. else if (StrEqual(CurrentGametype, "coop")) GetConVarString(g_Module_Configs_CoopConfig, GameTypeVote, sizeof(GameTypeVote));
  293. else GetConVarString(g_Module_Configs_SurvivalConfig, GameTypeVote, sizeof(GameTypeVote));
  294.  
  295. ServerCommand("sm_execcfg %s", GameTypeVote);
  296. if (!StrEqual(CurrentGametype, "survival"))
  297. {
  298. ResetCampaignScores();
  299. ChangeCampaign(true);
  300. }
  301. else
  302. {
  303. ResetCampaignScores();
  304. new random = GetRandomInt(1, 22);
  305. ChangeSurvival(random);
  306. }
  307. }
  308. }
  309.  
  310. stock PlayerVoteRequirement()
  311. {
  312. new count = 0;
  313. for (new i = 1; i <= MaxClients; i++)
  314. {
  315. if (IsClientHuman(i)) count++;
  316. }
  317. count /= 2;
  318. count++;
  319. return count;
  320. }
  321.  
  322. stock PlayerVoteFavour()
  323. {
  324. new count = 0;
  325. for (new i = 1; i <= MaxClients; i++)
  326. {
  327. if (IsClientInGame(i) && !IsFakeClient(i) && VoteType[i] == 2) count++;
  328. }
  329. return count;
  330. }
  331.  
  332. stock ResetPlayerVotes()
  333. {
  334. for (new i = 1; i <= MaxClients; i++)
  335. {
  336. if (IsClientInGame(i) && !IsFakeClient(i)) VoteType[i] = 0;
  337. }
  338. }
  339.  
  340. public Action:Timer_VoteCooldown(Handle:timer)
  341. {
  342. if (bRoundOver) return Plugin_Stop;
  343. if (VoteTimeCooldown > 0)
  344. {
  345. VoteTimeCooldown--;
  346. }
  347. if (VoteTimeCooldown < 1)
  348. {
  349. VoteTimeCooldown = 0;
  350. bIsVoteCooldown = false;
  351. PrintToChatAll("%t", "Gametype Vote Allowed", white, blue);
  352. return Plugin_Stop;
  353. }
  354. return Plugin_Continue;
  355. }
  356.  
  357. public Action:Timer_VoteTime(Handle:timer)
  358. {
  359. if (VoteTimeRemaining == -1) VoteTimeRemaining = GetConVarInt(g_Module_Configs_VoteTime);
  360. VoteTimeRemaining--;
  361. for (new i = 1; i <= MaxClients; i++)
  362. {
  363. if (IsClientHuman(i)) SendPanelToClientAndClose(Gametypevote_panel(i), i, Gametypevote_panel_init, 1);
  364. }
  365. if (VoteTimeRemaining > 0 && !bRoundOver) return Plugin_Continue;
  366. if (PlayerVoteFavour() < PlayerVoteRequirement() || bRoundOver) PrintToChatAll("%t", "Gametype Vote Failed", white, orange);
  367. else
  368. {
  369. ResetPlayerVotes();
  370. IsGametypeVote = true;
  371. ChangeGameType(false);
  372. }
  373. if (bRoundOver)
  374. {
  375. // Vote ended because the round ended, so we don't put a cooldown.
  376. VoteTimeCooldown = 0;
  377. }
  378. return Plugin_Stop;
  379. }
  380.  
  381. public ChangeGameType(bool:StartConfig) //argument is deprecated
  382. {
  383. decl String:MapName[128];
  384. GetCurrentMap(MapName, sizeof(MapName));
  385. decl String:GameType[128];
  386. if (!StartConfig)
  387. {
  388. if (StrEqual(GameTypeVote, "versus")) GetConVarString(g_Module_Configs_VersusConfig, GameType, sizeof(GameType));
  389. else if (StrEqual(GameTypeVote, "coop")) GetConVarString(g_Module_Configs_CoopConfig, GameType, sizeof(GameType));
  390. else if (StrEqual(GameTypeVote, "survival")) GetConVarString(g_Module_Configs_SurvivalConfig, GameType, sizeof(GameType));
  391. }
  392.  
  393. LogToFile(LOGFILE, "Executing Config: %s", GameType);
  394.  
  395. ServerCommand("sm_execcfg %s", GameType);
  396. Format(GameTypeVote, sizeof(GameTypeVote), "%s", GameType);
  397. IsChangingGametype = true;
  398. if (!IsGametypeSet)
  399. {
  400. CreateTimer(3.0, Timer_SetStartGametype);
  401. }
  402. else CreateTimer(2.0, Timer_SlayAll, _, TIMER_FLAG_NO_MAPCHANGE);
  403. }
  404.  
  405. public Action:Timer_SetStartGametype(Handle:timer)
  406. {
  407. // This only occurs if it is the servers first boot.
  408. GetConVarString(FindConVar("mp_gamemode"), CurrentGametype, sizeof(CurrentGametype));
  409. LogToFile(LOGFILE, "Server first boot. Gametype locked at %s", CurrentGametype);
  410. IsGametypeSet = true;
  411.  
  412. if (!StrEqual(CurrentGametype, "survival"))
  413. {
  414. ResetCampaignScores();
  415. ChangeCampaign(true);
  416. }
  417. else
  418. {
  419. ResetCampaignScores();
  420. new random = GetRandomInt(1, 22);
  421. ChangeSurvival(random);
  422. }
  423. return Plugin_Stop;
  424. }
  425.  
  426. public Action:Timer_SlayAll(Handle:timer)
  427. {
  428. ServerCommand("sm_slay @all");
  429. return Plugin_Stop;
  430. }
  431.  
  432. public Action:CMDTeleport(client, args)
  433. {
  434. if (args < 1)
  435. {
  436. PrintToChat(client, "!teleport <player>");
  437. return;
  438. }
  439. decl String:arg1[MAX_NAME_LENGTH];
  440. GetCmdArg(1, arg1, sizeof(arg1));
  441. if (!StrEqual(arg1, "all", false))
  442. {
  443. decl String:target_name[MAX_NAME_LENGTH];
  444. decl target_list[MAXPLAYERS + 1], target_count, bool:tn_is_ml;
  445. new name;
  446. new i = 0;
  447. if ((target_count = ProcessTargetString(
  448. arg1,
  449. client,
  450. target_list,
  451. MAXPLAYERS,
  452. COMMAND_FILTER_CONNECTED,
  453. target_name,
  454. sizeof(target_name),
  455. tn_is_ml)) > 0)
  456. {
  457. for (i = 0; i < target_count; i++) { name = target_list[i]; }
  458. }
  459. new survivorsalive = 0;
  460. for (new j = 1; j <= MaxClients; j++)
  461. {
  462. if (!IsClientInGame(j) || IsFakeClient(j) || !IsPlayerAlive(j) || GetClientTeam(j) != 2 || j == name) continue;
  463. survivorsalive++;
  464. }
  465. if (survivorsalive < 1)
  466. {
  467. PrintToChat(client, "No survivors found, cannot teleport player.");
  468. return;
  469. }
  470. new survivorfound = 0;
  471. while (survivorfound == 0)
  472. {
  473. i = GetRandomInt(1, MaxClients);
  474. if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2 && i != name)
  475. {
  476. new Float:teleport[3];
  477. GetClientAbsOrigin(i, teleport);
  478. TeleportEntity(name, Float:teleport, NULL_VECTOR, NULL_VECTOR);
  479. survivorfound = 1;
  480. PrintToChatAll("%N teleported %N to %N.", client, name, i);
  481. }
  482. }
  483. }
  484. else
  485. {
  486. if (IsPlayerAlive(client))
  487. {
  488. // teleport all human survivors to the players location.
  489. new Float:SurvivorLocation[3];
  490. GetClientAbsOrigin(client, SurvivorLocation);
  491. for (new i = 1; i <= MaxClients; i++)
  492. {
  493. if (IsClientHuman(i) && IsPlayerAlive(i) && GetClientTeam(i) == TEAM_SURVIVORS && i != client)
  494. {
  495. TeleportEntity(i, Float:SurvivorLocation, NULL_VECTOR, NULL_VECTOR);
  496. }
  497. }
  498. }
  499. }
  500. }
  501.  
  502. /*stock CheckLoadAttemptEveryone()
  503. {
  504. for (new client = 1; client <= MaxClients; client++)
  505. {
  506. if (IsClientHuman(client) && !bLoadAttempted[client])
  507. {
  508. bLoadAttempted[client] = true;
  509. LoadPlayerData(client);
  510. }
  511. }
  512. }*/
  513.  
  514. public Action:CMD_Teams(client, args)
  515. {
  516. if (!bLoadAttempted[client])
  517. {
  518. bLoadAttempted[client] = true;
  519. LoadPlayerData(client);
  520. }
  521. GetClientRank(client);
  522. SendPanelToClientAndClose(TeamManagerMenu(client), client, TeamManagerMenu_Init, MENU_TIME_FOREVER);
  523. return Plugin_Handled;
  524. }
  525.  
  526. public Action:CMD_BlockVotes(client, args)
  527. {
  528. if (GetConVarInt(g_Module_BlockVote_Enabled) == 1) return Plugin_Handled;
  529. else return Plugin_Continue;
  530. }
  531.  
  532. public OnConfigsExecuted()
  533. {
  534. AutoExecConfig(true, "teammanager");
  535.  
  536. // will make modules optional at some point
  537. CreateConVar("teammanager_version", PLUGIN_VERSION, "The current version release of the plugin.", CVAR_SHOW);
  538. SetConVarString(FindConVar("teammanager_version"), PLUGIN_VERSION);
  539. CreateConVar("teammanager_playerplus_version", PLAYERPLUS_VERSION, "The current version of player plus module.", CVAR_SHOW);
  540. SetConVarString(FindConVar("teammanager_playerplus_version"), PLAYERPLUS_VERSION);
  541. CreateConVar("teammanager_eavesdrop_version", EAVESDROP_VERSION, "The current version of eavesdrop module.", CVAR_SHOW);
  542. SetConVarString(FindConVar("teammanager_eavesdrop_version"), EAVESDROP_VERSION);
  543. SetAndMaintainSlots();
  544. SetConVarFlags(g_SteamgroupCvar, GetConVarFlags(g_SteamgroupCvar) & ~FCVAR_NOTIFY);
  545. }
  546.  
  547. public AllClientsLoaded()
  548. {
  549. bTransition = false;
  550. Format(MapPath, sizeof(MapPath), "none");
  551. if (IsFirstMap() || !IsVersus()) ResetCampaignScores();
  552.  
  553. roundCounter = 0;
  554. if (IsVersus())
  555. {
  556. new ScoreDifference = TeamDifference();
  557. if (!bFirstMapOfCampaign())
  558. {
  559. if (GetConVarInt(g_Debug) == 1) LogToFile(LOGFILE, "Score Difference: %d", ScoreDifference);
  560. if (ScoreDifference <= GetConVarInt(g_Module_Teams_Scramble) || LastScramble < 2) TeamAssignmentCheck(true);
  561. else if (GetConVarInt(g_Module_Teams_SmartScramble) == 1) Scramble(true);
  562. else if (GetConVarInt(g_Module_Teams_SmartScramble) == 0) Scramble(false);
  563. }
  564. else
  565. {
  566. if (GetConVarInt(g_Module_Teams_SmartScramble) == 1) Scramble(true);
  567. else if (GetConVarInt(g_Module_Teams_SmartScramble) == 0) Scramble(false);
  568. }
  569. }
  570. else
  571. {
  572. // Not versus, make sure they're survivor.
  573. for (new i = 1; i <= MaxClients; i++)
  574. {
  575. if (!IsClientHuman(i) || GetClientTeam(i) == TEAM_SURVIVORS || bAway[i]) continue;
  576. JoinTargetTeam(i, TEAM_SURVIVORS);
  577. }
  578. }
  579. for (new i = 1; i <= MaxClients; i++)
  580. {
  581. if (!IsClientHuman(i)) continue;
  582. //bLoadAttempted[i] = false;
  583. bFlyCooldown[i] = false;
  584. Fly[i] = false;
  585. }
  586. //SurvivorCheck();
  587. KickSurvivorBots();
  588. }
  589.  
  590. stock TeamDifference()
  591. {
  592. new ScoreDifference = 0;
  593. if (L4D2Direct_GetVSCampaignScore(0) > L4D2Direct_GetVSCampaignScore(1))
  594. {
  595. ScoreDifference = L4D2Direct_GetVSCampaignScore(0) - L4D2Direct_GetVSCampaignScore(1);
  596. }
  597. else
  598. {
  599. ScoreDifference = L4D2Direct_GetVSCampaignScore(1) - L4D2Direct_GetVSCampaignScore(0);
  600. }
  601. return ScoreDifference;
  602. }
  603.  
  604. stock bool:bFirstMapOfCampaign()
  605. {
  606. decl String:MapName[128];
  607. GetCurrentMap(MapName, sizeof(MapName));
  608. if (StrContains(MapName, "c1m1", true) > -1 ||
  609. StrContains(MapName, "c2m1", true) > -1 ||
  610. StrContains(MapName, "c3m1", true) > -1 ||
  611. StrContains(MapName, "c4m1", true) > -1 ||
  612. StrContains(MapName, "c5m1", true) > -1 ||
  613. StrContains(MapName, "c6m1", true) > -1 ||
  614. StrContains(MapName, "c7m1", true) > -1 ||
  615. StrContains(MapName, "c8m1", true) > -1 ||
  616. StrContains(MapName, "c9m1", true) > -1 ||
  617. StrContains(MapName, "c10m1", true) > -1 ||
  618. StrContains(MapName, "c11m1", true) > -1 ||
  619. StrContains(MapName, "c12m1", true) > -1 ||
  620. StrContains(MapName, "c13m1", true) > -1 ||
  621. StrContains(MapName, "zero01", true) > -1) return true;
  622. return false;
  623. }
  624.  
  625. public ReadyUpEnd()
  626. {
  627. decl String:GameTypeCurrent2[128];
  628. GetConVarString(FindConVar("mp_gamemode"), GameTypeCurrent2, 128);
  629. if (!StrEqual(GameTypeCurrent2, "survival")) SetMapPath();
  630. else ServerCommand("sm_forcepath easy");
  631.  
  632. if (GetConVarInt(g_Module_Campaign_Enabled) == 0) return;
  633. //bTransition = false;
  634. bRoundOver = false;
  635.  
  636. CreateTimer(1.0, Timer_AFK_CycleTime, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  637. bIsVoteCooldown = true;
  638. bIsVoteExisting = false;
  639. CreateTimer(1.0, Timer_VoteCooldown, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  640. //SurvivorCheck();
  641. KickSurvivorBots();
  642. }
  643.  
  644. public CoopMapFailed()
  645. {
  646. roundCounter--;
  647. SaveAllPlayers();
  648. }
  649.  
  650. public SetMapPath()
  651. {
  652. if (StrEqual(MapPath, "none"))
  653. {
  654. new random = GetRandomInt(1,3);
  655. if (random == 1) Format(MapPath, sizeof(MapPath), "easy");
  656. else if (random == 2) Format(MapPath, sizeof(MapPath), "medium");
  657. else Format(MapPath, sizeof(MapPath), "hard");
  658. }
  659. ServerCommand("sm_forcepath %s", MapPath);
  660. }
  661.  
  662. stock HumanSurvivorCount()
  663. {
  664. new count = 0;
  665. for (new i = 1; i <= MaxClients; i++)
  666. {
  667. if (IsClientHuman(i) && GetClientTeam(i) == TEAM_SURVIVORS) count++;
  668. }
  669. return count;
  670. }
  671.  
  672. public CheckTeams(client)
  673. {
  674. if (!IsVersus()) return;
  675.  
  676. new survivors = 0;
  677. new infected = 0;
  678. for (new i = 1; i <= MaxClients; i++)
  679. {
  680. if (IsClientHuman(i) && (client == 0 || client != i))
  681. {
  682. if (GetClientTeam(i) == TEAM_SURVIVORS) survivors++;
  683. else if (GetClientTeam(i) == TEAM_INFECTED) infected++;
  684. }
  685. }
  686. if (infected < GetConVarInt(g_CheckTeams_PlayerRequirement) || survivors < GetConVarInt(g_CheckTeams_PlayerRequirement)) return;
  687. if (infected > survivors + 1) RandomAssignment(TEAM_INFECTED, TEAM_SURVIVORS);
  688. else if (survivors > infected + 1) RandomAssignment(TEAM_SURVIVORS, TEAM_INFECTED);
  689. }
  690.  
  691. public RandomAssignment(TargetTeam, DestinationTeam)
  692. {
  693. new String:Name[MAX_NAME_LENGTH];
  694. new i = 0;
  695. while (i < 1)
  696. {
  697. new client = GetRandomInt(1, MaxClients);
  698. i = GetClientOfUserId(client);
  699. if (IsClientHuman(i) && GetClientTeam(i) == TargetTeam)
  700. {
  701. if (DestinationTeam == TEAM_INFECTED)
  702. {
  703. JoinTargetTeam(i, TEAM_INFECTED);
  704. GetClientName(i, Name, sizeof(Name));
  705. PrintToChatAll("%t", "Player Forced Infected Team", white, orange, white, Name);
  706. }
  707. else if (DestinationTeam == TEAM_SURVIVORS)
  708. {
  709. JoinTargetTeam(i, TEAM_SURVIVORS);
  710. GetClientName(i, Name, sizeof(Name));
  711. PrintToChatAll("%t", "Player Forced Survivor Team", white, blue, white, Name);
  712. CreateTimer(1.0, Timer_RespawnOnSurvivorForce, i, TIMER_FLAG_NO_MAPCHANGE);
  713. }
  714. }
  715. else i = 0;
  716. }
  717. // Check the teams again, just in case the teams are so imbalanced that they need more players moved.
  718. //CheckTeams(0);
  719. }
  720.  
  721. public Action:Timer_RespawnOnSurvivorForce(Handle:timer, any:client)
  722. {
  723. if (bRoundOver) return Plugin_Stop;
  724. if (IsClientHuman(client) && GetClientTeam(client) == TEAM_SURVIVORS)
  725. {
  726. if (IsPlayerAlive(client))
  727. {
  728. if (TeleportSurvivor(client)) return Plugin_Stop;
  729. else
  730. {
  731. LogToFile(LOGFILE, "No survivor to teleport respawned player on automatic team switch.");
  732. return Plugin_Stop;
  733. }
  734. }
  735. else SDKCall(hRoundRespawn, client);
  736. }
  737. return Plugin_Continue;
  738. }
  739.  
  740. public TeleportSurvivor(client)
  741. {
  742. new Float:Origin[3];
  743. for (new i = 1; i <= MaxClients; i++)
  744. {
  745. if (IsClientHuman(i) && GetClientTeam(i) == TEAM_SURVIVORS && IsPlayerAlive(i) && i != client)
  746. {
  747. GetClientAbsOrigin(i, Origin);
  748. TeleportEntity(client, Origin, NULL_VECTOR, NULL_VECTOR);
  749. return true;
  750. }
  751. }
  752. return false;
  753. }
  754.  
  755. stock bool:RespawnHumans()
  756. {
  757. for (new i = 1; i <= MaxClients; i++)
  758. {
  759. if (IsClientHuman(i) && GetClientTeam(i) == TEAM_SURVIVORS && !IsPlayerAlive(i)) SDKCall(hRoundRespawn, i);
  760. }
  761. }
  762.  
  763. stock bool:bAnyHumansAlive()
  764. {
  765. for (new i = 1; i <= MaxClients; i++)
  766. {
  767. if (IsClientHuman(i) && GetClientTeam(i) == TEAM_SURVIVORS && IsPlayerAlive(i)) return true;
  768. }
  769. return false;
  770. }
  771.  
  772. public CampaignComplete()
  773. {
  774. CheckForCampaignChange();
  775. }
  776.  
  777. public RoundTimeRecorder(NewRound)
  778. {
  779. if (NewRound) StartTime = GetTime();
  780. else
  781. {
  782. StartTime = GetTime() - StartTime;
  783. new Hours = 0;
  784. new Minutes = 0;
  785. new Seconds = 0;
  786. while (StartTime > 3600)
  787. {
  788. Hours++;
  789. StartTime -= 3600;
  790. }
  791. while (StartTime > 60)
  792. {
  793. Minutes++;
  794. StartTime -= 60;
  795. }
  796. Seconds = StartTime;
  797. PrintToChatAll("%t", "Round Length", white, blue, white, blue, white, blue, white, Hours, Minutes, Seconds);
  798. }
  799. }
  800.  
  801. /*stock LoadAllPlayersData()
  802. {
  803. for (new i = 1; i <= MaxClients; i++)
  804. {
  805. if (IsClientHuman(i)) LoadPlayerData(i);
  806. }
  807. }*/
  808.  
  809.  
  810. public CheckpointDoorStartOpened()
  811. {
  812. bTransition = false; // used for coop if the map fails and it isn't a finale.
  813. //LoadAllPlayersData();
  814. GetTop10();
  815. RoundTimeRecorder(true);
  816. if (!bAnyHumansAlive()) RespawnHumans();
  817. DisableAllEavesdropValues();
  818. }
  819.  
  820. public Action:Timer_ForceScoreboard(Handle:timer)
  821. {
  822. if (!bForceScoreboard) return Plugin_Stop;
  823. for (new i = 1; i <= MaxClients; i++)
  824. {
  825. if (IsClientHuman(i)) SendPanelToClientAndClose(Scoreboard_Menu(i), i, Scoreboard_Menu_Init, 1);
  826. }
  827. return Plugin_Continue;
  828. }
  829.  
  830. public ReadyUpStart()
  831. {
  832. bForceScoreboard = false;
  833. }
  834.  
  835. public OnMapStart()
  836. {
  837. bRoundOver = true;
  838. IsSurvivorCheck = false;
  839. PrecacheModel(NICK_MODEL);
  840. PrecacheModel(ROCHELLE_MODEL);
  841. PrecacheModel(COACH_MODEL);
  842. PrecacheModel(ELLIS_MODEL);
  843. PrecacheModel(ZOEY_MODEL);
  844. PrecacheModel(FRANCIS_MODEL);
  845. PrecacheModel(LOUIS_MODEL);
  846. }
  847.  
  848. public RoundIsOver()
  849. {
  850. if (!IsChangingGametype)
  851. {
  852. if (IsVersus())
  853. {
  854. CalculateSurvivorScore();
  855. CreateTimer(1.0, Timer_ForceScoreboard, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
  856. }
  857.  
  858. RoundTimeRecorder(false);
  859. bRoundOver = true;
  860. bForceScoreboard = true;
  861. roundCounter++;
  862. for (new i = 1; i <= MaxClients; i++)
  863. {
  864. if (!IsClientHuman(i)) continue;
  865. bCFF[i] = false;
  866. EavesdropAll[i] = false;
  867. FriendlyFire[i] = 0;
  868. bFlyCooldown[i] = false;
  869. Fly[i] = false;
  870. if (GetClientTeam(i) == TEAM_SURVIVORS) SurvivorRoundsPlayed[i]++;
  871. else if (GetClientTeam(i) == TEAM_INFECTED) InfectedRoundsPlayed[i]++;
  872. }
  873. DisableAllEavesdropValues();
  874.  
  875. if (roundCounter >= GetConVarInt(g_Module_Campaign_Rounds))
  876. {
  877. mapcounter++;
  878. bTransition = true;
  879. if (IsVersus()) TeamAssignmentCheck(false);
  880. CheckForCampaignChange();
  881. CheckForSurvivalChange();
  882. }
  883. else if (roundCounter < GetConVarInt(g_Module_Campaign_Rounds) && !IsCoop())
  884. {
  885. SaveAllPlayers();
  886. }
  887. }
  888. else
  889. {
  890. IsChangingGametype = false;
  891. OfficiateGametype();
  892. }
  893. }
  894.  
  895. stock OfficiateGametype()
  896. {
  897. if (!StrEqual(GameTypeVote, "survival"))
  898. {
  899. ResetCampaignScores();
  900. ChangeCampaign(true);
  901. }
  902. else
  903. {
  904. ResetCampaignScores();
  905. new random = GetRandomInt(1, 22);
  906. ChangeSurvival(random);
  907. }
  908. }
  909.  
  910. stock SaveAllPlayers()
  911. {
  912. for (new i = 1; i <= MaxClients; i++)
  913. {
  914. if (IsClientHuman(i)) SavePlayerData(i);
  915. }
  916. }
  917.  
  918. public GetTeamPlayers(team)
  919. {
  920. new count = 0;
  921. for (new i = 1; i <= MaxClients; i++)
  922. {
  923. if (!IsClientHuman(i) || GetClientTeam(i) != team) continue;
  924. count++;
  925. }
  926. return count;
  927. }
  928.  
  929. bool:IsRoot(client)
  930. {
  931. if (IsClientHuman(client))
  932. {
  933. decl flags;
  934. flags = GetUserFlagBits(client);
  935. if (!(flags & ADMFLAG_ROOT)) return false;
  936. return true;
  937. }
  938. else return false;
  939. }
  940.  
  941. bool:IsReserve(client)
  942. {
  943. if (IsClientHuman(client))
  944. {
  945. decl flags;
  946. flags = GetUserFlagBits(client);
  947. if (!(flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)) return false;
  948. return true;
  949. }
  950. else return false;
  951. }
  952.  
  953. stock bool:IsAdmin(client)
  954. {
  955. if (IsClientHuman(client))
  956. {
  957. decl flags;
  958. flags = GetUserFlagBits(client);
  959. if (!(flags & ADMFLAG_ROOT || flags & ADMFLAG_GENERIC)) return false;
  960. return true;
  961. }
  962. else return false;
  963. }
  964.  
  965. stock bool:IsIncapacitated(client)
  966. {
  967. return bool:GetEntProp(client, Prop_Send, "m_isIncapacitated");
  968. }
  969.  
  970. stock SendPanelToClientAndClose(Handle:panel, client, MenuHandler:handler, time)
  971. {
  972. SendPanelToClient(panel, client, handler, time);
  973. CloseHandle(panel);
  974. }
  975.  
  976. public GetCampaignScore(team)
  977. {
  978. new score = 0;
  979. for (new i = 0; i <= mapcounter; i++)
  980. {
  981. if (MapScores[i][team] < 0) MapScores[i][team] *= -1;
  982. if (MapScores[i][team] > 400) MapScores[i][team] = 400;
  983. score += MapScores[i][team];
  984. }
  985. return score;
  986. }
  987.  
  988. public CalculateSurvivorScore()
  989. {
  990. new Float:FlowPercent = GetSurvivorTeamDistance();
  991. FlowPercent *= 400.0;
  992.  
  993. new bFlipped = GameRules_GetProp("m_bAreTeamsFlipped");
  994. MapScores[mapcounter][bFlipped] += RoundToFloor(FlowPercent);
  995.  
  996. new String:text[512];
  997. for (new i = 1; i <= MaxClients; i++)
  998. {
  999. if (!IsClientHuman(i)) continue;
  1000. if (!bFlipped) Format(text, sizeof(text), "%T", "Score Map Total", i, blue, white, green, orange, white, green, white, blue, white, white, orange, white, MapScores[mapcounter][0], MapScores[mapcounter][1], GetCampaignScore(0), GetCampaignScore(1));
  1001. else Format(text, sizeof(text), "%T", "Score Map Total", i, blue, white, green, orange, white, green, white, blue, white, white, orange, white, MapScores[mapcounter][1], MapScores[mapcounter][0], GetCampaignScore(1), GetCampaignScore(0));
  1002. PrintToChat(i, text);
  1003. }
  1004. }
  1005.  
  1006. public Float:GetSurvivorTeamDistance()
  1007. {
  1008. new Float:value = 0.0;
  1009. for (new i = 1; i <= MaxClients; i++)
  1010. {
  1011. if (!IsClientHuman(i) || GetClientTeam(i) != TEAM_SURVIVORS) continue;
  1012. value += (L4D2Direct_GetFlowDistance(i) / L4D2Direct_GetMapMaxFlowDistance());
  1013. }
  1014. value /= HumanSurvivorCount();
  1015.  
  1016. return value;
  1017. }
  1018.  
  1019. stock FindZombieClass(client)
  1020. {
  1021. return GetEntProp(client, Prop_Send, "m_zombieClass");
  1022. }
  1023.  
  1024.  
  1025.  
  1026.  
  1027. #include "teammanager/database.sp"
  1028. #include "teammanager/login.sp"
  1029. #include "teammanager/afk.sp"
  1030. #include "teammanager/rotation.sp"
  1031. #include "teammanager/fly.sp"
  1032. #include "teammanager/reserve.sp"
  1033. #include "teammanager/campaign.sp"
  1034. #include "teammanager/teams.sp"
  1035. #include "teammanager/scramble.sp"
  1036. #include "teammanager/events.sp"
  1037. #include "teammanager/eavesdrop.sp"
  1038. #include "teammanager/ping.sp"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement