Owned

Untitled

Jul 25th, 2013
245
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2. * SetScores Left 4 Dead 2 plugin version 1.2. Allows players/admins to set the score for a match via the
  3. * !setscores command in chat. Through the cvar setscore_allow_player_vote (default 1, enabled) server
  4. * administrators may disable the vote functionality. The cvar setscore_force_admin_vote will force admins
  5. * to start a vote to change the score (default 0, vote not required). Additionally, the number of players
  6. * required to initiate the vote may be configured by setscore_player_limit (default 2).
  7. *
  8. * Original Author: vintik
  9. *
  10. * Contributors: purpletreefactory and Grego, added vote functionality and all chat messages
  11. *
  12. * Special Thanks: ProdigySim and Visor, code improvements and suggestions
  13. *
  14. * Testers: LuckyLock, DuckDuckGo, XBye, Statik
  15. */
  16.  
  17. #include <sourcemod>
  18. #include <sdktools>
  19. #include <l4d2_direct>
  20. #include <builtinvotes>
  21. #include <colors>
  22.  
  23. #define L4D_TEAM_SPECTATE 1
  24.  
  25. new Handle:minimumPlayersForVote = INVALID_HANDLE;
  26. new Handle:allowPlayersToVote = INVALID_HANDLE;
  27. new Handle:forceAdminsToVote = INVALID_HANDLE;
  28. new Handle:voteHandler = INVALID_HANDLE;
  29. new survivorScore = 0;
  30. new infectedScore = 0;
  31. new initiatingClient = 0;
  32. new bool:adminInitiated = false;
  33. new bool:inFirstReadyUpOfRound = false;
  34.  
  35. // Used to set the scores
  36. new Handle:gConf = INVALID_HANDLE;
  37. new Handle:fSetCampaignScores = INVALID_HANDLE;
  38.  
  39. public Plugin:myinfo = {
  40. name = "SetScores",
  41. author = "vintik",
  42. description = "Changes team scores.",
  43. version = "1.2",
  44. url = "https://bitbucket.org/vintik/various-plugins"
  45. }
  46.  
  47. //Beginning of our plugin, verifies the game is l4d2 and sets up our convars/command
  48. public OnPluginStart() {
  49. decl String:sGame[256];
  50. GetGameFolderName(sGame, sizeof(sGame));
  51.  
  52. if (!StrEqual(sGame, "left4dead2", false)) {
  53. SetFailState("Plugin 'SetScores' supports Left 4 Dead 2 only!");
  54. }
  55.  
  56. gConf = LoadGameConfigFile("left4downtown.l4d2");
  57. if(gConf == INVALID_HANDLE)
  58. {
  59. LogError("Could not load gamedata/left4downtown.l4d2.txt");
  60. }
  61.  
  62. StartPrepSDKCall(SDKCall_GameRules);
  63. if(PrepSDKCall_SetFromConf(gConf, SDKConf_Signature, "SetCampaignScores")) {
  64. PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
  65. PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
  66. fSetCampaignScores = EndPrepSDKCall();
  67. if(fSetCampaignScores == INVALID_HANDLE) {
  68. LogError("Function 'SetCampaignScores' found, but something went wrong.");
  69. }
  70. } else {
  71. LogError("Function 'SetCampaignScores' not found.");
  72. }
  73.  
  74. minimumPlayersForVote = CreateConVar("setscore_player_limit", "2", "Minimum # of players in game to start the vote", FCVAR_PLUGIN);
  75. allowPlayersToVote = CreateConVar("setscore_allow_player_vote", "1", "Whether player initiated votes are allowed, 1 to allow (default), 0 to disallow.", FCVAR_PLUGIN);
  76. forceAdminsToVote = CreateConVar("setscore_force_admin_vote", "0", "Whether admin score changes require a vote, 1 vote required, 0 vote not required (default).", FCVAR_PLUGIN);
  77. RegConsoleCmd("sm_setscores", Command_SetScores, "sm_setscores <survivor score> <infected score>");
  78. }
  79.  
  80. //Starting point for the setscores command
  81. public Action:Command_SetScores(client, args) {
  82. //Only allow during the first ready up of the round
  83. if (!inFirstReadyUpOfRound) {
  84. ReplyToCommand(client, "Scores can only be changed during readyup before the round starts.");
  85. return Plugin_Handled;
  86. }
  87.  
  88. if (args < 2) {
  89. ReplyToCommand(client, "Usage: sm_setscores <survivor score> <infected score>");
  90. return Plugin_Handled;
  91. }
  92.  
  93. //Store the client that requested a score change
  94. initiatingClient = client;
  95.  
  96. new String:buffer[32];
  97. //Retrieve and store the survivor score
  98. GetCmdArg(1, buffer, sizeof(buffer));
  99. survivorScore = StringToInt(buffer);
  100. //Retrieve and store the infected score
  101. GetCmdArg(2, buffer, sizeof(buffer));
  102. infectedScore = StringToInt(buffer);
  103.  
  104. new AdminId:id = GetUserAdmin(client);
  105.  
  106. //Determine whether the user is admin and what action to take
  107. if(id != INVALID_ADMIN_ID) {
  108. adminInitiated = true;
  109. //If we are forcing admins to start votes, start a vote
  110. if (GetConVarInt(forceAdminsToVote) == 1) {
  111. StartScoreVote();
  112. } else {
  113. SetScores();
  114. }
  115. } else if (GetConVarInt(allowPlayersToVote) == 1) {
  116. //If players are allowed to vote, start a vote
  117. adminInitiated = false;
  118. StartScoreVote();
  119. }
  120.  
  121. return Plugin_Handled;
  122. }
  123.  
  124. //Starts a vote to change scores
  125. StartScoreVote() {
  126. //Disallow spectator voting
  127. if (GetClientTeam(initiatingClient) == L4D_TEAM_SPECTATE) {
  128. PrintToChat(initiatingClient, "Score voting isn't allowed for spectators.");
  129. return;
  130. }
  131.  
  132. if (IsNewBuiltinVoteAllowed()) {
  133. //Determine the number of voting players (non-spectator) and store their client ids
  134. new iNumPlayers;
  135. decl iPlayers[MaxClients];
  136. for (new i=1; i<=MaxClients; i++) {
  137. if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) == L4D_TEAM_SPECTATE)) {
  138. continue;
  139. }
  140. iPlayers[iNumPlayers++] = i;
  141. }
  142.  
  143. //If there aren't enough players for the vote indicate so to the user
  144. if (iNumPlayers < GetConVarInt(minimumPlayersForVote)) {
  145. PrintToChat(initiatingClient, "Score vote cannot be started. Not enough players.");
  146. return;
  147. }
  148.  
  149. //Create the vote
  150. voteHandler = CreateBuiltinVote(VoteActionHandler, BuiltinVoteType_Custom_YesNo, BuiltinVoteAction_Cancel | BuiltinVoteAction_VoteEnd | BuiltinVoteAction_End);
  151.  
  152. //Set the text for the vote, initiating client and handler
  153. new String:sBuffer[64];
  154. Format(sBuffer, sizeof(sBuffer), "Change scores to %d - %d?", survivorScore, infectedScore);
  155. SetBuiltinVoteArgument(voteHandler, sBuffer);
  156. SetBuiltinVoteInitiator(voteHandler, initiatingClient);
  157. SetBuiltinVoteResultCallback(voteHandler, ScoreVoteResultHandler);
  158.  
  159. //Display the vote and make the initiator automatically vote yes
  160. DisplayBuiltinVote(voteHandler, iPlayers, iNumPlayers, 20);
  161. FakeClientCommand(initiatingClient, "Vote Yes");
  162. return;
  163. }
  164.  
  165. PrintToChat(initiatingClient, "Score vote cannot be started now.");
  166. }
  167.  
  168. //Actually sets the scores of the teams and print the results to all chat
  169. SetScores() {
  170. //Determine which teams are which
  171. new SurvivorTeamIndex = GameRules_GetProp("m_bAreTeamsFlipped") ? 1 : 0;
  172. new InfectedTeamIndex = GameRules_GetProp("m_bAreTeamsFlipped") ? 0 : 1;
  173.  
  174. //Set the scores
  175. SDKCall(fSetCampaignScores, survivorScore, infectedScore); //visible scores
  176. L4D2Direct_SetVSCampaignScore(SurvivorTeamIndex, survivorScore); //real scores
  177. L4D2Direct_SetVSCampaignScore(InfectedTeamIndex, infectedScore);
  178.  
  179. if(!adminInitiated) {
  180. CPrintToChatAll("Scores set to {olive}%d {default} ({green}Sur{default}) - {olive}%d {default} ({green}Inf{default}) by vote.", survivorScore, infectedScore);
  181. } else {
  182. new String:client_name[32];
  183. GetClientName(initiatingClient, client_name, sizeof(client_name));
  184. CPrintToChatAll("Scores set to {olive}%d {default} ({green}Sur{default}) - {olive}%d {default} ({green}Inf{default}) by {lightgreen}%s{default}.", survivorScore, infectedScore, client_name);
  185. }
  186. }
  187.  
  188. //Handler for the vote
  189. public VoteActionHandler(Handle:vote, BuiltinVoteAction:action, param1, param2) {
  190. switch (action) {
  191. case BuiltinVoteAction_End: {
  192. voteHandler = INVALID_HANDLE;
  193. CloseHandle(vote);
  194. }
  195. case BuiltinVoteAction_Cancel: {
  196. DisplayBuiltinVoteFail(vote, BuiltinVoteFailReason:param1);
  197. }
  198. }
  199. }
  200.  
  201. //Handles a score vote's results, if a majority voted for the score change then set the scores
  202. public ScoreVoteResultHandler(Handle:vote, num_votes, num_clients, const client_info[][2], num_items, const item_info[][2]) {
  203. for (new i=0; i<num_items; i++) {
  204. if (item_info[i][BUILTINVOTEINFO_ITEM_INDEX] == BUILTINVOTES_VOTE_YES) {
  205. if (item_info[i][BUILTINVOTEINFO_ITEM_VOTES] > (num_clients / 2)) {
  206. DisplayBuiltinVotePass(vote, "Changing scores...");
  207. SetScores();
  208. return;
  209. }
  210. }
  211. }
  212. DisplayBuiltinVoteFail(vote, BuiltinVoteFail_Loses);
  213. }
  214.  
  215. // Disables score changes once round goes live
  216. public OnRoundIsLive() {
  217. inFirstReadyUpOfRound = false;
  218. }
  219.  
  220. // Enables scores changes when map is loaded
  221. public OnMapStart() {
  222. inFirstReadyUpOfRound = true;
  223. }
RAW Paste Data