#pragma semicolon 1 #pragma newdecls required #include <sourcemod> #include <sdktools> #define VOTE_NO "###no###" #define VOTE_YES "###yes###" ConVar g_cvarExtendVoteTime = null; ConVar g_cvarExtendVotePercent = null; ConVar g_cvarMpMaxRounds = null; ConVar g_cvarMpFragLimit = null; ConVar g_cvarMpWinLimit = null; ConVar g_cvarMpTimeLimit = null; bool g_bGameOver = false; Address g_pGameOver; public Plugin myinfo = { name = "Map extend tools", author = "Obus + BotoX", description = "Adds map extension commands.", version = "1.0", url = "" }; public void OnPluginStart() { LoadTranslations("common.phrases"); LoadTranslations("basevotes.phrases"); g_cvarMpMaxRounds = FindConVar("mp_maxrounds"); g_cvarMpFragLimit = FindConVar("mp_fraglimit"); g_cvarMpWinLimit = FindConVar("mp_winlimit"); g_cvarMpTimeLimit = FindConVar("mp_timelimit"); g_cvarExtendVoteTime = CreateConVar("sm_extendvote_time", "15", "Time that will be added to mp_timelimit shall the extend vote succeed", FCVAR_NONE, true, 1.0); g_cvarExtendVotePercent = CreateConVar("sm_extendvote_percent", "0.6", "Percentage of \"yes\" votes required to consider the vote successful", FCVAR_NONE, true, 0.05, true, 1.0); AutoExecConfig(true, "plugin.Extend"); if (g_cvarMpMaxRounds != null) RegAdminCmd("sm_extend_rounds", Command_Extend_Rounds, ADMFLAG_GENERIC, "Add more rounds to mp_maxrounds"); else LogMessage("Failed to find \"mp_maxrounds\" console variable, related commands will be disabled."); if (g_cvarMpFragLimit != null) RegAdminCmd("sm_extend_frags", Command_Extend_Frags, ADMFLAG_GENERIC, "Add more frags to mp_fraglimit"); else LogMessage("Failed to find \"mp_fraglimit\" console variable, related commands will be disabled."); if (g_cvarMpWinLimit != null) RegAdminCmd("sm_extend_wins", Command_Extend_Wins, ADMFLAG_GENERIC, "Add more wins to mp_winlimit"); else LogMessage("Failed to find \"mp_winlimit\" console variable, related commands will be disabled."); if (g_cvarMpTimeLimit != null) { RegAdminCmd("sm_extend", Command_Extend, ADMFLAG_GENERIC, "Add more time to mp_timelimit"); RegAdminCmd("sm_extend_time", Command_Extend, ADMFLAG_GENERIC, "Add more time to mp_timelimit"); RegAdminCmd("sm_extendvote", Command_ExtendVote, ADMFLAG_GENERIC, "sm_extendvote [time] - Start an extendvote"); RegAdminCmd("sm_voteextend", Command_ExtendVote, ADMFLAG_GENERIC, "sm_voteextend [time] - Start an extendvote"); RegAdminCmd("sm_extend_vote", Command_ExtendVote, ADMFLAG_GENERIC, "sm_extend_vote [time] - Start an extendvote"); } else { LogMessage("Failed to find \"mp_timelimit\" console variable, related commands will be disabled."); } Handle hGameConf = LoadGameConfigFile("Extend.games"); if(hGameConf == INVALID_HANDLE) { g_bGameOver = false; LogError("Couldn't load Extend.games game config! GameOver cancel disabled."); return; } if(!(g_pGameOver = GameConfGetAddress(hGameConf, "GameOver"))) { g_bGameOver = false; delete hGameConf; LogError("Couldn't get GameOver address from game config! GameOver cancel disabled."); return; } g_bGameOver = true; delete hGameConf; } public Action Command_Extend_Rounds(int client, int argc) { if (argc < 1) { ReplyToCommand(client, "[SM] Usage: sm_extend_rounds <rounds>"); return Plugin_Handled; } char sArgs[16]; GetCmdArg(1, sArgs, sizeof(sArgs)); if (sArgs[0] == '-') { int iRoundsToDeduct; if (!StringToIntEx(sArgs[1], iRoundsToDeduct)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpMaxRounds.IntValue -= iRoundsToDeduct; LogAction(client, -1, "\"%L\" deducted \"%d\" rounds from \"mp_maxrounds\"", client, iRoundsToDeduct); return Plugin_Handled; } int iRoundsToAdd; if (!StringToIntEx(sArgs, iRoundsToAdd)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpMaxRounds.IntValue += iRoundsToAdd; CancelGameOver(); LogAction(client, -1, "\"%L\" added \"%d\" rounds to \"mp_maxrounds\"", client, iRoundsToAdd); return Plugin_Handled; } public Action Command_Extend_Frags(int client, int argc) { if (argc < 1) { ReplyToCommand(client, "[SM] Usage: sm_extend_frags <frags>"); return Plugin_Handled; } char sArgs[16]; GetCmdArg(1, sArgs, sizeof(sArgs)); if (sArgs[0] == '-') { int iFragsToDeduct; if (!StringToIntEx(sArgs[1], iFragsToDeduct)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpFragLimit.IntValue -= iFragsToDeduct; LogAction(client, -1, "\"%L\" deducted \"%d\" frags from \"mp_fraglimit\"", client, iFragsToDeduct); return Plugin_Handled; } int iFragsToAdd; if (!StringToIntEx(sArgs, iFragsToAdd)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpFragLimit.IntValue += iFragsToAdd; CancelGameOver(); LogAction(client, -1, "\"%L\" added \"%d\" frags to \"mp_fraglimit\"", client, iFragsToAdd); return Plugin_Handled; } public Action Command_Extend_Wins(int client, int argc) { if (argc < 1) { ReplyToCommand(client, "[SM] Usage: sm_extend_wins <wins>"); return Plugin_Handled; } char sArgs[16]; GetCmdArg(1, sArgs, sizeof(sArgs)); if (sArgs[0] == '-') { int iWinsToDeduct; if (!StringToIntEx(sArgs[1], iWinsToDeduct)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpWinLimit.IntValue -= iWinsToDeduct; LogAction(client, -1, "\"%L\" deducted \"%d\" wins from \"mp_winlimit\"", client, iWinsToDeduct); return Plugin_Handled; } int iWinsToAdd; if (!StringToIntEx(sArgs, iWinsToAdd)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpWinLimit.IntValue += iWinsToAdd; CancelGameOver(); LogAction(client, -1, "\"%L\" added \"%d\" wins to \"mp_winlimit\"", client, iWinsToAdd); return Plugin_Handled; } public Action Command_Extend(int client, int argc) { if (argc < 1) { ReplyToCommand(client, "[SM] Usage: sm_extend <time>"); return Plugin_Handled; } char sArgs[16]; GetCmdArg(1, sArgs, sizeof(sArgs)); if (sArgs[0] == '-') { int iMinutesToDeduct; if (!StringToIntEx(sArgs[1], iMinutesToDeduct)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpTimeLimit.IntValue -= iMinutesToDeduct; LogAction(client, -1, "\"%L\" deducted \"%d\" minutes from \"mp_timelimit\"", client, iMinutesToDeduct); PrintToChatAll("[SM] %N deducted %d minutes from the timelimit.", client, iMinutesToDeduct); return Plugin_Handled; } int iMinutesToAdd; if (!StringToIntEx(sArgs, iMinutesToAdd)) { ReplyToCommand(client, "[SM] Invalid value"); return Plugin_Handled; } g_cvarMpTimeLimit.IntValue += iMinutesToAdd; CancelGameOver(); LogAction(client, -1, "\"%L\" added \"%d\" minutes to \"mp_timelimit\"", client, iMinutesToAdd); PrintToChatAll("[SM] %N added %d minutes to the timelimit.", client, iMinutesToAdd); return Plugin_Handled; } int g_ExtendTime = 0; public Action Command_ExtendVote(int client, int argc) { if (IsVoteInProgress()) { ReplyToCommand(client, "[SM] %t", "Vote in Progress"); return Plugin_Handled; } g_ExtendTime = g_cvarExtendVoteTime.IntValue; if(argc == 1) { char sArg[64]; GetCmdArg(1, sArg, sizeof(sArg)); int Tmp = StringToInt(sArg); if(Tmp > 0) g_ExtendTime = Tmp > 30 ? 30 : Tmp; } Menu hVoteMenu = new Menu(Handler_VoteCallback, MenuAction_End|MenuAction_DisplayItem|MenuAction_VoteCancel|MenuAction_VoteEnd); hVoteMenu.SetTitle("Extend the current map (%d minutes)?", g_ExtendTime); hVoteMenu.AddItem(VOTE_YES, "Yes"); hVoteMenu.AddItem(VOTE_NO, "No"); hVoteMenu.OptionFlags = MENUFLAG_BUTTON_NOVOTE; hVoteMenu.ExitButton = false; hVoteMenu.DisplayVoteToAll(20); ShowActivity2(client, "[SM] ", "Initiated an extend vote"); LogAction(client, -1, "\"%L\" initiated an extend vote.", client); return Plugin_Handled; } public int Handler_VoteCallback(Menu menu, MenuAction action, int param1, int param2) { if (action == MenuAction_End) { delete menu; } else if (action == MenuAction_DisplayItem) { char display[64]; menu.GetItem(param2, "", 0, _, display, sizeof(display)); if (strcmp(display, VOTE_NO) == 0 || strcmp(display, VOTE_YES) == 0) { char buffer[255]; Format(buffer, sizeof(buffer), "%T", display, param1); return RedrawMenuItem(buffer); } } else if (action == MenuAction_VoteCancel && param1 == VoteCancel_NoVotes) { PrintToChatAll("[SM] %t", "No Votes Cast"); } else if (action == MenuAction_VoteEnd) { char item[64], display[64]; float percent, limit; int votes, totalVotes; GetMenuVoteInfo(param2, votes, totalVotes); menu.GetItem(param1, item, sizeof(item), _, display, sizeof(display)); if (strcmp(item, VOTE_NO) == 0) { votes = totalVotes - votes; } limit = g_cvarExtendVotePercent.FloatValue; percent = FloatDiv(float(votes),float(totalVotes)); if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent, limit) < 0) || strcmp(item, VOTE_NO) == 0) { LogAction(-1, -1, "Extend vote failed."); PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0 * limit), RoundToNearest(100.0 * percent), totalVotes); } else { LogAction(-1, -1, "Extend vote successful, extending current map by \"%d\" minutes", g_ExtendTime); PrintToChatAll("[SM] %t", "Vote Successful", RoundToNearest(100.0 * percent), totalVotes); g_cvarMpTimeLimit.IntValue += g_ExtendTime; CancelGameOver(); if (strcmp(item, VOTE_NO) == 0 || strcmp(item, VOTE_YES) == 0) { strcopy(item, sizeof(item), display); } } } return 0; } void CancelGameOver() { if (!g_bGameOver) return; StoreToAddress(g_pGameOver, 0, NumberType_Int8); for (int client = 1; client <= MaxClients; client++) { if (IsClientInGame(client)) { if (IsClientObserver(client)) SetEntityMoveType(client, MOVETYPE_NOCLIP); else SetEntityMoveType(client, MOVETYPE_WALK); } } }