This commit is contained in:
neon 2018-07-27 12:59:44 +02:00
commit 2988c9b464

View File

@ -1,386 +1,386 @@
/** /**
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* Rock The Vote Extended * Rock The Vote Extended
* Creates a map vote when the required number of players have requested one. * Creates a map vote when the required number of players have requested one.
* *
* Rock The Vote Extended (C)2012-2013 Powerlord (Ross Bemrose) * Rock The Vote Extended (C)2012-2013 Powerlord (Ross Bemrose)
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the * the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation. * Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
* *
* As a special exception, AlliedModders LLC gives you permission to link the * As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the * code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in * by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants * all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further * this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>. * or <http://www.sourcemod.net/license.php>.
* *
* Version: $Id$ * Version: $Id$
*/ */
#pragma semicolon 1 #pragma semicolon 1
#pragma newdecls required #pragma newdecls required
#include <sourcemod> #include <sourcemod>
#include <sdktools_functions> #include <sdktools_functions>
#include <mapchooser> #include <mapchooser>
#include <nextmap> #include <nextmap>
#define MCE_VERSION "1.13.0" #define MCE_VERSION "1.13.0"
public Plugin myinfo = public Plugin myinfo =
{ {
name = "Rock The Vote Extended", name = "Rock The Vote Extended",
author = "Powerlord and AlliedModders LLC", author = "Powerlord and AlliedModders LLC",
description = "Provides RTV Map Voting", description = "Provides RTV Map Voting",
version = MCE_VERSION, version = MCE_VERSION,
url = "https://forums.alliedmods.net/showthread.php?t=156974" url = "https://forums.alliedmods.net/showthread.php?t=156974"
}; };
ConVar g_Cvar_Needed; ConVar g_Cvar_Needed;
ConVar g_Cvar_MinPlayers; ConVar g_Cvar_MinPlayers;
ConVar g_Cvar_InitialDelay; ConVar g_Cvar_InitialDelay;
ConVar g_Cvar_Interval; ConVar g_Cvar_Interval;
ConVar g_Cvar_ChangeTime; ConVar g_Cvar_ChangeTime;
ConVar g_Cvar_RTVPostVoteAction; ConVar g_Cvar_RTVPostVoteAction;
ConVar g_Cvar_RTVAutoDisable; ConVar g_Cvar_RTVAutoDisable;
bool g_CanRTV = false; // True if RTV loaded maps and is active. bool g_CanRTV = false; // True if RTV loaded maps and is active.
bool g_RTVAllowed = false; // True if RTV is available to players. Used to delay rtv votes. bool g_RTVAllowed = false; // True if RTV is available to players. Used to delay rtv votes.
int g_Voters = 0; // Total voters connected. Doesn't include fake clients. int g_Voters = 0; // Total voters connected. Doesn't include fake clients.
int g_Votes = 0; // Total number of "say rtv" votes int g_Votes = 0; // Total number of "say rtv" votes
int g_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed) int g_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed)
bool g_Voted[MAXPLAYERS+1] = {false, ...}; bool g_Voted[MAXPLAYERS+1] = {false, ...};
Handle g_TimeOverTimer = INVALID_HANDLE; Handle g_TimeOverTimer = INVALID_HANDLE;
bool g_InChange = false; bool g_InChange = false;
public void OnPluginStart() public void OnPluginStart()
{ {
LoadTranslations("common.phrases"); LoadTranslations("common.phrases");
LoadTranslations("rockthevote.phrases"); LoadTranslations("rockthevote.phrases");
LoadTranslations("basevotes.phrases"); LoadTranslations("basevotes.phrases");
g_Cvar_Needed = CreateConVar("sm_rtv_needed", "0.60", "Percentage of players needed to rockthevote (Def 60%)", 0, true, 0.05, true, 1.0); g_Cvar_Needed = CreateConVar("sm_rtv_needed", "0.60", "Percentage of players needed to rockthevote (Def 60%)", 0, true, 0.05, true, 1.0);
g_Cvar_MinPlayers = CreateConVar("sm_rtv_minplayers", "0", "Number of players required before RTV will be enabled.", 0, true, 0.0, true, float(MAXPLAYERS)); g_Cvar_MinPlayers = CreateConVar("sm_rtv_minplayers", "0", "Number of players required before RTV will be enabled.", 0, true, 0.0, true, float(MAXPLAYERS));
g_Cvar_InitialDelay = CreateConVar("sm_rtv_initialdelay", "30.0", "Time (in seconds) before first RTV can be held", 0, true, 0.00); g_Cvar_InitialDelay = CreateConVar("sm_rtv_initialdelay", "30.0", "Time (in seconds) before first RTV can be held", 0, true, 0.00);
g_Cvar_Interval = CreateConVar("sm_rtv_interval", "240.0", "Time (in seconds) after a failed RTV before another can be held", 0, true, 0.00); g_Cvar_Interval = CreateConVar("sm_rtv_interval", "240.0", "Time (in seconds) after a failed RTV before another can be held", 0, true, 0.00);
g_Cvar_ChangeTime = CreateConVar("sm_rtv_changetime", "0", "When to change the map after a succesful RTV: 0 - Instant, 1 - RoundEnd, 2 - MapEnd", _, true, 0.0, true, 2.0); g_Cvar_ChangeTime = CreateConVar("sm_rtv_changetime", "0", "When to change the map after a succesful RTV: 0 - Instant, 1 - RoundEnd, 2 - MapEnd", _, true, 0.0, true, 2.0);
g_Cvar_RTVPostVoteAction = CreateConVar("sm_rtv_postvoteaction", "0", "What to do with RTV's after a mapvote has completed. 0 - Allow, success = instant change, 1 - Deny", _, true, 0.0, true, 1.0); g_Cvar_RTVPostVoteAction = CreateConVar("sm_rtv_postvoteaction", "0", "What to do with RTV's after a mapvote has completed. 0 - Allow, success = instant change, 1 - Deny", _, true, 0.0, true, 1.0);
g_Cvar_RTVAutoDisable = CreateConVar("sm_rtv_autodisable", "0", "Automatically disable RTV when map time is over.", _, true, 0.0, true, 1.0); g_Cvar_RTVAutoDisable = CreateConVar("sm_rtv_autodisable", "0", "Automatically disable RTV when map time is over.", _, true, 0.0, true, 1.0);
RegConsoleCmd("sm_rtv", Command_RTV); RegConsoleCmd("sm_rtv", Command_RTV);
RegAdminCmd("sm_forcertv", Command_ForceRTV, ADMFLAG_CHANGEMAP, "Force an RTV vote"); RegAdminCmd("sm_forcertv", Command_ForceRTV, ADMFLAG_CHANGEMAP, "Force an RTV vote");
RegAdminCmd("sm_disablertv", Command_DisableRTV, ADMFLAG_CHANGEMAP, "Disable the RTV command"); RegAdminCmd("sm_disablertv", Command_DisableRTV, ADMFLAG_CHANGEMAP, "Disable the RTV command");
RegAdminCmd("sm_enablertv", Command_EnableRTV, ADMFLAG_CHANGEMAP, "Enable the RTV command"); RegAdminCmd("sm_enablertv", Command_EnableRTV, ADMFLAG_CHANGEMAP, "Enable the RTV command");
HookEvent("player_team", OnPlayerChangedTeam, EventHookMode_PostNoCopy); HookEvent("player_team", OnPlayerChangedTeam, EventHookMode_PostNoCopy);
AutoExecConfig(true, "rtv"); AutoExecConfig(true, "rtv");
} }
public void OnMapStart() public void OnMapStart()
{ {
g_Voters = 0; g_Voters = 0;
g_Votes = 0; g_Votes = 0;
g_VotesNeeded = 0; g_VotesNeeded = 0;
g_InChange = false; g_InChange = false;
/* Handle late load */ /* Handle late load */
for (int i=1; i<=MaxClients; i++) for (int i=1; i<=MaxClients; i++)
{ {
if (IsClientConnected(i)) if (IsClientConnected(i))
{ {
OnClientConnected(i); OnClientConnected(i);
} }
} }
} }
public void OnMapEnd() public void OnMapEnd()
{ {
g_CanRTV = false; g_CanRTV = false;
g_RTVAllowed = false; g_RTVAllowed = false;
g_TimeOverTimer = INVALID_HANDLE; g_TimeOverTimer = INVALID_HANDLE;
} }
public void OnConfigsExecuted() public void OnConfigsExecuted()
{ {
g_CanRTV = true; g_CanRTV = true;
g_RTVAllowed = false; g_RTVAllowed = false;
CreateTimer(g_Cvar_InitialDelay.FloatValue, Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE); CreateTimer(g_Cvar_InitialDelay.FloatValue, Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
SetupTimeOverTimer(); SetupTimeOverTimer();
} }
public void OnMapTimeLeftChanged() public void OnMapTimeLeftChanged()
{ {
SetupTimeOverTimer(); SetupTimeOverTimer();
} }
public void OnClientConnected(int client) public void OnClientConnected(int client)
{ {
UpdateRTV(); UpdateRTV();
} }
public void OnClientDisconnect(int client) public void OnClientDisconnect(int client)
{ {
if (g_Voted[client]) if (g_Voted[client])
{ {
g_Voted[client] = false; g_Voted[client] = false;
g_Votes--; g_Votes--;
} }
UpdateRTV(); UpdateRTV();
} }
public void OnPlayerChangedTeam(Handle event, const char[] name, bool dontBroadcast) public void OnPlayerChangedTeam(Handle event, const char[] name, bool dontBroadcast)
{ {
UpdateRTV(); UpdateRTV();
} }
void UpdateRTV() void UpdateRTV()
{ {
g_Voters = 0; g_Voters = 0;
for (int i=1; i<=MAXPLAYERS; i++) for (int i=1; i<=MaxClients; i++)
{ {
if (IsClientInGame(i) && !IsFakeClient(i)) if (IsClientConnected(i) && !IsFakeClient(i))
{ {
if (GetClientTeam(i) == 2 || GetClientTeam(i) == 3) if (GetClientTeam(i) == 2 || GetClientTeam(i) == 3)
{ {
g_Voters++; g_Voters++;
} }
} }
} }
// g_Voters = GetTeamClientCount(2) + GetTeamClientCount(3); // g_Voters = GetTeamClientCount(2) + GetTeamClientCount(3);
g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed)); g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
if (!g_CanRTV) if (!g_CanRTV)
{ {
return; return;
} }
if (g_Votes && if (g_Votes &&
g_Voters && g_Voters &&
g_Votes >= g_VotesNeeded && g_Votes >= g_VotesNeeded &&
g_RTVAllowed ) g_RTVAllowed )
{ {
if (g_Cvar_RTVPostVoteAction.IntValue == 1 && HasEndOfMapVoteFinished()) if (g_Cvar_RTVPostVoteAction.IntValue == 1 && HasEndOfMapVoteFinished())
{ {
return; return;
} }
StartRTV(); StartRTV();
} }
} }
public void OnClientSayCommand_Post(int client, const char[] command, const char[] sArgs) public void OnClientSayCommand_Post(int client, const char[] command, const char[] sArgs)
{ {
if (!g_CanRTV || !client) if (!g_CanRTV || !client)
{ {
return; return;
} }
if (strcmp(sArgs, "rtv", false) == 0 || strcmp(sArgs, "rockthevote", false) == 0) if (strcmp(sArgs, "rtv", false) == 0 || strcmp(sArgs, "rockthevote", false) == 0)
{ {
ReplySource old = SetCmdReplySource(SM_REPLY_TO_CHAT); ReplySource old = SetCmdReplySource(SM_REPLY_TO_CHAT);
AttemptRTV(client); AttemptRTV(client);
SetCmdReplySource(old); SetCmdReplySource(old);
} }
} }
public Action Command_RTV(int client, int args) public Action Command_RTV(int client, int args)
{ {
if (!g_CanRTV || !client) if (!g_CanRTV || !client)
{ {
return Plugin_Handled; return Plugin_Handled;
} }
AttemptRTV(client); AttemptRTV(client);
return Plugin_Handled; return Plugin_Handled;
} }
void AttemptRTV(int client) void AttemptRTV(int client)
{ {
if (!g_RTVAllowed || (g_Cvar_RTVPostVoteAction.IntValue == 1 && HasEndOfMapVoteFinished())) if (!g_RTVAllowed || (g_Cvar_RTVPostVoteAction.IntValue == 1 && HasEndOfMapVoteFinished()))
{ {
ReplyToCommand(client, "[SM] %t", "RTV Not Allowed"); ReplyToCommand(client, "[SM] %t", "RTV Not Allowed");
return; return;
} }
if (!CanMapChooserStartVote()) if (!CanMapChooserStartVote())
{ {
ReplyToCommand(client, "[SM] %t", "RTV Started"); ReplyToCommand(client, "[SM] %t", "RTV Started");
return; return;
} }
if (GetClientCount(true) < g_Cvar_MinPlayers.IntValue) if (GetClientCount(true) < g_Cvar_MinPlayers.IntValue)
{ {
ReplyToCommand(client, "[SM] %t", "Minimal Players Not Met"); ReplyToCommand(client, "[SM] %t", "Minimal Players Not Met");
return; return;
} }
if (g_Voted[client]) if (g_Voted[client])
{ {
ReplyToCommand(client, "[SM] %t", "Already Voted", g_Votes, g_VotesNeeded); ReplyToCommand(client, "[SM] %t", "Already Voted", g_Votes, g_VotesNeeded);
return; return;
} }
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
GetClientName(client, name, sizeof(name)); GetClientName(client, name, sizeof(name));
g_Votes++; g_Votes++;
g_Voted[client] = true; g_Voted[client] = true;
PrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded); PrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded);
if (g_Votes >= g_VotesNeeded) if (g_Votes >= g_VotesNeeded)
{ {
StartRTV(); StartRTV();
} }
} }
public Action Timer_DelayRTV(Handle timer) public Action Timer_DelayRTV(Handle timer)
{ {
g_RTVAllowed = true; g_RTVAllowed = true;
} }
void StartRTV() void StartRTV()
{ {
if (g_InChange) if (g_InChange)
{ {
return; return;
} }
if (EndOfMapVoteEnabled() && HasEndOfMapVoteFinished()) if (EndOfMapVoteEnabled() && HasEndOfMapVoteFinished())
{ {
/* Change right now then */ /* Change right now then */
char map[PLATFORM_MAX_PATH]; char map[PLATFORM_MAX_PATH];
if (GetNextMap(map, sizeof(map))) if (GetNextMap(map, sizeof(map)))
{ {
GetMapDisplayName(map, map, sizeof(map)); GetMapDisplayName(map, map, sizeof(map));
PrintToChatAll("[SM] %t", "Changing Maps", map); PrintToChatAll("[SM] %t", "Changing Maps", map);
CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE); CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE);
g_InChange = true; g_InChange = true;
ResetRTV(); ResetRTV();
g_RTVAllowed = false; g_RTVAllowed = false;
} }
return; return;
} }
if (CanMapChooserStartVote()) if (CanMapChooserStartVote())
{ {
MapChange when = view_as<MapChange>(g_Cvar_ChangeTime.IntValue); MapChange when = view_as<MapChange>(g_Cvar_ChangeTime.IntValue);
InitiateMapChooserVote(when); InitiateMapChooserVote(when);
ResetRTV(); ResetRTV();
g_RTVAllowed = false; g_RTVAllowed = false;
CreateTimer(g_Cvar_Interval.FloatValue, Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE); CreateTimer(g_Cvar_Interval.FloatValue, Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
} }
} }
void ResetRTV() void ResetRTV()
{ {
g_Votes = 0; g_Votes = 0;
for (int i=1; i<=MAXPLAYERS; i++) for (int i=1; i<=MAXPLAYERS; i++)
{ {
g_Voted[i] = false; g_Voted[i] = false;
} }
} }
public Action Timer_ChangeMap(Handle hTimer) public Action Timer_ChangeMap(Handle hTimer)
{ {
g_InChange = false; g_InChange = false;
LogMessage("RTV changing map manually"); LogMessage("RTV changing map manually");
char map[PLATFORM_MAX_PATH]; char map[PLATFORM_MAX_PATH];
if (GetNextMap(map, sizeof(map))) if (GetNextMap(map, sizeof(map)))
{ {
ForceChangeLevel(map, "RTV after mapvote"); ForceChangeLevel(map, "RTV after mapvote");
} }
return Plugin_Stop; return Plugin_Stop;
} }
public Action Command_ForceRTV(int client, int args) public Action Command_ForceRTV(int client, int args)
{ {
if(!g_CanRTV) if(!g_CanRTV)
return Plugin_Handled; return Plugin_Handled;
ShowActivity2(client, "[RTVE] ", "%t", "Initiated Vote Map"); ShowActivity2(client, "[RTVE] ", "%t", "Initiated Vote Map");
StartRTV(); StartRTV();
return Plugin_Handled; return Plugin_Handled;
} }
public Action Command_DisableRTV(int client, int args) public Action Command_DisableRTV(int client, int args)
{ {
if(!g_RTVAllowed) if(!g_RTVAllowed)
return Plugin_Handled; return Plugin_Handled;
ShowActivity2(client, "[RTVE] ", "disabled RockTheVote."); ShowActivity2(client, "[RTVE] ", "disabled RockTheVote.");
g_RTVAllowed = false; g_RTVAllowed = false;
return Plugin_Handled; return Plugin_Handled;
} }
public Action Command_EnableRTV(int client, int args) public Action Command_EnableRTV(int client, int args)
{ {
if(g_RTVAllowed) if(g_RTVAllowed)
return Plugin_Handled; return Plugin_Handled;
ShowActivity2(client, "[RTVE] ", "enabled RockTheVote"); ShowActivity2(client, "[RTVE] ", "enabled RockTheVote");
g_RTVAllowed = true; g_RTVAllowed = true;
return Plugin_Handled; return Plugin_Handled;
} }
void SetupTimeOverTimer() void SetupTimeOverTimer()
{ {
int time; int time;
if(GetMapTimeLeft(time) && time > 0) if(GetMapTimeLeft(time) && time > 0)
{ {
if(g_TimeOverTimer != INVALID_HANDLE) if(g_TimeOverTimer != INVALID_HANDLE)
{ {
KillTimer(g_TimeOverTimer); KillTimer(g_TimeOverTimer);
g_TimeOverTimer = INVALID_HANDLE; g_TimeOverTimer = INVALID_HANDLE;
} }
g_TimeOverTimer = CreateTimer(float(time), Timer_MapOver, _, TIMER_FLAG_NO_MAPCHANGE); g_TimeOverTimer = CreateTimer(float(time), Timer_MapOver, _, TIMER_FLAG_NO_MAPCHANGE);
} }
} }
public Action Timer_MapOver(Handle timer) public Action Timer_MapOver(Handle timer)
{ {
g_TimeOverTimer = INVALID_HANDLE; g_TimeOverTimer = INVALID_HANDLE;
if(g_Cvar_RTVAutoDisable.BoolValue) if(g_Cvar_RTVAutoDisable.BoolValue)
g_RTVAllowed = false; g_RTVAllowed = false;
} }