New mapchooser, rockthevote and nominations plugins finally ready. Removed the existing mapmanager stuff.
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402313
This commit is contained in:
parent
ac9b9f8c2a
commit
4106620928
80
plugins/include/mapchooser.inc
Normal file
80
plugins/include/mapchooser.inc
Normal file
@ -0,0 +1,80 @@
|
||||
#if defined _mapchooser_included_
|
||||
#endinput
|
||||
#endif
|
||||
#define _mapchooser_included_
|
||||
|
||||
enum NominateResult
|
||||
{
|
||||
Nominate_Added, /** The map was added to the nominate list */
|
||||
Nominate_Replaced, /** A clients existing nomination was replaced */
|
||||
Nominate_AlreadyInVote, /** Specified map was already in the vote */
|
||||
Nominate_InvalidMap, /** Mapname specifed wasn't a valid map */
|
||||
Nominate_VoteFull, /** This will only occur if force was set to false */
|
||||
};
|
||||
|
||||
enum MapChange
|
||||
{
|
||||
MapChange_Instant, /** Change map as soon as the voting results have come in */
|
||||
MapChange_RoundEnd, /** Change map at the end of the round */
|
||||
MapChange_MapEnd, /** Change the sm_nextmap cvar */
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to add a map to the mapchooser map list.
|
||||
*
|
||||
* @param map Map to add.
|
||||
* @param force Should we force the map in even if it requires overwriting an existing nomination?
|
||||
* @param owner Client index of the nominater. If the client disconnects the nomination will be removed. Use 0 for constant nominations
|
||||
* @return Nominate Result of the outcome
|
||||
*/
|
||||
native NominateResult:NominateMap(const String:map[], bool:force, owner);
|
||||
|
||||
/**
|
||||
* Gets the current list of excluded maps.
|
||||
*
|
||||
* @param array An ADT array handle to add the map strings to. Needs to be
|
||||
* @noreturn
|
||||
*/
|
||||
native GetExcludeMapList(Handle:array);
|
||||
|
||||
/**
|
||||
* Checks if MapChooser will allow a vote
|
||||
*
|
||||
* @return True if a vote can be held, or false if mapchooser is already holding a vote.
|
||||
*/
|
||||
native bool:CanMapChooserStartVote();
|
||||
|
||||
/**
|
||||
* Initiates a MapChooser map vote
|
||||
*
|
||||
* Note: If no input array is specified mapchooser will use its internal list. This includes
|
||||
* any nominations and excluded maps (as per mapchoosers convars).
|
||||
*
|
||||
* @param when MapChange consant of when the resulting mapchange should occur.
|
||||
* @param inputarray ADT array list of maps to add to the vote.
|
||||
*/
|
||||
native InitiateMapChooserVote(MapChange:when, Handle:inputarray=INVALID_HANDLE);
|
||||
|
||||
|
||||
/**
|
||||
* A horribly named native that checks if MapChooser's end of map vote has completed.
|
||||
*/
|
||||
native bool:HasEndOfMapVoteFinished();
|
||||
|
||||
/**
|
||||
* Called when mapchooser removes a nomination from its list.
|
||||
* Nominations cleared on map start will not trigger this forward
|
||||
*/
|
||||
forward OnNominationRemoved(String:map[], owner);
|
||||
|
||||
|
||||
public SharedPlugin:__pl_mapchooser =
|
||||
{
|
||||
name = "mapchooser",
|
||||
file = "mapchooser.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
@ -72,7 +72,7 @@ struct Plugin
|
||||
#include <adt>
|
||||
#include <banning>
|
||||
#include <commandfilters>
|
||||
//#include <nextmap>
|
||||
#include <nextmap>
|
||||
|
||||
/**
|
||||
* Declare this as a struct in your plugin to expose its information.
|
||||
|
@ -34,6 +34,11 @@
|
||||
|
||||
#pragma semicolon 1
|
||||
#include <sourcemod>
|
||||
#include <mapchooser>
|
||||
#include <nextmap>
|
||||
#undef REQUIRE_EXTENSIONS
|
||||
#include <tf2>
|
||||
#define REQUIRE_EXTENSIONS
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
@ -44,12 +49,13 @@ public Plugin:myinfo =
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
/* Valve ConVars */
|
||||
new Handle:g_Cvar_Winlimit = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Maxrounds = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Fraglimit = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Bonusroundtime = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Cvar_Nextmap = INVALID_HANDLE;
|
||||
|
||||
/* Plugin ConVars */
|
||||
new Handle:g_Cvar_StartTime = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_StartRounds = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_StartFrags = INVALID_HANDLE;
|
||||
@ -60,22 +66,39 @@ new Handle:g_Cvar_ExcludeMaps = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_IncludeMaps = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_NoVoteMode = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Extend = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Cvar_DontChange = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_EndOfMapVote = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_VoteDuration = INVALID_HANDLE;
|
||||
new Handle:g_VoteTimer = INVALID_HANDLE;
|
||||
new Handle:g_RetryTimer = INVALID_HANDLE;
|
||||
|
||||
/* Data Handles */
|
||||
new Handle:g_MapList = INVALID_HANDLE;
|
||||
new Handle:g_NominateList = INVALID_HANDLE;
|
||||
new Handle:g_NominateOwners = INVALID_HANDLE;
|
||||
new Handle:g_OldMapList = INVALID_HANDLE;
|
||||
new Handle:g_NextMapList = INVALID_HANDLE;
|
||||
new Handle:g_TeamScores = INVALID_HANDLE;
|
||||
new Handle:g_VoteMenu = INVALID_HANDLE;
|
||||
|
||||
new g_Extends;
|
||||
new g_TotalRounds;
|
||||
new bool:g_HasVoteStarted;
|
||||
new bool:g_WaitingForVote;
|
||||
new bool:g_MapVoteCompleted;
|
||||
new bool:g_ChangeMapAtRoundEnd;
|
||||
new g_mapFileSerial = -1;
|
||||
|
||||
new g_NominateCount = 0;
|
||||
new MapChange:g_ChangeTime;
|
||||
|
||||
new Handle:g_NominationsResetForward = INVALID_HANDLE;
|
||||
|
||||
/* Upper bound of how many team there could be */
|
||||
#define MAXTEAMS 10
|
||||
new g_winCount[MAXTEAMS];
|
||||
|
||||
#define VOTE_EXTEND "##extend##"
|
||||
#define VOTE_DONTCHANGE "##dontchange##"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
@ -83,30 +106,38 @@ public OnPluginStart()
|
||||
|
||||
new arraySize = ByteCountToCells(33);
|
||||
g_MapList = CreateArray(arraySize);
|
||||
g_NominateList = CreateArray(arraySize);
|
||||
g_NominateOwners = CreateArray(1);
|
||||
g_OldMapList = CreateArray(arraySize);
|
||||
g_NextMapList = CreateArray(arraySize);
|
||||
|
||||
g_Cvar_EndOfMapVote = CreateConVar("sm_mapvote_endvote", "1", "Specifies if MapChooser should run an end of map vote", _, true, 0.0, true, 1.0);
|
||||
HookConVarChange(g_Cvar_EndOfMapVote, EndVoteChanged);
|
||||
|
||||
g_Cvar_StartTime = CreateConVar("sm_mapvote_start", "3.0", "Specifies when to start the vote based on time remaining.", _, true, 1.0);
|
||||
g_Cvar_StartRounds = CreateConVar("sm_mapvote_startround", "2.0", "Specifies when to start the vote based on rounds remaining.", _, true, 1.0);
|
||||
g_Cvar_StartRounds = CreateConVar("sm_mapvote_startround", "2.0", "Specifies when to start the vote based on rounds remaining. Use 0 on TF2 to start vote during bonus round time", _, true, 0.0);
|
||||
g_Cvar_StartFrags = CreateConVar("sm_mapvote_startfrags", "5.0", "Specifies when to start the vote base on frags remaining.", _, true, 1.0);
|
||||
g_Cvar_ExtendTimeStep = CreateConVar("sm_extendmap_timestep", "15", "Specifies how much many more minutes each extension makes", _, true, 5.0);
|
||||
g_Cvar_ExtendRoundStep = CreateConVar("sm_extendmap_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 5.0);
|
||||
g_Cvar_ExtendRoundStep = CreateConVar("sm_extendmap_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 1.0);
|
||||
g_Cvar_ExtendFragStep = CreateConVar("sm_extendmap_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0);
|
||||
g_Cvar_ExcludeMaps = CreateConVar("sm_mapvote_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0);
|
||||
g_Cvar_IncludeMaps = CreateConVar("sm_mapvote_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0);
|
||||
g_Cvar_NoVoteMode = CreateConVar("sm_mapvote_novote", "1", "Specifies whether or not MapChooser should pick a map if no votes are received.", _, true, 0.0, true, 1.0);
|
||||
g_Cvar_Extend = CreateConVar("sm_mapvote_extend", "0", "Number of extensions allowed each map.", _, true, 0.0);
|
||||
|
||||
g_Cvar_DontChange = CreateConVar("sm_mapvote_dontchange", "1", "Specifies if a 'Don't Change' option should be added to early votes", _, true, 0.0);
|
||||
g_Cvar_VoteDuration = CreateConVar("sm_mapvote_voteduration", "20", "Specifies how long the mapvote should be available for.", _, true, 5.0, true, 25.0);
|
||||
RegAdminCmd("sm_mapvote", Command_Mapvote, ADMFLAG_CHANGEMAP, "sm_mapvote - Forces MapChooser to attempt to run a map vote now.");
|
||||
|
||||
g_Cvar_Winlimit = FindConVar("mp_winlimit");
|
||||
g_Cvar_Maxrounds = FindConVar("mp_maxrounds");
|
||||
g_Cvar_Fraglimit = FindConVar("mp_fraglimit");
|
||||
g_Cvar_Bonusroundtime = FindConVar("mp_bonusroundtime");
|
||||
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE || g_Cvar_Maxrounds != INVALID_HANDLE)
|
||||
{
|
||||
HookEvent("round_end", Event_RoundEnd);
|
||||
HookEventEx("teamplay_round_win", Event_TeamPlayRoundWin);
|
||||
HookEventEx("teamplay_win_panel", Event_TeamPlayWinPanel);
|
||||
HookEventEx("teamplay_restart_round", Event_TFRestartRound);
|
||||
}
|
||||
|
||||
if (g_Cvar_Fraglimit != INVALID_HANDLE)
|
||||
@ -115,18 +146,37 @@ public OnPluginStart()
|
||||
}
|
||||
|
||||
AutoExecConfig(true, "mapchooser");
|
||||
|
||||
//Change the mp_bonusroundtime max so that we have time to display the vote
|
||||
//If you display a vote during bonus time good defaults are 17 vote duration and 19 mp_bonustime
|
||||
if (g_Cvar_Bonusroundtime != INVALID_HANDLE)
|
||||
{
|
||||
SetConVarBounds(g_Cvar_Bonusroundtime, ConVarBound_Upper, true, 30.0);
|
||||
}
|
||||
|
||||
RegPluginLibrary("mapchooser");
|
||||
|
||||
g_NominationsResetForward = CreateGlobalForward("OnNominationRemoved", ET_Ignore, Param_String, Param_Cell);
|
||||
}
|
||||
|
||||
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
|
||||
{
|
||||
CreateNative("NominateMap", Native_NominateMap);
|
||||
CreateNative("InitiateMapChooserVote", Native_InitiateVote);
|
||||
CreateNative("CanMapChooserStartVote", Native_CanVoteStart);
|
||||
CreateNative("HasEndOfMapVoteFinished", Native_CheckVoteDone);
|
||||
CreateNative("GetExcludeMapList", Native_GetExcludeMapList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
Call_Cancel();
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
g_Cvar_Nextmap = FindConVar("sm_nextmap");
|
||||
|
||||
if (g_Cvar_Nextmap == INVALID_HANDLE)
|
||||
{
|
||||
LogError("FATAL: Cannot find sm_nextmap cvar. Mapchooser not loaded.");
|
||||
SetFailState("sm_nextmap not found");
|
||||
}
|
||||
|
||||
if (ReadMapList(g_MapList,
|
||||
g_mapFileSerial,
|
||||
"mapchooser",
|
||||
@ -142,22 +192,37 @@ public OnConfigsExecuted()
|
||||
|
||||
CreateNextVote();
|
||||
SetupTimeleftTimer();
|
||||
SetConVarString(g_Cvar_Nextmap, "Pending Vote");
|
||||
|
||||
if (g_TeamScores != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_TeamScores);
|
||||
}
|
||||
|
||||
g_TeamScores = CreateArray(2);
|
||||
g_TotalRounds = 0;
|
||||
|
||||
g_Extends = 0;
|
||||
|
||||
g_MapVoteCompleted = false;
|
||||
|
||||
g_NominateCount = 0;
|
||||
ClearArray(g_NominateList);
|
||||
ClearArray(g_NominateOwners);
|
||||
|
||||
for (new i=0; i<MAXTEAMS; i++)
|
||||
{
|
||||
g_winCount[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check if mapchooser will attempt to start mapvote during bonus round time - TF2 Only */
|
||||
if ((g_Cvar_Bonusroundtime != INVALID_HANDLE) && !GetConVarInt(g_Cvar_StartRounds))
|
||||
{
|
||||
if (GetConVarFloat(g_Cvar_Bonusroundtime) <= GetConVarFloat(g_Cvar_VoteDuration))
|
||||
{
|
||||
LogError("Warning - Bonus Round Time shorter than Vote Time. Votes during bonus round may not have time to complete");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapEnd()
|
||||
{
|
||||
g_HasVoteStarted = false;
|
||||
g_WaitingForVote = false;
|
||||
|
||||
if (g_VoteTimer != INVALID_HANDLE)
|
||||
{
|
||||
@ -170,6 +235,48 @@ public OnMapEnd()
|
||||
KillTimer(g_RetryTimer);
|
||||
g_RetryTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
decl String:map[32];
|
||||
GetCurrentMap(map, sizeof(map));
|
||||
PushArrayString(g_OldMapList, map);
|
||||
|
||||
if (GetArraySize(g_OldMapList) > GetConVarInt(g_Cvar_ExcludeMaps))
|
||||
{
|
||||
RemoveFromArray(g_OldMapList, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public OnClientDisconnect(client)
|
||||
{
|
||||
new index = FindValueInArray(g_NominateOwners, client);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new String:oldmap[33];
|
||||
GetArrayString(g_NominateList, index, oldmap, sizeof(oldmap));
|
||||
Call_StartForward(g_NominationsResetForward);
|
||||
Call_PushString(oldmap);
|
||||
Call_PushCell(GetArrayCell(g_NominateOwners, index));
|
||||
Call_Finish();
|
||||
|
||||
RemoveFromArray(g_NominateOwners, index);
|
||||
RemoveFromArray(g_NominateList, index);
|
||||
g_NominateCount--;
|
||||
}
|
||||
|
||||
public EndVoteChanged(Handle:convar, const String:oldValue[], const String:newValue[])
|
||||
{
|
||||
if (newValue[0] == '1')
|
||||
{
|
||||
SetNextMap("Pending Vote");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextMap("");
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapTimeLeftChanged()
|
||||
@ -186,9 +293,9 @@ SetupTimeleftTimer()
|
||||
if (GetMapTimeLeft(time) && time > 0)
|
||||
{
|
||||
new startTime = GetConVarInt(g_Cvar_StartTime) * 60;
|
||||
if (time - startTime < 0)
|
||||
if (time - startTime < 0 && GetConVarBool(g_Cvar_EndOfMapVote) && !g_MapVoteCompleted && !g_HasVoteStarted)
|
||||
{
|
||||
InitiateVote();
|
||||
InitiateVote(MapChange_MapEnd, INVALID_HANDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -205,7 +312,7 @@ SetupTimeleftTimer()
|
||||
|
||||
public Action:Timer_StartMapVote(Handle:timer)
|
||||
{
|
||||
if (!GetArraySize(g_MapList))
|
||||
if (!GetArraySize(g_MapList) || !GetConVarBool(g_Cvar_EndOfMapVote) || g_MapVoteCompleted || g_HasVoteStarted)
|
||||
{
|
||||
return Plugin_Stop;
|
||||
}
|
||||
@ -218,87 +325,116 @@ public Action:Timer_StartMapVote(Handle:timer)
|
||||
{
|
||||
g_VoteTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
InitiateVote();
|
||||
|
||||
InitiateVote(MapChange_MapEnd, INVALID_HANDLE);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
public Event_TeamPlayRoundWin(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
public Event_TFRestartRound(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new isFull = GetEventInt(event, "full_round");
|
||||
new winningTeam = GetEventInt(event, "team");
|
||||
|
||||
if (isFull == 1)
|
||||
/* Game got restarted - reset our round count tracking */
|
||||
g_TotalRounds = 0;
|
||||
}
|
||||
|
||||
public Event_TeamPlayWinPanel(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
if (g_ChangeMapAtRoundEnd)
|
||||
{
|
||||
RoundCompleted(winningTeam);
|
||||
g_ChangeMapAtRoundEnd = false;
|
||||
CreateTimer(2.0, Timer_ChangeMap, INVALID_HANDLE);
|
||||
}
|
||||
|
||||
if (!GetArraySize(g_MapList) || g_HasVoteStarted || g_MapVoteCompleted || !GetConVarBool(g_Cvar_EndOfMapVote))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new bluescore = GetEventInt(event, "blue_score");
|
||||
new redscore = GetEventInt(event, "red_score");
|
||||
|
||||
if(GetEventInt(event, "round_complete") == 1)
|
||||
{
|
||||
switch(GetEventInt(event, "winning_team"))
|
||||
{
|
||||
case TFTeam_Blue:
|
||||
{
|
||||
CheckWinLimit(bluescore);
|
||||
}
|
||||
case TFTeam_Red:
|
||||
{
|
||||
CheckWinLimit(redscore);
|
||||
}
|
||||
//We need to do nothing on winning_team == 0 this indicates stalemate.
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_TotalRounds++;
|
||||
CheckMaxRounds(g_TotalRounds);
|
||||
}
|
||||
}
|
||||
/* You ask, why don't you just use team_score event? And I answer... Because CSS doesn't. */
|
||||
public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
if (!GetArraySize(g_MapList) || g_HasVoteStarted)
|
||||
if (g_ChangeMapAtRoundEnd)
|
||||
{
|
||||
g_ChangeMapAtRoundEnd = false;
|
||||
CreateTimer(2.0, Timer_ChangeMap, INVALID_HANDLE);
|
||||
}
|
||||
|
||||
if (!GetArraySize(g_MapList) || g_HasVoteStarted || g_MapVoteCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new winner = GetEventInt(event, "winner");
|
||||
|
||||
RoundCompleted(winner);
|
||||
}
|
||||
|
||||
public RoundCompleted(winner)
|
||||
{
|
||||
if (winner == 0 || winner == 1)
|
||||
if (winner == 0 || winner == 1 || !GetConVarBool(g_Cvar_EndOfMapVote))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (winner >= MAXTEAMS)
|
||||
{
|
||||
SetFailState("Mod exceed maximum team count - Please file a bug report.");
|
||||
}
|
||||
|
||||
g_TotalRounds++;
|
||||
|
||||
new team[2], teamPos = -1;
|
||||
for (new i; i < GetArraySize(g_TeamScores); i++)
|
||||
{
|
||||
GetArrayArray(g_TeamScores, i, team);
|
||||
if (team[0] == winner)
|
||||
{
|
||||
teamPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (teamPos == -1)
|
||||
{
|
||||
team[0] = winner;
|
||||
team[1] = 1;
|
||||
PushArrayArray(g_TeamScores, team);
|
||||
}
|
||||
else
|
||||
{
|
||||
team[1]++;
|
||||
SetArrayArray(g_TeamScores, teamPos, team);
|
||||
}
|
||||
g_winCount[winner]++;
|
||||
|
||||
CheckWinLimit(g_winCount[winner]);
|
||||
CheckMaxRounds(g_TotalRounds);
|
||||
}
|
||||
|
||||
public CheckWinLimit(winner_score)
|
||||
{
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE)
|
||||
{
|
||||
new winlimit = GetConVarInt(g_Cvar_Winlimit);
|
||||
if (winlimit)
|
||||
{
|
||||
if (team[1] >= (winlimit - GetConVarInt(g_Cvar_StartRounds)))
|
||||
{
|
||||
if (winner_score >= (winlimit - GetConVarInt(g_Cvar_StartRounds)))
|
||||
{
|
||||
InitiateVote();
|
||||
InitiateVote(MapChange_MapEnd, INVALID_HANDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CheckMaxRounds(roundcount)
|
||||
{
|
||||
if (g_Cvar_Maxrounds != INVALID_HANDLE)
|
||||
{
|
||||
new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
|
||||
if (maxrounds)
|
||||
{
|
||||
if (g_TotalRounds >= (maxrounds - GetConVarInt(g_Cvar_StartRounds)))
|
||||
if (roundcount >= (maxrounds - GetConVarInt(g_Cvar_StartRounds)))
|
||||
{
|
||||
InitiateVote();
|
||||
InitiateVote(MapChange_MapEnd, INVALID_HANDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -311,7 +447,7 @@ public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetConVarInt(g_Cvar_Fraglimit))
|
||||
if (!GetConVarInt(g_Cvar_Fraglimit) || !GetConVarBool(g_Cvar_EndOfMapVote))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -319,54 +455,249 @@ public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
new fragger = GetClientOfUserId(GetEventInt(event, "attacker"));
|
||||
if (fragger && GetClientFrags(fragger) >= (GetConVarInt(g_Cvar_Fraglimit) - GetConVarInt(g_Cvar_StartFrags)))
|
||||
{
|
||||
InitiateVote();
|
||||
InitiateVote(MapChange_MapEnd, INVALID_HANDLE);
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Mapvote(client, args)
|
||||
{
|
||||
InitiateVote();
|
||||
InitiateVote(MapChange_MapEnd, INVALID_HANDLE);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
InitiateVote()
|
||||
InitiateVote(MapChange:when, Handle:inputlist)
|
||||
{
|
||||
if (g_HasVoteStarted || g_RetryTimer != INVALID_HANDLE)
|
||||
if (!CanVoteStart())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_WaitingForVote = true;
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
// Can't start a vote, try again in 5 seconds.
|
||||
g_RetryTimer = CreateTimer(5.0, Timer_StartMapVote);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_ChangeTime = when;
|
||||
|
||||
g_WaitingForVote = false;
|
||||
|
||||
g_HasVoteStarted = true;
|
||||
g_VoteMenu = CreateMenu(Handler_MapVoteMenu, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_VoteMenu, "Vote Nextmap");
|
||||
|
||||
SetVoteResultCallback(g_VoteMenu, Handler_MapVoteFinished);
|
||||
|
||||
/**
|
||||
* TODO: Make a proper decision on when to clear the nominations list.
|
||||
* Currently it clears when used, and stays if an external list is provided.
|
||||
* Is this the right thing to do? External lists will probably come from places
|
||||
* like sm_mapvote from the adminmenu in the future.
|
||||
*/
|
||||
|
||||
decl String:map[32];
|
||||
for (new i = 0; i < GetArraySize(g_NextMapList); i++)
|
||||
|
||||
/* No input given - User our internal nominations and maplist */
|
||||
if (inputlist == INVALID_HANDLE)
|
||||
{
|
||||
GetArrayString(g_NextMapList, i, map, sizeof(map));
|
||||
AddMenuItem(g_VoteMenu, map, map);
|
||||
new nominateCount = GetArraySize(g_NominateList);
|
||||
new voteSize = GetConVarInt(g_Cvar_IncludeMaps);
|
||||
|
||||
/* Smaller of the two - It should be impossible for nominations to exceed the size though (cvar changed mid-map?) */
|
||||
new nominationsToAdd = nominateCount >= voteSize ? voteSize : nominateCount;
|
||||
|
||||
|
||||
for (new i=0; i<nominationsToAdd; i++)
|
||||
{
|
||||
GetArrayString(g_NominateList, i, map, sizeof(map));
|
||||
AddMenuItem(g_VoteMenu, map, map);
|
||||
|
||||
/* Notify Nominations that this map is now free */
|
||||
Call_StartForward(g_NominationsResetForward);
|
||||
Call_PushString(map);
|
||||
Call_PushCell(GetArrayCell(g_NominateOwners, i));
|
||||
Call_Finish();
|
||||
}
|
||||
|
||||
/* Clear out the rest of the nominations array */
|
||||
for (new i=nominationsToAdd; i<nominateCount; i++)
|
||||
{
|
||||
GetArrayString(g_NominateList, i, map, sizeof(map));
|
||||
|
||||
/* Notify Nominations that this map is now free */
|
||||
Call_StartForward(g_NominationsResetForward);
|
||||
Call_PushString(map);
|
||||
Call_PushCell(GetArrayCell(g_NominateOwners, i));
|
||||
Call_Finish();
|
||||
}
|
||||
|
||||
/* There should currently be 'nominationsToAdd' unique maps in the vote */
|
||||
|
||||
new i = nominationsToAdd;
|
||||
new count = 0;
|
||||
new availableMaps = GetArraySize(g_NextMapList);
|
||||
|
||||
while (i < voteSize)
|
||||
{
|
||||
GetArrayString(g_NextMapList, count, map, sizeof(map));
|
||||
count++;
|
||||
|
||||
//Check if this map is in the nominate list (and thus already in the vote) */
|
||||
if (FindStringInArray(g_NominateList, map) == -1)
|
||||
{
|
||||
/* Insert the map and increment our count */
|
||||
AddMenuItem(g_VoteMenu, map, map);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (count >= availableMaps)
|
||||
{
|
||||
//Run out of maps, this will have to do.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wipe out our nominations list - Nominations have already been informed of this */
|
||||
ClearArray(g_NominateOwners);
|
||||
ClearArray(g_NominateList);
|
||||
}
|
||||
|
||||
if (GetConVarBool(g_Cvar_Extend) && g_Extends < GetConVarInt(g_Cvar_Extend))
|
||||
else //We were given a list of maps to start the vote with
|
||||
{
|
||||
new size = GetArraySize(inputlist);
|
||||
|
||||
for (new i=0; i<size; i++)
|
||||
{
|
||||
GetArrayString(inputlist, i, map, sizeof(map));
|
||||
|
||||
if (IsMapValid(map))
|
||||
{
|
||||
AddMenuItem(g_VoteMenu, map, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we add any special items? */
|
||||
if ((when == MapChange_Instant || when == MapChange_RoundEnd) && GetConVarBool(g_Cvar_DontChange))
|
||||
{
|
||||
AddMenuItem(g_VoteMenu, VOTE_DONTCHANGE, "Don't Change");
|
||||
}
|
||||
else if (GetConVarBool(g_Cvar_Extend) && g_Extends < GetConVarInt(g_Cvar_Extend))
|
||||
{
|
||||
AddMenuItem(g_VoteMenu, VOTE_EXTEND, "Extend Map");
|
||||
}
|
||||
|
||||
new voteDuration = GetConVarInt(g_Cvar_VoteDuration);
|
||||
|
||||
SetMenuExitButton(g_VoteMenu, false);
|
||||
VoteMenuToAll(g_VoteMenu, 20);
|
||||
VoteMenuToAll(g_VoteMenu, voteDuration);
|
||||
|
||||
LogMessage("Voting for next map has started.");
|
||||
PrintToChatAll("[SM] %t", "Nextmap Voting Started");
|
||||
}
|
||||
|
||||
public Handler_MapVoteFinished(Handle:menu,
|
||||
num_votes,
|
||||
num_clients,
|
||||
const client_info[][2],
|
||||
num_items,
|
||||
const item_info[][2])
|
||||
{
|
||||
if (num_votes == 0)
|
||||
{
|
||||
LogError("No Votes recorded yet Advanced callback fired - Tell pRED* to fix this");
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:map[32];
|
||||
GetMenuItem(menu, item_info[0][VOTEINFO_ITEM_INDEX], map, sizeof(map));
|
||||
|
||||
if (strcmp(map, VOTE_EXTEND, false) == 0)
|
||||
{
|
||||
g_Extends++;
|
||||
|
||||
new time;
|
||||
if (GetMapTimeLimit(time))
|
||||
{
|
||||
if (time > 0)
|
||||
{
|
||||
ExtendMapTimeLimit(GetConVarInt(g_Cvar_ExtendTimeStep)*60);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE)
|
||||
{
|
||||
new winlimit = GetConVarInt(g_Cvar_Winlimit);
|
||||
if (winlimit)
|
||||
{
|
||||
SetConVarInt(g_Cvar_Winlimit, winlimit + GetConVarInt(g_Cvar_ExtendRoundStep));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Maxrounds != INVALID_HANDLE)
|
||||
{
|
||||
new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
|
||||
if (maxrounds)
|
||||
{
|
||||
SetConVarInt(g_Cvar_Maxrounds, maxrounds + GetConVarInt(g_Cvar_ExtendRoundStep));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Fraglimit != INVALID_HANDLE)
|
||||
{
|
||||
new fraglimit = GetConVarInt(g_Cvar_Fraglimit);
|
||||
if (fraglimit)
|
||||
{
|
||||
SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep));
|
||||
}
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Current Map Extended", RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes);
|
||||
LogMessage("Voting for next map has finished. The current map has been extended.");
|
||||
|
||||
// We extended, so we'll have to vote again.
|
||||
g_HasVoteStarted = false;
|
||||
CreateNextVote();
|
||||
SetupTimeleftTimer();
|
||||
|
||||
}
|
||||
else if (strcmp(map, VOTE_DONTCHANGE, false) == 0)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Current Map Stays", RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes);
|
||||
LogMessage("Voting for next map has finished. 'No Change' was the winner");
|
||||
|
||||
g_HasVoteStarted = false;
|
||||
CreateNextVote();
|
||||
SetupTimeleftTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_ChangeTime == MapChange_MapEnd)
|
||||
{
|
||||
SetNextMap(map);
|
||||
}
|
||||
else if (g_ChangeTime == MapChange_Instant)
|
||||
{
|
||||
new Handle:data;
|
||||
CreateDataTimer(2.0, Timer_ChangeMap, data);
|
||||
WritePackString(data, map);
|
||||
}
|
||||
else // MapChange_RoundEnd
|
||||
{
|
||||
SetNextMap(map);
|
||||
g_ChangeMapAtRoundEnd = true;
|
||||
}
|
||||
|
||||
g_HasVoteStarted = false;
|
||||
g_MapVoteCompleted = true;
|
||||
|
||||
PrintToChatAll("[SM] %t", "Nextmap Voting Finished", map, RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes);
|
||||
LogMessage("Voting for next map has finished. Nextmap: %s.", map);
|
||||
}
|
||||
}
|
||||
|
||||
public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
@ -397,20 +728,14 @@ public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
Format(buffer, sizeof(buffer), "%T", "Extend Map", param1);
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
else if (strcmp(map, VOTE_DONTCHANGE, false) == 0)
|
||||
{
|
||||
Format(buffer, sizeof(buffer), "%T", "Dont Change", param1);
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Why am I commented out? Because BAIL hasn't decided yet if
|
||||
// vote notification will be built into the Vote API.
|
||||
/*case MenuAction_Select:
|
||||
{
|
||||
decl String:Name[32], String:Map[32];
|
||||
GetClientName(param1, Name, sizeof(Name));
|
||||
GetMenuItem(menu, param2, Map, sizeof(Map));
|
||||
|
||||
PrintToChatAll("[SM] %s has voted for map '%s'", Name, Map);
|
||||
}*/
|
||||
|
||||
|
||||
case MenuAction_VoteCancel:
|
||||
{
|
||||
// If we receive 0 votes, pick at random.
|
||||
@ -432,84 +757,37 @@ public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
else
|
||||
{
|
||||
// We were actually cancelled. What should we do?
|
||||
}
|
||||
}
|
||||
|
||||
case MenuAction_VoteEnd:
|
||||
{
|
||||
decl String:map[32];
|
||||
GetMenuItem(menu, param1, map, sizeof(map));
|
||||
|
||||
if (strcmp(map, VOTE_EXTEND, false) == 0)
|
||||
{
|
||||
g_Extends++;
|
||||
|
||||
new time;
|
||||
if (GetMapTimeLimit(time))
|
||||
{
|
||||
if (time > 0)
|
||||
{
|
||||
ExtendMapTimeLimit(GetConVarInt(g_Cvar_ExtendTimeStep)*60);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE)
|
||||
{
|
||||
new winlimit = GetConVarInt(g_Cvar_Winlimit);
|
||||
if (winlimit)
|
||||
{
|
||||
SetConVarInt(g_Cvar_Winlimit, winlimit + GetConVarInt(g_Cvar_ExtendRoundStep));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Maxrounds != INVALID_HANDLE)
|
||||
{
|
||||
new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
|
||||
if (maxrounds)
|
||||
{
|
||||
SetConVarInt(g_Cvar_Maxrounds, maxrounds + GetConVarInt(g_Cvar_ExtendRoundStep));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Fraglimit != INVALID_HANDLE)
|
||||
{
|
||||
new fraglimit = GetConVarInt(g_Cvar_Fraglimit);
|
||||
if (fraglimit)
|
||||
{
|
||||
SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep));
|
||||
}
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Current Map Extended");
|
||||
LogMessage("Voting for next map has finished. The current map has been extended.");
|
||||
|
||||
// We extended, so we'll have to vote again.
|
||||
g_HasVoteStarted = false;
|
||||
CreateNextVote();
|
||||
SetupTimeleftTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextMap(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetNextMap(const String:map[])
|
||||
public Action:Timer_ChangeMap(Handle:hTimer, Handle:dp)
|
||||
{
|
||||
SetConVarString(g_Cvar_Nextmap, map);
|
||||
PushArrayString(g_OldMapList, map);
|
||||
|
||||
if (GetArraySize(g_OldMapList) > GetConVarInt(g_Cvar_ExcludeMaps))
|
||||
new String:map[65];
|
||||
|
||||
if (dp == INVALID_HANDLE)
|
||||
{
|
||||
RemoveFromArray(g_OldMapList, 0);
|
||||
if (!GetNextMap(map, sizeof(map)))
|
||||
{
|
||||
//No passed map and no set nextmap. fail!
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Nextmap Voting Finished", map);
|
||||
LogMessage("Voting for next map has finished. Nextmap: %s.", map);
|
||||
else
|
||||
{
|
||||
ResetPack(dp);
|
||||
ReadPackString(dp, map, sizeof(map));
|
||||
}
|
||||
|
||||
ServerCommand("changelevel \"%s\"", map);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
CreateNextVote()
|
||||
@ -552,4 +830,131 @@ CreateNextVote()
|
||||
}
|
||||
|
||||
CloseHandle(tempMaps);
|
||||
}
|
||||
|
||||
bool:CanVoteStart()
|
||||
{
|
||||
if (g_WaitingForVote || g_HasVoteStarted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NominateResult:InternalNominateMap(String:map[], bool:force, owner)
|
||||
{
|
||||
if (!IsMapValid(map))
|
||||
{
|
||||
return Nominate_InvalidMap;
|
||||
}
|
||||
|
||||
new index;
|
||||
|
||||
if ((index = FindValueInArray(g_NominateOwners, owner)) != -1)
|
||||
{
|
||||
new String:oldmap[33];
|
||||
GetArrayString(g_NominateList, index, oldmap, sizeof(oldmap));
|
||||
Call_StartForward(g_NominationsResetForward);
|
||||
Call_PushString(oldmap);
|
||||
Call_PushCell(owner);
|
||||
Call_Finish();
|
||||
|
||||
|
||||
SetArrayString(g_NominateList, index, map);
|
||||
return Nominate_Replaced;
|
||||
}
|
||||
|
||||
/* Too many nominated maps. */
|
||||
if (g_NominateCount >= GetConVarInt(g_Cvar_IncludeMaps) && !force)
|
||||
{
|
||||
return Nominate_VoteFull;
|
||||
}
|
||||
|
||||
/* Map already in the vote */
|
||||
if (FindStringInArray(g_NominateList, map) != -1)
|
||||
{
|
||||
return Nominate_AlreadyInVote;
|
||||
}
|
||||
|
||||
|
||||
PushArrayString(g_NominateList, map);
|
||||
PushArrayCell(g_NominateOwners, owner);
|
||||
g_NominateCount++;
|
||||
|
||||
while (GetArraySize(g_NominateList) > GetConVarInt(g_Cvar_IncludeMaps))
|
||||
{
|
||||
new String:oldmap[33];
|
||||
GetArrayString(g_NominateList, 0, oldmap, sizeof(oldmap));
|
||||
Call_StartForward(g_NominationsResetForward);
|
||||
Call_PushString(oldmap);
|
||||
Call_PushCell(GetArrayCell(g_NominateOwners, 0));
|
||||
Call_Finish();
|
||||
|
||||
RemoveFromArray(g_NominateList, 0);
|
||||
RemoveFromArray(g_NominateOwners, 0);
|
||||
}
|
||||
|
||||
return Nominate_Added;
|
||||
}
|
||||
|
||||
/* Add natives to allow nominate and initiate vote to be call */
|
||||
|
||||
/* native bool:NominateMap(const String:map[], bool:force, &NominateError:error); */
|
||||
public Native_NominateMap(Handle:plugin, numParams)
|
||||
{
|
||||
new len;
|
||||
GetNativeStringLength(1, len);
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
new String:map[len+1];
|
||||
GetNativeString(1, map, len+1);
|
||||
|
||||
return _:InternalNominateMap(map, GetNativeCell(2), GetNativeCell(3));
|
||||
}
|
||||
|
||||
/* native InitiateMapChooserVote(); */
|
||||
public Native_InitiateVote(Handle:plugin, numParams)
|
||||
{
|
||||
new MapChange:when = MapChange:GetNativeCell(1);
|
||||
new Handle:inputarray = Handle:GetNativeCell(2);
|
||||
|
||||
LogMessage("Starting map vote because outside request");
|
||||
InitiateVote(when, inputarray);
|
||||
}
|
||||
|
||||
public Native_CanVoteStart(Handle:plugin, numParams)
|
||||
{
|
||||
return CanVoteStart();
|
||||
}
|
||||
|
||||
public Native_CheckVoteDone(Handle:plugin, numParams)
|
||||
{
|
||||
return g_MapVoteCompleted;
|
||||
}
|
||||
|
||||
public Native_GetExcludeMapList(Handle:plugin, numParams)
|
||||
{
|
||||
new Handle:array = Handle:GetNativeCell(1);
|
||||
|
||||
if (array == INVALID_HANDLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
new size = GetArraySize(g_OldMapList);
|
||||
decl String:map[33];
|
||||
|
||||
for (new i=0; i<size; i++)
|
||||
{
|
||||
GetArrayString(g_OldMapList, i, map, sizeof(map));
|
||||
PushArrayString(array, map);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
@ -1,370 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Management Plugin
|
||||
* Provides all map related functionality, including map changing, map voting,
|
||||
* and nextmap.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
#include <sourcemod>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Map Manager",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Map Management",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
#include "mapmanager/globals.sp"
|
||||
#include "mapmanager/commands.sp"
|
||||
#include "mapmanager/events.sp"
|
||||
#include "mapmanager/functions.sp"
|
||||
#include "mapmanager/functions_menu.sp"
|
||||
#include "mapmanager/menus.sp"
|
||||
#include "mapmanager/timers.sp"
|
||||
#include "mapmanager/votes.sp"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("mapmanager.phrases");
|
||||
|
||||
// Prepare nextmap functionality.
|
||||
g_VGUIMenu = GetUserMessageId("VGUIMenu");
|
||||
if (g_VGUIMenu == INVALID_MESSAGE_ID)
|
||||
{
|
||||
LogError("FATAL: Cannot find VGUIMenu user message id. MapManager crippled.");
|
||||
g_NextMapEnabled = false;
|
||||
}
|
||||
HookUserMessage(g_VGUIMenu, UserMsg_VGUIMenu);
|
||||
|
||||
// Create all of the arrays, sized for a 64 character string.
|
||||
new arraySize = ByteCountToCells(64);
|
||||
g_MapCycle = CreateArray(arraySize);
|
||||
g_MapList = CreateArray(arraySize);
|
||||
g_MapHistory = CreateArray(arraySize);
|
||||
g_NextVoteMaps = CreateArray(arraySize);
|
||||
g_SelectedMaps = CreateArray(arraySize);
|
||||
g_NominatedMaps = CreateArray(arraySize);
|
||||
|
||||
g_TeamScores = CreateArray(2);
|
||||
|
||||
// Hook say
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
// Register all commands.
|
||||
RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map <map> [r/e]");
|
||||
RegAdminCmd("sm_setnextmap", Command_SetNextmap, ADMFLAG_CHANGEMAP, "sm_setnextmap <map>");
|
||||
RegAdminCmd("sm_votemap", Command_Votemap, ADMFLAG_VOTE|ADMFLAG_CHANGEMAP, "sm_votemap <mapname> [mapname2] ... [mapname5] ");
|
||||
RegAdminCmd("sm_maplist", Command_List, ADMFLAG_GENERIC, "sm_maplist");
|
||||
RegAdminCmd("sm_nominate", Command_Nominate, ADMFLAG_CHANGEMAP, "sm_nominate <mapname> - Nominates a map for RockTheVote and MapChooser. Overrides existing nominations.");
|
||||
RegAdminCmd("sm_mapvote", Command_Mapvote, ADMFLAG_CHANGEMAP, "sm_mapvote - Forces the MapChooser vote to occur.");
|
||||
|
||||
if (GetCommandFlags("nextmap") == INVALID_FCVAR_FLAGS)
|
||||
{
|
||||
RegServerCmd("nextmap", Command_Nextmap);
|
||||
}
|
||||
|
||||
// Register all convars
|
||||
g_Cvar_NextMap = CreateConVar("sm_nextmap", "", "Sets the Next Map", FCVAR_NOTIFY);
|
||||
|
||||
g_Cvar_MapCount = CreateConVar("sm_mm_maps", "4", "Number of maps to be voted on at end of map or RTV. 2 to 6. (Def 4)", 0, true, 2.0, true, 6.0);
|
||||
g_Cvar_Excludes = CreateConVar("sm_mm_exclude", "5", "Specifies how many past maps to exclude from end of map vote and RTV.", _, true, 0.0);
|
||||
|
||||
g_Cvar_MapChooser = CreateConVar("sm_mm_mapchooser", "0", "Enables MapChooser (End of Map voting)", 0, true, 0.0, true, 1.0);
|
||||
g_Cvar_RockTheVote = CreateConVar("sm_mm_rockthevote", "0", "Enables RockTheVote (Player initiated map votes)", 0, true, 0.0, true, 1.0);
|
||||
g_Cvar_Randomize = CreateConVar("sm_mm_randomize", "0", "Enabled Randomizer (Randomly picks the next map)", 0, true, 0.0, true, 1.0);
|
||||
g_Cvar_Nominate = CreateConVar("sm_mm_nominate", "1", "Enables nomination system.", 0, true, 0.0, true, 1.0);
|
||||
|
||||
g_Cvar_VoteMap = CreateConVar("sm_mm_votemap", "0.60", "Percentage required for successful sm_votemap.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_RTVLimit = CreateConVar("sm_mm_rtvlimit", "0.60", "Required percentage of players needed to rockthevote", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_MinPlayers = CreateConVar("sm_mm_minplayers", "0", "Number of players required before RTV will be enabled.", 0, true, 0.0, true, float(MAXPLAYERS));
|
||||
|
||||
g_Cvar_StartTime = CreateConVar("sm_mapvote_start", "3.0", "Specifies when to start the vote based on time remaining.", _, true, 1.0);
|
||||
g_Cvar_StartRounds = CreateConVar("sm_mapvote_startround", "2.0", "Specifies when to start the vote based on rounds remaining.", _, true, 1.0);
|
||||
g_Cvar_StartFrags = CreateConVar("sm_mapvote_startfrags", "5.0", "Specifies when to start the vote base on frags remaining.", _, true, 1.0);
|
||||
g_Cvar_ExtendTimeMax = CreateConVar("sm_extendmap_maxtime", "90", "Specifies the maximum amount of time a map can be extended", _, true, 0.0);
|
||||
g_Cvar_ExtendTimeStep = CreateConVar("sm_extendmap_timestep", "15", "Specifies how much many more minutes each extension makes", _, true, 5.0);
|
||||
g_Cvar_ExtendRoundMax = CreateConVar("sm_extendmap_maxrounds", "30", "Specfies the maximum amount of rounds a map can be extended", _, true, 0.0);
|
||||
g_Cvar_ExtendRoundStep = CreateConVar("sm_extendmap_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 5.0);
|
||||
g_Cvar_ExtendFragMax = CreateConVar("sm_extendmap_maxfrags", "150", "Specfies the maximum frags allowed that a map can be extended.", _, true, 0.0);
|
||||
g_Cvar_ExtendFragStep = CreateConVar("sm_extendmap_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0);
|
||||
g_Cvar_Mapfile = CreateConVar("sm_mapvote_file", "configs/maps.ini", "Map file to use. (Def sourcemod/configs/maps.ini)");
|
||||
g_Cvar_ExcludeMaps = CreateConVar("sm_mapvote_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0);
|
||||
g_Cvar_IncludeMaps = CreateConVar("sm_mapvote_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0);
|
||||
g_Cvar_NoVoteMode = CreateConVar("sm_mapvote_novote", "1", "Specifies whether or not MapChooser should pick a map if no votes are received.", _, true, 0.0, true, 1.0);
|
||||
g_Cvar_Extend = CreateConVar("sm_mapvote_extend", "1", "Specifies whether or not MapChooser will allow the map to be extended.", _, true, 0.0, true, 1.0);
|
||||
|
||||
|
||||
// Find game convars
|
||||
g_Cvar_Chattime = FindConVar("mp_chattime");
|
||||
g_Cvar_Winlimit = FindConVar("mp_winlimit");
|
||||
g_Cvar_Maxrounds = FindConVar("mp_maxrounds");
|
||||
g_Cvar_Fraglimit = FindConVar("mp_fraglimit");
|
||||
|
||||
if (GetCommandFlags("nextmap") == INVALID_FCVAR_FLAGS)
|
||||
{
|
||||
RegServerCmd("nextmap", Command_Nextmap);
|
||||
}
|
||||
|
||||
// Hook events
|
||||
HookEvent("round_end", Event_RoundEnd); // We always require round_end
|
||||
if (g_Cvar_Fraglimit != INVALID_HANDLE)
|
||||
{
|
||||
HookEvent("player_death", Event_PlayerDeath);
|
||||
}
|
||||
|
||||
// Set to the current map so OnMapStart() will know what to do
|
||||
decl String:currentMap[64];
|
||||
GetCurrentMap(currentMap, 64);
|
||||
SetNextMap(currentMap);
|
||||
|
||||
// Create necessary menus for TopMenu
|
||||
g_Menu_Map = CreateMenu(MenuHandler_Map);
|
||||
SetMenuTitle(g_Menu_Map, "Please select a map");
|
||||
SetMenuExitBackButton(g_Menu_Map, true);
|
||||
|
||||
g_Menu_Votemap = CreateMenu(MenuHandler_VoteMap, MenuAction_DrawItem);
|
||||
SetMenuTitle(g_Menu_Votemap, "Please select a map");
|
||||
SetMenuExitBackButton(g_Menu_Votemap, true);
|
||||
|
||||
// Bind TopMenu commands to adminmenu_maplist.ini, in cases it doesn't exist in maplists.cfg
|
||||
decl String:mapListPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, mapListPath, sizeof(mapListPath), "configs/adminmenu_maplist.ini");
|
||||
SetMapListCompatBind("sm_map menu", mapListPath);
|
||||
SetMapListCompatBind("sm_votemap menu", mapListPath);
|
||||
|
||||
// Account for late loading
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
|
||||
AutoExecConfig(true, "mapmanager");
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
new TopMenuObject:server_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_SERVERCOMMANDS);
|
||||
|
||||
if (server_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_map",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Map,
|
||||
server_commands,
|
||||
"sm_map",
|
||||
ADMFLAG_CHANGEMAP);
|
||||
}
|
||||
|
||||
new TopMenuObject:voting_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_VOTINGCOMMANDS);
|
||||
|
||||
if (voting_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_votemap",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteMap,
|
||||
voting_commands,
|
||||
"sm_votemap",
|
||||
ADMFLAG_VOTE|ADMFLAG_CHANGEMAP);
|
||||
}
|
||||
}
|
||||
|
||||
public OnLibraryRemoved(const String:name[])
|
||||
{
|
||||
if (strcmp(name, "adminmenu") == 0)
|
||||
{
|
||||
hTopMenu = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
// Add map logic here
|
||||
|
||||
// Get the current and last maps.
|
||||
decl String:lastMap[64], String:currentMap[64];
|
||||
GetConVarString(g_Cvar_NextMap, lastMap, 64);
|
||||
GetCurrentMap(currentMap, 64);
|
||||
|
||||
// Why am I doing this? If we switched to a new map, but it wasn't what we expected (Due to sm_map, sm_votemap, or
|
||||
// some other plugin/command), we don't want to scramble the map cycle. Or for example, admin switches to a custom map
|
||||
// not in mapcyclefile. So we keep it set to the last expected nextmap. - ferret
|
||||
if (strcmp(lastMap, currentMap) == 0)
|
||||
{
|
||||
FindAndSetNextMap();
|
||||
}
|
||||
|
||||
// Build map menus for sm_map, sm_votemap, and RTV.
|
||||
/* TODO: Figure out wtf I'm supposed to do here */
|
||||
BuildMapMenu(g_Menu_Map);
|
||||
BuildMapMenu(g_Menu_Votemap);
|
||||
|
||||
|
||||
// If the Randomize option is on, randomize!
|
||||
if (GetConVarBool(g_Cvar_Randomize))
|
||||
{
|
||||
CreateTimer(5.0, Timer_RandomizeNextmap);
|
||||
}
|
||||
|
||||
// If MapChooser is active, start it up!
|
||||
if (GetConVarBool(g_Cvar_MapChooser))
|
||||
{
|
||||
SetupTimeleftTimer();
|
||||
SetConVarString(g_Cvar_NextMap, "Pending Vote");
|
||||
}
|
||||
|
||||
/*
|
||||
// If RockTheVote is active, start it up!
|
||||
if (GetConVarBool(g_Cvar_RockTheVote))
|
||||
{
|
||||
BuildMapMenu(g_Menu_RTV, list);
|
||||
CreateTimer(30.0, Timer_DelayRTV);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Reinitialize all our various globals
|
||||
public OnMapStart()
|
||||
{
|
||||
if (g_Menu_Nominate != INVALID_HANDLE)
|
||||
{
|
||||
ClearArray(g_Menu_Nominate);
|
||||
}
|
||||
|
||||
if (g_TeamScores != INVALID_HANDLE)
|
||||
{
|
||||
ClearArray(g_TeamScores);
|
||||
}
|
||||
|
||||
g_TotalRounds = 0;
|
||||
|
||||
g_RTV_Voters = 0;
|
||||
g_RTV_Votes = 0;
|
||||
g_RTV_VotesNeeded = 0;
|
||||
g_RTV_Started = false;
|
||||
g_RTV_Ended = false;
|
||||
}
|
||||
|
||||
// Reset globals as necessary and kill timers
|
||||
public OnMapEnd()
|
||||
{
|
||||
g_IntermissionCalled = false;
|
||||
g_HasVoteStarted = false;
|
||||
|
||||
g_RTV_Allowed = false;
|
||||
|
||||
if (g_VoteTimer != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(g_VoteTimer);
|
||||
g_VoteTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (g_RetryTimer != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(g_RetryTimer);
|
||||
g_RetryTimer = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
|
||||
{
|
||||
if (IsFakeClient(client))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If RTV is active, deal with vote counting.
|
||||
if (GetConVarBool(g_Cvar_RockTheVote))
|
||||
{
|
||||
g_RTV_Voted[client] = false;
|
||||
g_RTV_Voters++;
|
||||
g_RTV_VotesNeeded = RoundToFloor(float(g_RTV_Voters) * GetConVarFloat(g_Cvar_RTVLimit));
|
||||
}
|
||||
|
||||
// If Nominate is active, let the new client nominate
|
||||
if (GetConVarBool(g_Cvar_Nominate))
|
||||
{
|
||||
g_Nominated[client] = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public OnClientDisconnect(client)
|
||||
{
|
||||
if (IsFakeClient(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If RTV is active, deal with vote counting.
|
||||
if (GetConVarBool(g_Cvar_RockTheVote))
|
||||
{
|
||||
if(g_RTV_Voted[client])
|
||||
{
|
||||
g_RTV_Votes--;
|
||||
}
|
||||
|
||||
g_RTV_Voters--;
|
||||
g_RTV_VotesNeeded = RoundToFloor(float(g_RTV_Voters) * GetConVarFloat(g_Cvar_RTVLimit));
|
||||
|
||||
// If this client caused us to fall below the RTV threshold and its allowed be started, start it.
|
||||
if (g_RTV_Votes && g_RTV_Voters && g_RTV_Votes >= g_RTV_VotesNeeded && g_RTV_Allowed && !g_RTV_Started)
|
||||
{
|
||||
g_RTV_Started = true;
|
||||
CreateTimer(2.0, Timer_StartRTV, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapTimeLeftChanged()
|
||||
{
|
||||
if (GetConVarBool(g_Cvar_MapChooser))
|
||||
{
|
||||
SetupTimeleftTimer();
|
||||
}
|
||||
}
|
@ -1,398 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Manager Plugin
|
||||
* Contains callbacks for commands
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
{
|
||||
decl String:text[192];
|
||||
if (GetCmdArgString(text, sizeof(text)) < 1)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new startidx;
|
||||
if (text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
decl String:message[8];
|
||||
BreakString(text[startidx], message, sizeof(message));
|
||||
|
||||
if (strcmp(message, "nextmap", false) == 0)
|
||||
{
|
||||
decl String:map[32];
|
||||
GetConVarString(g_Cvar_Nextmap, map, sizeof(map));
|
||||
|
||||
PrintToChat(client, "%t", "Next Map", map);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetConVarBool(g_Cvar_RockTheVote) && (strcmp(text[startidx], "rtv", false) == 0 || strcmp(text[startidx], "rockthevote", false) == 0))
|
||||
{
|
||||
if (g_MapChanged)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map change in progress");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (!g_RTV_Allowed)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Not Allowed");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTV_Ended)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Ended");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTV_Started)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Started");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (GetClientCount(true) < GetConVarInt(g_Cvar_MinPlayers) && g_RTV_Votes == 0) // Should we keep checking g_Votes here?
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Minimal Players Not Met");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTV_Voted[client])
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Already Voted");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
g_RTV_Votes++;
|
||||
g_RTV_Voted[client] = true;
|
||||
|
||||
PrintToChatAll("[SM] %t", "RTV Requested", name, g_RTV_Votes, g_RTV_VotesNeeded);
|
||||
|
||||
if (g_RTV_Votes >= g_RTV_VotesNeeded)
|
||||
{
|
||||
g_RTV_Started = true;
|
||||
CreateTimer(2.0, Timer_StartRTV, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
else if (GetConVarBool(g_Cvar_Nominate) && strcmp(text[startidx], "nominate", false) == 0)
|
||||
{
|
||||
if (g_MapChanged)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map change in progress");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTV_Started || g_HasVoteStarted)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map vote in progress");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_Nominated[client])
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Already Nominated");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (GetArraySize(g_Nominate) >= GetConVarInt(g_Cvar_Maps))
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Max Nominations");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
DisplayMenu(g_Menu_Nominate, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action:Command_Mapvote(client, args)
|
||||
{
|
||||
InitiateVote();
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Nextmap(args)
|
||||
{
|
||||
decl String:map[64];
|
||||
|
||||
GetConVarString(g_Cvar_Nextmap, map, sizeof(map));
|
||||
|
||||
ReplyToCommand(0, "%t", "Next Map", map);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_List(client, args)
|
||||
{
|
||||
PrintToConsole(client, "Map Cycle:");
|
||||
|
||||
decl String:currentMap[64];
|
||||
GetCurrentMap(currentMap, 64);
|
||||
|
||||
decl String:mapName[64];
|
||||
for (new i = 0; i < GetArraySize(g_MapCycle); i++)
|
||||
{
|
||||
GetArrayString(g_MapCycle, i, mapName, sizeof(mapName));
|
||||
if (strcmp(mapName, currentMap) == 0)
|
||||
{
|
||||
PrintToConsole(client, "%s <========= Current map", mapName);
|
||||
}
|
||||
else if (strcmp(mapName, g_NextMap) == 0)
|
||||
{
|
||||
PrintToConsole(client, "%s <========= Next map", mapName);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToConsole(client, "%s", mapName);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SetNextmap(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_setnextmap <map>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (g_MapChanged)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map change in progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:map[64];
|
||||
GetCmdArg(1, map, sizeof(map));
|
||||
|
||||
if (!IsMapValid(map))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map was not found", map);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShowActivity(client, "%t", "Cvar changed", "sm_nextmap", map);
|
||||
LogMessage("\"%L\" changed sm_nextmap to \"%s\"", client, map);
|
||||
|
||||
SetNextMap(map);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Map(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_map <map> [r/e]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (g_MapChanged)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map change in progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:map[64];
|
||||
GetCmdArg(1, map, sizeof(map));
|
||||
|
||||
if (!IsMapValid(map))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map was not found", map);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:when[2];
|
||||
if (args > 1)
|
||||
{
|
||||
GetCmdArg(2, when, sizeof(when));
|
||||
|
||||
when[0] = CharToLower(when[0]);
|
||||
if (when[0] != 'r' && when[0] != 'e')
|
||||
{
|
||||
when[0] = 'i';
|
||||
}
|
||||
}
|
||||
|
||||
SetMapChange(client, map, when);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Votemap(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_votemap [r/e] <mapname> [mapname2] ... [mapname5]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (g_MapChanged)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map change in progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:maps[5][64];
|
||||
new mapCount;
|
||||
new len, pos;
|
||||
|
||||
// Find out if the user specified "when"
|
||||
decl String:when[64];
|
||||
pos = BreakString(text[len], when, sizeof(when));
|
||||
if (!IsMapValid(when))
|
||||
{
|
||||
when[0] = CharToLower(when[0]);
|
||||
if (when[0] != 'r' && when[0] != 'e')
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map was not found", maps[mapCount]);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(maps[mapCount], sizeof(maps[]), when);
|
||||
mapCount++;
|
||||
when[0] = 'i';
|
||||
}
|
||||
|
||||
len += pos;
|
||||
|
||||
while (pos != -1 && mapCount < 5)
|
||||
{
|
||||
pos = BreakString(text[len], maps[mapCount], sizeof(maps[]));
|
||||
|
||||
if (!IsMapValid(maps[mapCount]))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map was not found", maps[mapCount]);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
mapCount++;
|
||||
|
||||
len += pos;
|
||||
}
|
||||
|
||||
g_VoteMapInUse = client;
|
||||
g_Client_Data[client][0] = when[0];
|
||||
|
||||
DisplayVoteMapMenu(client, mapCount, maps);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Nominate(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_nominate <mapname>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!GetConVarBool(g_Cvar_Nominate))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Nominations are currently disabled.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:mapname[64];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
if (FindStringInArray(g_MapList, mapname) == -1)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (GetArraySize(g_Nominated) > 0)
|
||||
{
|
||||
if (FindStringInArray(g_Nominated, mapname) != -1)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map Already In Vote", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShiftArrayUp(g_Nominated, 0);
|
||||
SetArrayString(g_Nominated, 0, mapname);
|
||||
|
||||
while (GetArraySize(g_Nominated) > GetConVarInt(g_Cvar_Maps))
|
||||
{
|
||||
RemoveFromArray(g_Nominated, GetConVarInt(g_Cvar_Maps));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PushArrayString(g_Nominated, mapname);
|
||||
}
|
||||
|
||||
decl String:item[64];
|
||||
for (new i = 0; i < GetMenuItemCount(g_Menu_Nominate); i++)
|
||||
{
|
||||
GetMenuItem(g_Menu_Nominate, i, item, sizeof(item));
|
||||
if (strcmp(item, mapname) == 0)
|
||||
{
|
||||
RemoveMenuItem(g_Menu_Nominate, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReplyToCommand(client, "%t", "Map Inserted", mapname);
|
||||
LogAction(client, -1, "\"%L\" inserted map \"%s\".", client, mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Manager Plugin
|
||||
* Contains event callbacks
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
public Action:UserMsg_VGUIMenu(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init)
|
||||
{
|
||||
if (g_IntermissionCalled)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:type[15];
|
||||
|
||||
/* If we don't get a valid string, bail out. */
|
||||
if (BfReadString(bf, type, sizeof(type)) < 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (BfReadByte(bf) == 1 && BfReadByte(bf) == 0 && (strcmp(type, "scores", false) == 0))
|
||||
{
|
||||
g_IntermissionCalled = true;
|
||||
|
||||
decl String:map[32];
|
||||
new Float:fChatTime = GetConVarFloat(g_Cvar_Chattime);
|
||||
|
||||
if (fChatTime < 2.0)
|
||||
{
|
||||
SetConVarFloat(g_Cvar_Chattime, 2.0);
|
||||
}
|
||||
|
||||
LogMessage("[MapManager] Changing map to '%s' due to map ending.", g_NextMap);
|
||||
|
||||
g_MapChanged = true;
|
||||
CreateTimer(fChatTime - 1.0, Timer_ChangeMap);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
if (g_MapChanged)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_MapChangeSet && g_MapChangeWhen == 'r')
|
||||
{
|
||||
LogMessage("[MapManager] Changing map to '%s' due to round ending.", g_NextMap);
|
||||
|
||||
g_MapChanged = true;
|
||||
CreateTimer(1.0, Timer_ChangeMap);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_HasVoteStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new winner = GetEventInt(event, "winner");
|
||||
|
||||
if (winner == 0 || winner == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_TotalRounds++;
|
||||
|
||||
new team[2], teamPos = -1;
|
||||
for (new i; i < GetArraySize(g_TeamScores); i++)
|
||||
{
|
||||
GetArrayArray(g_TeamScores, i, team);
|
||||
if (team[0] == winner)
|
||||
{
|
||||
teamPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (teamPos == -1)
|
||||
{
|
||||
team[0] = winner;
|
||||
team[1] = 1;
|
||||
PushArrayArray(g_TeamScores, team);
|
||||
}
|
||||
else
|
||||
{
|
||||
team[1]++;
|
||||
SetArrayArray(g_TeamScores, teamPos, team);
|
||||
}
|
||||
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE)
|
||||
{
|
||||
new winlimit = GetConVarInt(g_Cvar_Winlimit);
|
||||
if (winlimit)
|
||||
{
|
||||
if (team[1] >= (winlimit - GetConVarInt(g_Cvar_StartRounds)))
|
||||
{
|
||||
InitiateVote();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Maxrounds != INVALID_HANDLE)
|
||||
{
|
||||
new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
|
||||
if (maxrounds)
|
||||
{
|
||||
if (g_TotalRounds >= (maxrounds - GetConVarInt(g_Cvar_StartRounds)))
|
||||
{
|
||||
InitiateVote();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
if (g_MapChanged || g_HasVoteStarted || g_Cvar_Fraglimit == INVALID_HANDLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetConVarInt(g_Cvar_Fraglimit))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new fragger = GetClientOfUserId(GetEventInt(event, "attacker"));
|
||||
if (fragger && GetClientFrags(fragger) >= (GetConVarInt(g_Cvar_Fraglimit) - GetConVarInt(g_Cvar_StartFrags)))
|
||||
{
|
||||
InitiateVote();
|
||||
}
|
||||
}
|
@ -1,335 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Management Plugin
|
||||
* Contains misc functions.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
SetNextMap(String:map[])
|
||||
{
|
||||
strcopy(g_NextMap, sizeof(g_NextMap), map);
|
||||
SetConVarString(g_Cvar_Nextmap, map);
|
||||
}
|
||||
|
||||
SetMapChange(client, map, when, Float:time = 3.0)
|
||||
{
|
||||
g_MapChangeSet = true;
|
||||
g_MapChangeWhen = when[0];
|
||||
SetNextMap(map);
|
||||
|
||||
if (when[0] == 'r')
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Changing map end of round", map);
|
||||
LogAction(client, -1, "\"%L\" set end of round map change to \"%s\"", client, map);
|
||||
}
|
||||
else if (when[0] == 'e')
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set nextmap", map);
|
||||
LogAction(client, -1, "\"%L\" set the next map to \"%s\"", client, map);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Change map", map);
|
||||
LogAction(client, -1, "\"%L\" changed map to \"%s\"", client, map);
|
||||
|
||||
g_MapChanged = true;
|
||||
CreateTimer(3.0, Timer_ChangeMap);
|
||||
}
|
||||
}
|
||||
|
||||
FindAndSetNextMap()
|
||||
{
|
||||
if (ReadMapList(g_MapList,
|
||||
g_MapListSerial,
|
||||
"mapcyclefile",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT)
|
||||
== INVALID_HANDLE)
|
||||
{
|
||||
if (g_MapListSerial == -1)
|
||||
{
|
||||
LogError("FATAL: Cannot load map cycle. Nextmap not loaded.");
|
||||
SetFailState("Mapcycle Not Found");
|
||||
}
|
||||
}
|
||||
|
||||
new mapCount = GetArraySize(g_MapList);
|
||||
decl String:mapName[32];
|
||||
|
||||
if (g_MapPos == -1)
|
||||
{
|
||||
decl String:current[64];
|
||||
GetCurrentMap(current, 64);
|
||||
|
||||
for (new i = 0; i < mapCount; i++)
|
||||
{
|
||||
GetArrayString(g_MapList, i, mapName, sizeof(mapName));
|
||||
if (strcmp(current, mapName, false) == 0)
|
||||
{
|
||||
g_MapPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_MapPos == -1)
|
||||
g_MapPos = 0;
|
||||
}
|
||||
|
||||
g_MapPos++;
|
||||
if (g_MapPos >= mapCount)
|
||||
g_MapPos = 0;
|
||||
|
||||
GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
|
||||
SetConVarString(g_Cvar_Nextmap, mapName);
|
||||
}
|
||||
|
||||
Float:GetVotePercent(votes, totalVotes)
|
||||
{
|
||||
return FloatDiv(float(votes),float(totalVotes));
|
||||
}
|
||||
|
||||
bool:TestVoteDelay(client)
|
||||
{
|
||||
new delay = CheckVoteDelay();
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
if (delay > 60)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Delay Minutes", delay % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Delay Seconds", delay);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BuildMapMenu()
|
||||
{
|
||||
if (g_MapMenu != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_MapMenu);
|
||||
g_MapMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
g_MapMenu = CreateMenu(Handler_MapSelectMenu);
|
||||
SetMenuTitle(g_MapMenu, "%t", "Nominate Title");
|
||||
|
||||
decl String:map[64];
|
||||
for (new i = 0; i < GetArraySize(g_MapList); i++)
|
||||
{
|
||||
GetArrayString(g_MapList, i, map, sizeof(map));
|
||||
AddMenuItem(g_MapMenu, map, map);
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_MapMenu, false);
|
||||
}
|
||||
|
||||
SetupTimeleftTimer()
|
||||
{
|
||||
new time;
|
||||
if (GetMapTimeLeft(time) && time > 0)
|
||||
{
|
||||
new startTime = GetConVarInt(g_Cvar_StartTime) * 60;
|
||||
if (time - startTime < 0)
|
||||
{
|
||||
InitiateVote();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_VoteTimer != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(g_VoteTimer);
|
||||
g_VoteTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
g_VoteTimer = CreateTimer(float(time - startTime), Timer_StartMapVote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InitiateVote()
|
||||
{
|
||||
if (g_HasVoteStarted || g_RetryTimer != INVALID_HANDLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
// Can't start a vote, try again in 5 seconds.
|
||||
g_RetryTimer = CreateTimer(5.0, Timer_StartMapVote);
|
||||
return;
|
||||
}
|
||||
|
||||
g_HasVoteStarted = true;
|
||||
g_VoteMenu = CreateMenu(Handler_MapVoteMenu, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_VoteMenu, "Vote Nextmap");
|
||||
|
||||
decl String:map[32];
|
||||
for (new i = 0; i < GetArraySize(g_NextMapList); i++)
|
||||
{
|
||||
GetArrayString(g_NextMapList, i, map, sizeof(map));
|
||||
AddMenuItem(g_VoteMenu, map, map);
|
||||
}
|
||||
|
||||
if (GetConVarBool(g_Cvar_Extend))
|
||||
{
|
||||
new bool:allowExtend, time;
|
||||
if (GetMapTimeLimit(time) && time > 0 && time < GetConVarInt(g_Cvar_ExtendTimeMax))
|
||||
{
|
||||
allowExtend = true;
|
||||
}
|
||||
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE && GetConVarInt(g_Cvar_Winlimit) < GetConVarInt(g_Cvar_ExtendRoundMax))
|
||||
{
|
||||
allowExtend = true;
|
||||
}
|
||||
|
||||
if (g_Cvar_Maxrounds != INVALID_HANDLE && GetConVarInt(g_Cvar_Maxrounds) < GetConVarInt(g_Cvar_ExtendRoundMax))
|
||||
{
|
||||
allowExtend = true;
|
||||
}
|
||||
|
||||
if (g_Cvar_Fraglimit != INVALID_HANDLE && GetConVarInt(g_Cvar_Fraglimit) < GetConVarInt(g_Cvar_ExtendFragMax))
|
||||
{
|
||||
allowExtend = true;
|
||||
}
|
||||
|
||||
if (allowExtend)
|
||||
{
|
||||
AddMenuItem(g_VoteMenu, VOTE_EXTEND, "Extend Map");
|
||||
}
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_VoteMenu, false);
|
||||
VoteMenuToAll(g_VoteMenu, 20);
|
||||
|
||||
LogMessage("Voting for next map has started.");
|
||||
PrintToChatAll("[SM] %t", "Nextmap Voting Started");
|
||||
}
|
||||
|
||||
SetNextMap(const String:map[])
|
||||
{
|
||||
SetConVarString(g_Cvar_Nextmap, map);
|
||||
PushArrayString(g_OldMapList, map);
|
||||
|
||||
if (GetArraySize(g_OldMapList) > GetConVarInt(g_Cvar_ExcludeMaps))
|
||||
{
|
||||
RemoveFromArray(g_OldMapList, 0);
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Nextmap Voting Finished", map);
|
||||
LogMessage("Voting for next map has finished. Nextmap: %s.", map);
|
||||
}
|
||||
|
||||
CreateNextVote()
|
||||
{
|
||||
if(g_NextMapList != INVALID_HANDLE)
|
||||
{
|
||||
ClearArray(g_NextMapList);
|
||||
}
|
||||
|
||||
decl String:map[32];
|
||||
new index, Handle:tempMaps = CloneArray(g_MapList);
|
||||
|
||||
GetCurrentMap(map, sizeof(map));
|
||||
index = FindStringInArray(tempMaps, map);
|
||||
if (index != -1)
|
||||
{
|
||||
RemoveFromArray(tempMaps, index);
|
||||
}
|
||||
|
||||
if (GetConVarInt(g_Cvar_ExcludeMaps) && GetArraySize(tempMaps) > GetConVarInt(g_Cvar_ExcludeMaps))
|
||||
{
|
||||
for (new i = 0; i < GetArraySize(g_OldMapList); i++)
|
||||
{
|
||||
GetArrayString(g_OldMapList, i, map, sizeof(map));
|
||||
index = FindStringInArray(tempMaps, map);
|
||||
if (index != -1)
|
||||
{
|
||||
RemoveFromArray(tempMaps, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new limit = (GetConVarInt(g_Cvar_IncludeMaps) < GetArraySize(tempMaps) ? GetConVarInt(g_Cvar_IncludeMaps) : GetArraySize(tempMaps));
|
||||
for (new i = 0; i < limit; i++)
|
||||
{
|
||||
new b = GetRandomInt(0, GetArraySize(tempMaps) - 1);
|
||||
GetArrayString(tempMaps, b, map, sizeof(map));
|
||||
PushArrayString(g_NextMapList, map);
|
||||
RemoveFromArray(tempMaps, b);
|
||||
}
|
||||
|
||||
CloseHandle(tempMaps);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
new Handle:g_map_array = INVALID_HANDLE;
|
||||
new g_map_serial = -1;
|
||||
|
||||
LoadMapList(Handle:menu)
|
||||
{
|
||||
new Handle:map_array;
|
||||
|
||||
if ((map_array = ReadMapList(g_map_array,
|
||||
g_map_serial,
|
||||
"sm_map menu",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT|MAPLIST_FLAG_MAPSFOLDER))
|
||||
!= INVALID_HANDLE)
|
||||
{
|
||||
g_map_array = map_array;
|
||||
}
|
||||
|
||||
if (g_map_array == INVALID_HANDLE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RemoveAllMenuItems(menu);
|
||||
|
||||
decl String:map_name[64];
|
||||
new map_count = GetArraySize(g_map_array);
|
||||
|
||||
for (new i = 0; i < map_count; i++)
|
||||
{
|
||||
GetArrayString(g_map_array, i, map_name, sizeof(map_name));
|
||||
AddMenuItem(menu, map_name, map_name);
|
||||
}
|
||||
|
||||
return map_count;
|
||||
}
|
||||
|
||||
*/
|
@ -1,115 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Management Plugin
|
||||
* Contains misc functions.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
DisplayWhenMenu(client, bool:vote = false)
|
||||
{
|
||||
new Handle:
|
||||
|
||||
if (!vote)
|
||||
{
|
||||
menu = CreateMenu(MenuHandler_ChangeMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu = CreateMenu(MenuHandler_VoteWhen);
|
||||
}
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Map Change When", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, "i", "Immediately");
|
||||
AddMenuItem(menu, "r", "Round End");
|
||||
AddMenuItem(menu, "e", "Map End");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayConfirmVoteMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Confirm);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Confirm Vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, "Confirm", "Start the Vote");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayAcceptVoteMenu(String:map[])
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Accept);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Accept Vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, map, "Accept Vote");
|
||||
|
||||
DisplayMenu(menu, g_VoteMapInUse, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayVoteMapMenu(client, mapCount, String:maps[5][])
|
||||
{
|
||||
LogAction(client, -1, "\"%L\" initiated a map vote.", client);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Map");
|
||||
|
||||
new Handle:menu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
|
||||
if (mapCount == 1)
|
||||
{
|
||||
//strcopy(g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]), maps[0]);
|
||||
|
||||
SetMenuTitle(menu, "Change Map To");
|
||||
AddMenuItem(menu, maps[0], "Yes");
|
||||
AddMenuItem(menu, VOTE_NO, "No");
|
||||
}
|
||||
else
|
||||
{
|
||||
//g_voteInfo[VOTE_NAME][0] = '\0';
|
||||
|
||||
SetMenuTitle(menu, "Map Vote");
|
||||
for (new i = 0; i < mapCount; i++)
|
||||
{
|
||||
AddMenuItem(menu, maps[i], maps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SetMenuExitButton(menu, false);
|
||||
VoteMenuToAll(menu, 20);
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Manager Plugin
|
||||
* Contains globals and defines
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#define VOTE_EXTEND "##extend##"
|
||||
#define VOTE_YES "###yes###"
|
||||
#define VOTE_NO "###no###"
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE; // TopMenu
|
||||
|
||||
new Handle:g_MapCycle = INVALID_HANDLE; // mapcyclefile maps
|
||||
new Handle:g_MapList = INVALID_HANDLE; // maplist.txt maps
|
||||
new Handle:g_MapHistory = INVALID_HANDLE; // History of maps played
|
||||
new Handle:g_NextVoteMaps = INVALID_HANDLE; // Array of maps for next RTV or MC vote
|
||||
new Handle:g_NominatedMaps = INVALID_HANDLE; // Array of maps that have been nominated
|
||||
|
||||
new Handle:g_Menu_Map = INVALID_HANDLE; // Menu of maps used by sm_map in admin menu
|
||||
new Handle:g_Menu_Votemap = INVALID_HANDLE; // Menu of maps used by sm_votemap in admin menu
|
||||
new Handle:g_Menu_Nominate = INVALID_HANDLE; // Menu of maps used by Nomination system
|
||||
|
||||
new Handle:g_SelectedMaps; // List of maps chosen so far by a user in sm_votemap admin menu
|
||||
new g_VoteMapInUse; // Client index of admin using sm_votemap
|
||||
new String:g_Client_Data[MAXCLIENTS+1][64]; // Used to hold bits of client data during sm_votemap
|
||||
|
||||
new bool:g_MapChangeSet; // True if a command or vote has set the map
|
||||
new bool:g_MapChanged; // True if a map change has been issued
|
||||
new g_MapChangeWhen; // Either 'i' for immediate, 'r' for round end, or 'e' for end of map.
|
||||
|
||||
new UserMsg:g_VGUIMenu; // VGUI usermsg id for nextmap
|
||||
new bool:g_NextMapEnabled = true // If set to false, all features requiring nextmap are disabled.
|
||||
new bool:g_IntermissionCalled; // Has the end of map intermission begun?
|
||||
new String:g_NextMap[64]; // All important! This is the next map!
|
||||
new g_MapPos = -1; // Position in mapcycle
|
||||
|
||||
new bool:g_RTV_Voted[MAXPLAYERS+1] = {false, ...}; // Whether or not a player has voted for RTV
|
||||
new bool:g_RTV_Allowed = false; // True if RTV is available to players. Used to delay rtv votes.
|
||||
new bool:g_RTV_Started = false; // Indicates that the actual map vote has started
|
||||
new bool:g_RTV_Ended = false; // Indicates that the actual map vote has concluded
|
||||
new g_RTV_Voters = 0; // Total voters connected. Doesn't include fake clients.
|
||||
new g_RTV_Votes = 0; // Total number of "say rtv" votes
|
||||
new g_RTV_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed)
|
||||
|
||||
new bool:g_Nominated[MAXPLAYERS+1] = {false, ...}; // Whether or not a player has nominated a map
|
||||
|
||||
new Handle:g_TeamScores = INVALID_HANDLE; // Array of team scores
|
||||
new g_TotalRounds; // Total rounds played this map
|
||||
new bool:g_HasVoteStarted; // Whether or not MapChooser has begun
|
||||
|
||||
// ConVar handles
|
||||
new Handle:g_Cvar_NextMap = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_VoteMap = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Excludes = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_StartTime = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_StartRounds = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_StartFrags = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExtendTimeMax = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExtendTimeStep = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExtendRoundMax = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExtendRoundStep = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExtendFragMax = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExtendFragStep = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Mapfile = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExcludeMaps = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_IncludeMaps = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_NoVoteMode = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Extend = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_VoteTimer = INVALID_HANDLE;
|
||||
new Handle:g_RetryTimer = INVALID_HANDLE;
|
||||
|
||||
// VALVe ConVars
|
||||
new Handle:g_Cvar_Chattime = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Winlimit = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Maxrounds = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Fraglimit = INVALID_HANDLE;
|
@ -1,263 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Manager Plugin
|
||||
* Contains menu callbacks
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
// Following callbacks are for sm_map
|
||||
public AdminMenu_Map(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Choose Map", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayMenu(g_Menu_Map, param, MENU_TIME_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Map(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
GetMenuItem(menu, param2, g_Client_Data[param1], sizeof(g_Client_Data[]));
|
||||
DisplayWhenMenu(param1);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_ChangeMap(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:when[2];
|
||||
GetMenuItem(menu, param2, when, sizeof(when));
|
||||
SetMapChange(client, g_Client_Data[param1], when[0])
|
||||
}
|
||||
}
|
||||
|
||||
// Following callbacks are for sm_votemap
|
||||
public AdminMenu_VoteMap(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Map vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
g_VoteMapInUse = param;
|
||||
ClearArray(g_SelectedMaps);
|
||||
DisplayMenu(g_Menu_Votemap, param, MENU_TIME_FOREVER);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running, theres no maps listed or someone else has already accessed this menu */
|
||||
buffer[0] = (!IsNewVoteAllowed() || g_VoteMapInUse) ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_VoteMap(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayWhenMenu(param1, true);
|
||||
}
|
||||
else // no action was selected.
|
||||
{
|
||||
/* Re-enable the menu option */
|
||||
g_VoteMapInUse = 0;
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_DrawItem)
|
||||
{
|
||||
decl String:info[32];
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
|
||||
if (FindStringInArray(g_SelectedMaps, info) != -1)
|
||||
{
|
||||
return ITEMDRAW_IGNORE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
|
||||
PushArrayString(g_SelectedMaps, info);
|
||||
|
||||
/* Redisplay the list */
|
||||
if (GetArraySize(g_SelectedMaps) < 5)
|
||||
{
|
||||
DisplayMenu(g_MapList, param1, MENU_TIME_FOREVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayWhenMenu(param1, true);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public MenuHandler_VoteWhen(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
g_Menu_Info[param1][0] = 'i';
|
||||
DisplayConfirmVoteMenu(param1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_VoteMapInUse = 0;
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
GetMenuItem(menu, param2, g_Menu_Info[param1], sizeof(g_Menu_Info[]));
|
||||
|
||||
DisplayConfirmVoteMenu(param1);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Confirm(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
g_VoteMapInUse = 0;
|
||||
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:maps[5][64];
|
||||
new selectedmaps = GetArraySize(g_SelectedMaps);
|
||||
|
||||
for (new i = 0; i < selectedmaps; i++)
|
||||
{
|
||||
GetArrayString(g_SelectedMaps, i, maps[i], sizeof(maps[]));
|
||||
}
|
||||
|
||||
DisplayVoteMapMenu(param1, selectedmaps, maps);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Accept(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
g_VoteMapInUse = 0;
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:map[64]
|
||||
GetMenuItem(menu, 1, map, sizeof(map));
|
||||
|
||||
SetMapChange(param1, map, g_Client_Data[param1][0])
|
||||
}
|
||||
}
|
||||
|
||||
public Handler_MapSelectMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_Select:
|
||||
{
|
||||
if (GetArraySize(g_RTVMapList) >= GetConVarInt(g_Cvar_Maps))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Max Nominations");
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:map[64], String:name[64];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
if (FindStringInArray(g_RTVMapList, map) != -1)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Map Already Nominated");
|
||||
return;
|
||||
}
|
||||
|
||||
GetClientName(param1, name, 64);
|
||||
|
||||
PushArrayString(g_RTVMapList, map);
|
||||
RemoveMenuItem(menu, param2);
|
||||
|
||||
g_Nominated[param1] = true;
|
||||
|
||||
PrintToChatAll("[SM] %t", "Map Nominated", name, map);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Manager Plugin
|
||||
* Contains timer callbacks
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
public Action:Timer_ChangeMap(Handle:timer)
|
||||
{
|
||||
ServerCommand("changelevel \"%s\"", g_NextMap);
|
||||
PushArrayString(g_MapHistory, g_NextMap);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
public Action:Timer_RandomizeNextmap(Handle:timer)
|
||||
{
|
||||
decl String:map[64];
|
||||
|
||||
new exclusion = GetConVarInt(g_Cvar_ExcludeMaps);
|
||||
if (exclusion > GetArraySize(g_MapCycle))
|
||||
{
|
||||
exclusion = GetArraySize(g_MapCycle) - 1;
|
||||
}
|
||||
|
||||
new b = GetRandomInt(0, GetArraySize(g_MapCycle) - 1);
|
||||
GetArrayString(g_MapCycle, b, map, sizeof(map));
|
||||
|
||||
while (FindStringInArray(g_MapHistory, map) != -1)
|
||||
{
|
||||
b = GetRandomInt(0, GetArraySize(g_MapCycle) - 1);
|
||||
GetArrayString(g_MapCycle, b, map, sizeof(map));
|
||||
}
|
||||
|
||||
SetNextmap(map);
|
||||
|
||||
LogMessage("[MapManager] Randomizer has chosen '%s' as the next map.", map);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
public Action:Timer_DelayRTV(Handle:timer)
|
||||
{
|
||||
g_RTVAllowed = true;
|
||||
g_RTVStarted = false;
|
||||
g_RTVEnded = false;
|
||||
}
|
||||
|
||||
public Action:Timer_StartRTV(Handle:timer)
|
||||
{
|
||||
if (timer == g_RetryTimer)
|
||||
{
|
||||
g_RetryTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (g_RetryTimer != INVALID_HANDLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
// Can't start a vote, try again in 5 seconds.
|
||||
g_RetryTimer = CreateTimer(5.0, Timer_StartRTV, TIMER_FLAG_NO_MAPCHANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "RTV Vote Ready");
|
||||
|
||||
new Handle:MapVoteMenu = CreateMenu(Handler_MapMapVoteMenu, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(MapVoteMenu, "Rock The Vote");
|
||||
|
||||
new Handle:tempMaps = CloneArray(g_MapList);
|
||||
decl String:map[32];
|
||||
|
||||
GetCurrentMap(map, sizeof(map));
|
||||
new index = FindStringInArray(tempMaps, map);
|
||||
if (index != -1)
|
||||
{
|
||||
RemoveFromArray(tempMaps, index);
|
||||
}
|
||||
|
||||
// We assume that g_RTVMapList is within the correct limits, based on the logic for nominations
|
||||
for (new i = 0; i < GetArraySize(g_RTVMapList); i++)
|
||||
{
|
||||
GetArrayString(g_RTVMapList, i, map, sizeof(map));
|
||||
AddMenuItem(MapVoteMenu, map, map);
|
||||
|
||||
index = FindStringInArray(tempMaps, map);
|
||||
if (index != -1)
|
||||
{
|
||||
RemoveFromArray(tempMaps, index);
|
||||
}
|
||||
}
|
||||
|
||||
new limit = GetConVarInt(g_Cvar_Maps) - GetArraySize(g_RTVMapList);
|
||||
if (limit > GetArraySize(tempMaps))
|
||||
{
|
||||
limit = GetArraySize(tempMaps);
|
||||
}
|
||||
|
||||
for (new i = 0; i < limit; i++)
|
||||
{
|
||||
new b = GetRandomInt(0, GetArraySize(tempMaps) - 1);
|
||||
GetArrayString(tempMaps, b, map, sizeof(map));
|
||||
PushArrayString(g_RTVMapList, map);
|
||||
AddMenuItem(MapVoteMenu, map, map);
|
||||
RemoveFromArray(tempMaps, b);
|
||||
}
|
||||
|
||||
CloseHandle(tempMaps);
|
||||
|
||||
AddMenuItem(MapVoteMenu, "Don't Change", "Don't Change");
|
||||
|
||||
SetMenuExitButton(MapVoteMenu, false);
|
||||
VoteMenuToAll(MapVoteMenu, 20);
|
||||
|
||||
LogMessage("[SM] Rockthevote was successfully started.");
|
||||
}
|
||||
|
||||
public Action:Timer_StartMapVote(Handle:timer)
|
||||
{
|
||||
if (!GetArraySize(g_MapList))
|
||||
{
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
if (timer == g_RetryTimer)
|
||||
{
|
||||
g_RetryTimer = INVALID_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_VoteTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
InitiateVote();
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Manager Plugin
|
||||
* Contains vote callbacks
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
// sm_votemap
|
||||
public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Display)
|
||||
{
|
||||
decl String:title[64];
|
||||
GetMenuTitle(menu, title, sizeof(title));
|
||||
|
||||
decl String:map[64];
|
||||
GetMenuItem(menu, 1, map, sizeof(map));
|
||||
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", title, param1, map);
|
||||
|
||||
new Handle:panel = Handle:param2;
|
||||
SetPanelTitle(panel, buffer);
|
||||
}
|
||||
else if (action == MenuAction_DisplayItem)
|
||||
{
|
||||
decl String:display[64];
|
||||
GetMenuItem(menu, param2, "", 0, _, display, sizeof(display));
|
||||
|
||||
if (strcmp(display, "No") == 0 || strcmp(display, "Yes") == 0)
|
||||
{
|
||||
decl String: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)
|
||||
{
|
||||
decl String:item[64], String:display[64];
|
||||
new Float:percent, Float:limit, votes, totalVotes;
|
||||
|
||||
GetMenuVoteInfo(param2, votes, totalVotes);
|
||||
GetMenuItem(menu, param1, item, sizeof(item), _, display, sizeof(display));
|
||||
|
||||
if (strcmp(item, VOTE_NO) == 0 && param1 == 1)
|
||||
{
|
||||
votes = totalVotes - votes; // Reverse the votes to be in relation to the Yes option.
|
||||
}
|
||||
|
||||
percent = GetVotePercent(votes, totalVotes);
|
||||
|
||||
limit = GetConVarFloat(g_Cvar_VoteMap);
|
||||
|
||||
// A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
|
||||
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
|
||||
{
|
||||
LogAction(-1, -1, "Vote failed.");
|
||||
PrintToChatAll("[SM] %t", "Votemap Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Votemap Successful", RoundToNearest(100.0*percent), totalVotes);
|
||||
|
||||
if (g_VoteMapInUse && IsClientInGame(g_VoteMapInUse))
|
||||
{
|
||||
DisplayAcceptVoteMenu(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAction(-1, -1, "Changing map to %s due to vote.", item);
|
||||
PrintToChatAll("[SM] %t", "Changing map", item);
|
||||
SetMapChange(0, item, g_Client_Data[g_VoteMapInUse][0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Handler_MapMapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_End:
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
|
||||
case MenuAction_Display:
|
||||
{
|
||||
decl String:oldTitle[255], String:buffer[255];
|
||||
GetMenuTitle(menu, oldTitle, sizeof(oldTitle));
|
||||
Format(buffer, sizeof(buffer), "%T", oldTitle, param1);
|
||||
|
||||
new Handle:panel = Handle:param2;
|
||||
SetPanelTitle(panel, buffer);
|
||||
}
|
||||
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
if (GetMenuItemCount(menu) - 1 == param2)
|
||||
{
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", "Don't Change", param1);
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Why am I commented out? Because BAIL hasn't decided yet if
|
||||
// vote notification will be built into the Vote API.
|
||||
/*case MenuAction_Select:
|
||||
{
|
||||
decl String:Name[32], String:Map[32];
|
||||
GetClientName(param1, Name, sizeof(Name));
|
||||
GetMenuItem(menu, param2, Map, sizeof(Map));
|
||||
|
||||
PrintToChatAll("[SM] %s has voted for map '%s'", Name, Map);
|
||||
}*/
|
||||
|
||||
case MenuAction_VoteCancel:
|
||||
{
|
||||
if (param1 == VoteCancel_NoVotes)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "No Votes");
|
||||
g_RTVEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
case MenuAction_VoteEnd:
|
||||
{
|
||||
new String:map[64];
|
||||
|
||||
GetMenuItem(menu, param1, map, sizeof(map));
|
||||
|
||||
if (GetMenuItemCount(menu) - 1 == param1) // This should always match the "Keep Current" option
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Current Map Stays");
|
||||
LogMessage("[SM] Rockthevote has ended, current map kept.");
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Changing Maps", map);
|
||||
LogMessage("[SM] Rockthevote has ended, changing to map %s.", map);
|
||||
new Handle:dp;
|
||||
CreateDataTimer(5.0, Timer_ChangeMap, dp);
|
||||
WritePackString(dp, map);
|
||||
}
|
||||
|
||||
g_RTVEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_End:
|
||||
{
|
||||
g_VoteMenu = INVALID_HANDLE;
|
||||
CloseHandle(menu);
|
||||
}
|
||||
|
||||
case MenuAction_Display:
|
||||
{
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", "Vote Nextmap", param1);
|
||||
|
||||
new Handle:panel = Handle:param2;
|
||||
SetPanelTitle(panel, buffer);
|
||||
}
|
||||
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
if (GetMenuItemCount(menu) - 1 == param2)
|
||||
{
|
||||
decl String:map[64], String:buffer[255];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
if (strcmp(map, VOTE_EXTEND, false) == 0)
|
||||
{
|
||||
Format(buffer, sizeof(buffer), "%T", "Extend Map", param1);
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Why am I commented out? Because BAIL hasn't decided yet if
|
||||
// vote notification will be built into the Vote API.
|
||||
/*case MenuAction_Select:
|
||||
{
|
||||
decl String:Name[32], String:Map[32];
|
||||
GetClientName(param1, Name, sizeof(Name));
|
||||
GetMenuItem(menu, param2, Map, sizeof(Map));
|
||||
|
||||
PrintToChatAll("[SM] %s has voted for map '%s'", Name, Map);
|
||||
}*/
|
||||
|
||||
case MenuAction_VoteCancel:
|
||||
{
|
||||
// If we receive 0 votes, pick at random.
|
||||
if (param1 == VoteCancel_NoVotes && GetConVarBool(g_Cvar_NoVoteMode))
|
||||
{
|
||||
new count = GetMenuItemCount(menu);
|
||||
new item = GetRandomInt(0, count - 1);
|
||||
decl String:map[32];
|
||||
GetMenuItem(menu, item, map, sizeof(map));
|
||||
|
||||
while (strcmp(map, VOTE_EXTEND, false) == 0)
|
||||
{
|
||||
item = GetRandomInt(0, count - 1);
|
||||
GetMenuItem(menu, item, map, sizeof(map));
|
||||
}
|
||||
|
||||
SetNextMap(map);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We were actually cancelled. What should we do?
|
||||
}
|
||||
}
|
||||
|
||||
case MenuAction_VoteEnd:
|
||||
{
|
||||
decl String:map[32];
|
||||
GetMenuItem(menu, param1, map, sizeof(map));
|
||||
|
||||
if (strcmp(map, VOTE_EXTEND, false) == 0)
|
||||
{
|
||||
new time;
|
||||
if (GetMapTimeLimit(time))
|
||||
{
|
||||
if (time > 0 && time < GetConVarInt(g_Cvar_ExtendTimeMax))
|
||||
{
|
||||
ExtendMapTimeLimit(GetConVarInt(g_Cvar_ExtendTimeStep)*60);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Winlimit != INVALID_HANDLE)
|
||||
{
|
||||
new winlimit = GetConVarInt(g_Cvar_Winlimit);
|
||||
if (winlimit && winlimit < GetConVarInt(g_Cvar_ExtendRoundMax))
|
||||
{
|
||||
SetConVarInt(g_Cvar_Winlimit, winlimit + GetConVarInt(g_Cvar_ExtendRoundStep));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Maxrounds != INVALID_HANDLE)
|
||||
{
|
||||
new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
|
||||
if (maxrounds && maxrounds < GetConVarInt(g_Cvar_ExtendRoundMax))
|
||||
{
|
||||
SetConVarInt(g_Cvar_Maxrounds, maxrounds + GetConVarInt(g_Cvar_ExtendRoundStep));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_Fraglimit != INVALID_HANDLE)
|
||||
{
|
||||
new fraglimit = GetConVarInt(g_Cvar_Fraglimit);
|
||||
if (fraglimit && fraglimit < GetConVarInt(g_Cvar_ExtendFragMax))
|
||||
{
|
||||
SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep));
|
||||
}
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Current Map Extended");
|
||||
LogMessage("Voting for next map has finished. The current map has been extended.");
|
||||
|
||||
// We extended, so we'll have to vote again.
|
||||
g_HasVoteStarted = false;
|
||||
CreateNextVote();
|
||||
SetupTimeleftTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextMap(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
327
plugins/nominations.sp
Normal file
327
plugins/nominations.sp
Normal file
@ -0,0 +1,327 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Rock The Vote Plugin
|
||||
* Creates a map vote when the required number of players have requested one.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* "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
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <sourcemod>
|
||||
#include <mapchooser>
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Map Nominations",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Provides Map Nominations",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new Handle:g_Cvar_ExcludeOld = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExcludeCurrent = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_MapList = INVALID_HANDLE;
|
||||
new Handle:g_MapMenu = INVALID_HANDLE;
|
||||
new g_mapFileSerial = -1;
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("nominations.phrases");
|
||||
|
||||
new arraySize = ByteCountToCells(33);
|
||||
g_MapList = CreateArray(arraySize);
|
||||
|
||||
g_Cvar_ExcludeOld = CreateConVar("sm_nominate_excludeold", "1", "Specifies if the current map should be excluded from the Nominations list", 0, true, 0.00, true, 1.0);
|
||||
g_Cvar_ExcludeCurrent = CreateConVar("sm_nominate_excludecurrent", "1", "Specifies if the MapChooser excluded maps should also be excluded from Nominations", 0, true, 0.00, true, 1.0);
|
||||
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
RegConsoleCmd("sm_nominate", Command_Nominate);
|
||||
|
||||
RegAdminCmd("sm_nominate_addmap", Command_Addmap, ADMFLAG_CHANGEMAP, "sm_nominate_addmap <mapname> - Forces a map to be on the next mapvote.");
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
if (ReadMapList(g_MapList,
|
||||
g_mapFileSerial,
|
||||
"nominations",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_MAPSFOLDER)
|
||||
== INVALID_HANDLE)
|
||||
{
|
||||
if (g_mapFileSerial == -1)
|
||||
{
|
||||
SetFailState("Unable to create a valid map list.");
|
||||
}
|
||||
}
|
||||
|
||||
BuildMapMenu();
|
||||
}
|
||||
|
||||
public OnNominationRemoved(String:map[], owner)
|
||||
{
|
||||
AddMenuItem(g_MapMenu, map, map);
|
||||
}
|
||||
|
||||
public Action:Command_Addmap(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_nominate_addmap <mapname>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:mapname[64];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
if (FindStringInArray(g_MapList, mapname) == -1)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new NominateResult:result = NominateMap(mapname, true, 0);
|
||||
|
||||
if (result > Nominate_Replaced)
|
||||
{
|
||||
/* We assume already in vote is the casue because the maplist does a Map Validity check and we forced, so it can't be full */
|
||||
ReplyToCommand(client, "%t", "Map Already In Vote", mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:item[64];
|
||||
for (new i = 0; i < GetMenuItemCount(g_MapMenu); i++)
|
||||
{
|
||||
GetMenuItem(g_MapMenu, i, item, sizeof(item));
|
||||
if (strcmp(item, mapname) == 0)
|
||||
{
|
||||
RemoveMenuItem(g_MapMenu, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReplyToCommand(client, "%t", "Map Inserted", mapname);
|
||||
LogAction(client, -1, "\"%L\" inserted map \"%s\".", client, mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
{
|
||||
if (!client)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
if (!GetCmdArgString(text, sizeof(text)))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new startidx = 0;
|
||||
if(text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT);
|
||||
|
||||
if (strcmp(text[startidx], "nominate", false) == 0)
|
||||
{
|
||||
AttemptNominate(client);
|
||||
}
|
||||
|
||||
SetCmdReplySource(old);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action:Command_Nominate(client, args)
|
||||
{
|
||||
if (!client)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (args == 0)
|
||||
{
|
||||
AttemptNominate(client);
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
decl String:mapname[64];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
if (FindStringInArray(g_MapList, mapname) == -1)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new NominateResult:result = NominateMap(mapname, false, client);
|
||||
|
||||
if (result > Nominate_Replaced)
|
||||
{
|
||||
if (result == Nominate_AlreadyInVote)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map Already In Vote", mapname);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map Already Nominated");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:item[64];
|
||||
for (new i = 0; i < GetMenuItemCount(g_MapMenu); i++)
|
||||
{
|
||||
GetMenuItem(g_MapMenu, i, item, sizeof(item));
|
||||
if (strcmp(item, mapname) == 0)
|
||||
{
|
||||
RemoveMenuItem(g_MapMenu, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
PrintToChatAll("[SM] %t", "Map Nominated", name, mapname);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
AttemptNominate(client)
|
||||
{
|
||||
SetMenuTitle(g_MapMenu, "%t", "Nominate Title", client);
|
||||
DisplayMenu(g_MapMenu, client, MENU_TIME_FOREVER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BuildMapMenu()
|
||||
{
|
||||
if (g_MapMenu != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_MapMenu);
|
||||
g_MapMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
g_MapMenu = CreateMenu(Handler_MapSelectMenu);
|
||||
|
||||
decl String:map[64];
|
||||
|
||||
new Handle:excludeMaps;
|
||||
decl String:currentMap[32];
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeOld))
|
||||
{
|
||||
excludeMaps = CreateArray(ByteCountToCells(33));
|
||||
GetExcludeMapList(excludeMaps);
|
||||
}
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeCurrent))
|
||||
{
|
||||
GetCurrentMap(currentMap, sizeof(currentMap));
|
||||
}
|
||||
|
||||
for (new i = 0; i < GetArraySize(g_MapList); i++)
|
||||
{
|
||||
GetArrayString(g_MapList, i, map, sizeof(map));
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeOld))
|
||||
{
|
||||
if (FindStringInArray(excludeMaps, map) != -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeCurrent))
|
||||
{
|
||||
if (StrEqual(map, currentMap))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
AddMenuItem(g_MapMenu, map, map);
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_MapMenu, true);
|
||||
}
|
||||
|
||||
public Handler_MapSelectMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_Select:
|
||||
{
|
||||
decl String:map[64], String:name[64];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
|
||||
GetClientName(param1, name, 64);
|
||||
|
||||
|
||||
new NominateResult:result = NominateMap(map, false, param1);
|
||||
|
||||
/* Don't need to check for InvalidMap because the menu did that already */
|
||||
if (result == Nominate_AlreadyInVote)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Map Already Nominated");
|
||||
return;
|
||||
}
|
||||
else if (result == Nominate_VoteFull)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Max Nominations");
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveMenuItem(menu, param2);
|
||||
|
||||
if (result == Nominate_Replaced)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Map Nomination Changed", name, map);
|
||||
return;
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Map Nominated", name, map);
|
||||
}
|
||||
}
|
||||
}
|
@ -150,7 +150,7 @@ public OnClientPostAdminCheck(client)
|
||||
else if (type == 1)
|
||||
{
|
||||
if (clients > limit)
|
||||
{
|
||||
{
|
||||
if (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
|
||||
{
|
||||
new target = SelectKickClient();
|
||||
|
@ -32,6 +32,8 @@
|
||||
*/
|
||||
|
||||
#include <sourcemod>
|
||||
#include <mapchooser>
|
||||
#include <nextmap>
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
@ -45,44 +47,37 @@ public Plugin:myinfo =
|
||||
};
|
||||
|
||||
new Handle:g_Cvar_Needed = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Maps = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Nominate = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_MinPlayers = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_MapList = INVALID_HANDLE;
|
||||
new Handle:g_RTVMapList = INVALID_HANDLE;
|
||||
new Handle:g_MapMenu = INVALID_HANDLE;
|
||||
new Handle:g_RetryTimer = INVALID_HANDLE;
|
||||
new g_mapFileSerial = -1;
|
||||
new Handle:g_Cvar_InitialDelay = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Interval = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ChangeTime = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_RTVPostVoteAction = INVALID_HANDLE;
|
||||
|
||||
new bool:g_CanRTV = false; // True if RTV loaded maps and is active.
|
||||
new bool:g_RTVAllowed = false; // True if RTV is available to players. Used to delay rtv votes.
|
||||
new bool:g_RTVStarted = false; // Indicates that the actual map vote has started
|
||||
new bool:g_RTVEnded = false; // Indicates that the actual map vote has concluded
|
||||
new g_Voters = 0; // Total voters connected. Doesn't include fake clients.
|
||||
new g_Votes = 0; // Total number of "say rtv" votes
|
||||
new g_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed)
|
||||
new bool:g_Voted[MAXPLAYERS+1] = {false, ...};
|
||||
new bool:g_Nominated[MAXPLAYERS+1] = {false, ...};
|
||||
|
||||
new bool:g_InChange = false;
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("rockthevote.phrases");
|
||||
|
||||
new arraySize = ByteCountToCells(33);
|
||||
g_MapList = CreateArray(arraySize);
|
||||
g_RTVMapList = CreateArray(arraySize);
|
||||
|
||||
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_Maps = CreateConVar("sm_rtv_maps", "4", "Number of maps to be voted on. 2 to 6. (Def 4)", 0, true, 2.0, true, 6.0);
|
||||
g_Cvar_Nominate = CreateConVar("sm_rtv_nominate", "1", "Enables nomination system.", 0, true, 0.0, 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_InitialDelay = CreateConVar("sm_rtv_initialdelay", "30.0", "Time before first RTV can be held", 0, true, 0.00);
|
||||
g_Cvar_Interval = CreateConVar("sm_rtv_interval", "240.0", "Time 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_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);
|
||||
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
RegAdminCmd("sm_rtv_addmap", Command_Addmap, ADMFLAG_CHANGEMAP, "sm_rtv_addmap <mapname> - Forces a map to be on the RTV, and lowers the allowed nominations.");
|
||||
RegConsoleCmd("sm_rtv", Command_RTV);
|
||||
|
||||
AutoExecConfig(true, "rtv");
|
||||
}
|
||||
@ -92,8 +87,17 @@ public OnMapStart()
|
||||
g_Voters = 0;
|
||||
g_Votes = 0;
|
||||
g_VotesNeeded = 0;
|
||||
g_RTVStarted = false;
|
||||
g_RTVEnded = false;
|
||||
g_InChange = false;
|
||||
|
||||
/* Handle late load */
|
||||
new maxclients = GetMaxClients();
|
||||
for (new i=1; i<=maxclients; i++)
|
||||
{
|
||||
if (IsClientConnected(i))
|
||||
{
|
||||
OnClientConnect(i, "", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapEnd()
|
||||
@ -103,36 +107,18 @@ public OnMapEnd()
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
if (g_RTVMapList != INVALID_HANDLE)
|
||||
{
|
||||
ClearArray(g_RTVMapList);
|
||||
}
|
||||
|
||||
if (ReadMapList(g_MapList,
|
||||
g_mapFileSerial,
|
||||
"rockthevote",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_MAPSFOLDER)
|
||||
== INVALID_HANDLE)
|
||||
{
|
||||
if (g_mapFileSerial == -1)
|
||||
{
|
||||
LogError("Unable to create a valid map list.");
|
||||
}
|
||||
}
|
||||
|
||||
BuildMapMenu();
|
||||
{
|
||||
g_CanRTV = true;
|
||||
CreateTimer(30.0, Timer_DelayRTV);
|
||||
g_RTVAllowed = false;
|
||||
CreateTimer(GetConVarFloat(g_Cvar_InitialDelay), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
|
||||
public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
|
||||
{
|
||||
if(!g_CanRTV || IsFakeClient(client))
|
||||
if(IsFakeClient(client))
|
||||
return true;
|
||||
|
||||
g_Voted[client] = false;
|
||||
g_Nominated[client] = false;
|
||||
|
||||
g_Voters++;
|
||||
g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
|
||||
@ -154,72 +140,30 @@ public OnClientDisconnect(client)
|
||||
|
||||
g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
|
||||
|
||||
if (g_Votes && g_Voters && g_Votes >= g_VotesNeeded && g_RTVAllowed && !g_RTVStarted)
|
||||
if (g_Votes &&
|
||||
g_Voters &&
|
||||
g_Votes >= g_VotesNeeded &&
|
||||
g_RTVAllowed )
|
||||
{
|
||||
g_RTVStarted = true;
|
||||
CreateTimer(2.0, Timer_StartRTV, TIMER_FLAG_NO_MAPCHANGE);
|
||||
if (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartRTV();
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Addmap(client, args)
|
||||
public Action:Command_RTV(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
if (!g_CanRTV || !client)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_rtv_addmap <mapname>");
|
||||
return Plugin_Handled;
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (!g_CanRTV)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] RockTheVote is not available.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
AttemptRTV(client);
|
||||
|
||||
decl String:mapname[64];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
if (FindStringInArray(g_MapList, mapname) == -1)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (GetArraySize(g_RTVMapList) > 0)
|
||||
{
|
||||
if (FindStringInArray(g_RTVMapList, mapname) != -1)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map Already In Vote", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShiftArrayUp(g_RTVMapList, 0);
|
||||
SetArrayString(g_RTVMapList, 0, mapname);
|
||||
|
||||
while (GetArraySize(g_RTVMapList) > GetConVarInt(g_Cvar_Maps))
|
||||
{
|
||||
RemoveFromArray(g_RTVMapList, GetConVarInt(g_Cvar_Maps));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PushArrayString(g_RTVMapList, mapname);
|
||||
}
|
||||
|
||||
decl String:item[64];
|
||||
for (new i = 0; i < GetMenuItemCount(g_MapMenu); i++)
|
||||
{
|
||||
GetMenuItem(g_MapMenu, i, item, sizeof(item));
|
||||
if (strcmp(item, mapname) == 0)
|
||||
{
|
||||
RemoveMenuItem(g_MapMenu, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReplyToCommand(client, "%t", "Map Inserted", mapname);
|
||||
LogAction(client, -1, "\"%L\" inserted map \"%s\".", client, mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
@ -228,7 +172,7 @@ public Action:Command_Say(client, args)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
|
||||
decl String:text[192];
|
||||
if (!GetCmdArgString(text, sizeof(text)))
|
||||
{
|
||||
@ -242,301 +186,120 @@ public Action:Command_Say(client, args)
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT);
|
||||
|
||||
if (strcmp(text[startidx], "rtv", false) == 0 || strcmp(text[startidx], "rockthevote", false) == 0)
|
||||
{
|
||||
if (!g_RTVAllowed)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Not Allowed");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTVEnded)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Ended");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTVStarted)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Started");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (GetClientCount(true) < GetConVarInt(g_Cvar_MinPlayers) && g_Votes == 0) // Should we keep checking g_Votes here?
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Minimal Players Not Met");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_Voted[client])
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Already Voted");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
g_Votes++;
|
||||
g_Voted[client] = true;
|
||||
|
||||
PrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded);
|
||||
|
||||
if (g_Votes >= g_VotesNeeded)
|
||||
{
|
||||
g_RTVStarted = true;
|
||||
CreateTimer(2.0, Timer_StartRTV, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
else if (GetConVarBool(g_Cvar_Nominate) && strcmp(text[startidx], "nominate", false) == 0)
|
||||
{
|
||||
if (g_RTVEnded)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Ended");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_RTVStarted)
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "RTV Started");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (g_Nominated[client])
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Already Nominated");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (GetArraySize(g_RTVMapList) >= GetConVarInt(g_Cvar_Maps))
|
||||
{
|
||||
PrintToChat(client, "[SM] %t", "Max Nominations");
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
DisplayMenu(g_MapMenu, client, MENU_TIME_FOREVER);
|
||||
AttemptRTV(client);
|
||||
}
|
||||
|
||||
SetCmdReplySource(old);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
AttemptRTV(client)
|
||||
{
|
||||
if (!g_RTVAllowed || (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished()))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "RTV Not Allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanMapChooserStartVote())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "RTV Started");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetClientCount(true) < GetConVarInt(g_Cvar_MinPlayers))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Minimal Players Not Met");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Voted[client])
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Already Voted");
|
||||
return;
|
||||
}
|
||||
|
||||
new String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
g_Votes++;
|
||||
g_Voted[client] = true;
|
||||
|
||||
PrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded);
|
||||
|
||||
if (g_Votes >= g_VotesNeeded)
|
||||
{
|
||||
StartRTV();
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_DelayRTV(Handle:timer)
|
||||
{
|
||||
g_RTVAllowed = true;
|
||||
g_RTVStarted = false;
|
||||
g_RTVEnded = false;
|
||||
}
|
||||
|
||||
public Action:Timer_StartRTV(Handle:timer)
|
||||
StartRTV()
|
||||
{
|
||||
if (timer == g_RetryTimer)
|
||||
if (g_InChange)
|
||||
{
|
||||
g_RetryTimer = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_RetryTimer != INVALID_HANDLE)
|
||||
if (HasEndOfMapVoteFinished())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
// Can't start a vote, try again in 5 seconds.
|
||||
g_RetryTimer = CreateTimer(5.0, Timer_StartRTV, TIMER_FLAG_NO_MAPCHANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "RTV Vote Ready");
|
||||
|
||||
new Handle:MapVoteMenu = CreateMenu(Handler_MapMapVoteMenu, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(MapVoteMenu, "Rock The Vote");
|
||||
|
||||
new Handle:tempMaps = CloneArray(g_MapList);
|
||||
decl String:map[32];
|
||||
|
||||
GetCurrentMap(map, sizeof(map));
|
||||
new index = FindStringInArray(tempMaps, map);
|
||||
if (index != -1)
|
||||
{
|
||||
RemoveFromArray(tempMaps, index);
|
||||
}
|
||||
|
||||
// We assume that g_RTVMapList is within the correct limits, based on the logic for nominations
|
||||
for (new i = 0; i < GetArraySize(g_RTVMapList); i++)
|
||||
{
|
||||
GetArrayString(g_RTVMapList, i, map, sizeof(map));
|
||||
AddMenuItem(MapVoteMenu, map, map);
|
||||
|
||||
index = FindStringInArray(tempMaps, map);
|
||||
if (index != -1)
|
||||
/* Change right now then */
|
||||
new String:map[65];
|
||||
if (GetNextMap(map, sizeof(map)))
|
||||
{
|
||||
RemoveFromArray(tempMaps, index);
|
||||
PrintToChatAll("[SM] %t", "Changing Maps", map);
|
||||
CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE);
|
||||
g_InChange = true;
|
||||
|
||||
ResetRTV();
|
||||
|
||||
g_RTVAllowed = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
new limit = GetConVarInt(g_Cvar_Maps) - GetArraySize(g_RTVMapList);
|
||||
if (limit > GetArraySize(tempMaps))
|
||||
if (CanMapChooserStartVote())
|
||||
{
|
||||
limit = GetArraySize(tempMaps);
|
||||
new MapChange:when = MapChange:GetConVarInt(g_Cvar_ChangeTime);
|
||||
InitiateMapChooserVote(when);
|
||||
|
||||
ResetRTV();
|
||||
|
||||
g_RTVAllowed = false;
|
||||
CreateTimer(GetConVarFloat(g_Cvar_Interval), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
|
||||
for (new i = 0; i < limit; i++)
|
||||
{
|
||||
new b = GetRandomInt(0, GetArraySize(tempMaps) - 1);
|
||||
GetArrayString(tempMaps, b, map, sizeof(map));
|
||||
PushArrayString(g_RTVMapList, map);
|
||||
AddMenuItem(MapVoteMenu, map, map);
|
||||
RemoveFromArray(tempMaps, b);
|
||||
}
|
||||
|
||||
CloseHandle(tempMaps);
|
||||
|
||||
AddMenuItem(MapVoteMenu, "Don't Change", "Don't Change");
|
||||
|
||||
SetMenuExitButton(MapVoteMenu, false);
|
||||
VoteMenuToAll(MapVoteMenu, 20);
|
||||
|
||||
LogMessage("[SM] Rockthevote was successfully started.");
|
||||
}
|
||||
|
||||
public Action:Timer_ChangeMap(Handle:hTimer, Handle:dp)
|
||||
ResetRTV()
|
||||
{
|
||||
g_Votes = 0;
|
||||
|
||||
for (new i=1; i<=MAXPLAYERS; i++)
|
||||
{
|
||||
g_Voted[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_ChangeMap(Handle:hTimer)
|
||||
{
|
||||
g_InChange = false;
|
||||
|
||||
LogMessage("RTV changing map manually");
|
||||
|
||||
new String:map[65];
|
||||
|
||||
ResetPack(dp);
|
||||
ReadPackString(dp, map, sizeof(map));
|
||||
|
||||
ServerCommand("changelevel \"%s\"", map);
|
||||
if (GetNextMap(map, sizeof(map)))
|
||||
{
|
||||
ServerCommand("changelevel \"%s\"", map);
|
||||
}
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
public Handler_MapMapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_End:
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
|
||||
case MenuAction_Display:
|
||||
{
|
||||
decl String:oldTitle[255], String:buffer[255];
|
||||
GetMenuTitle(menu, oldTitle, sizeof(oldTitle));
|
||||
Format(buffer, sizeof(buffer), "%T", oldTitle, param1);
|
||||
|
||||
new Handle:panel = Handle:param2;
|
||||
SetPanelTitle(panel, buffer);
|
||||
}
|
||||
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
if (GetMenuItemCount(menu) - 1 == param2)
|
||||
{
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", "Don't Change", param1);
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Why am I commented out? Because BAIL hasn't decided yet if
|
||||
// vote notification will be built into the Vote API.
|
||||
/*case MenuAction_Select:
|
||||
{
|
||||
decl String:Name[32], String:Map[32];
|
||||
GetClientName(param1, Name, sizeof(Name));
|
||||
GetMenuItem(menu, param2, Map, sizeof(Map));
|
||||
|
||||
PrintToChatAll("[SM] %s has voted for map '%s'", Name, Map);
|
||||
}*/
|
||||
|
||||
case MenuAction_VoteCancel:
|
||||
{
|
||||
if (param1 == VoteCancel_NoVotes)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "No Votes");
|
||||
g_RTVEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
case MenuAction_VoteEnd:
|
||||
{
|
||||
new String:map[64];
|
||||
|
||||
GetMenuItem(menu, param1, map, sizeof(map));
|
||||
|
||||
if (GetMenuItemCount(menu) - 1 == param1) // This should always match the "Keep Current" option
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Current Map Stays");
|
||||
LogMessage("[SM] Rockthevote has ended, current map kept.");
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Changing Maps", map);
|
||||
LogMessage("[SM] Rockthevote has ended, changing to map %s.", map);
|
||||
new Handle:dp;
|
||||
CreateDataTimer(5.0, Timer_ChangeMap, dp);
|
||||
WritePackString(dp, map);
|
||||
}
|
||||
|
||||
g_RTVEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Handler_MapSelectMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_Select:
|
||||
{
|
||||
if (GetArraySize(g_RTVMapList) >= GetConVarInt(g_Cvar_Maps))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Max Nominations");
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:map[64], String:name[64];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
if (FindStringInArray(g_RTVMapList, map) != -1)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Map Already Nominated");
|
||||
return;
|
||||
}
|
||||
|
||||
GetClientName(param1, name, 64);
|
||||
|
||||
PushArrayString(g_RTVMapList, map);
|
||||
RemoveMenuItem(menu, param2);
|
||||
|
||||
g_Nominated[param1] = true;
|
||||
|
||||
PrintToChatAll("[SM] %t", "Map Nominated", name, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BuildMapMenu()
|
||||
{
|
||||
if (g_MapMenu != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_MapMenu);
|
||||
g_MapMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
g_MapMenu = CreateMenu(Handler_MapSelectMenu);
|
||||
SetMenuTitle(g_MapMenu, "%t", "Nominate Title");
|
||||
|
||||
decl String:map[64];
|
||||
for (new i = 0; i < GetArraySize(g_MapList); i++)
|
||||
{
|
||||
GetArrayString(g_MapList, i, map, sizeof(map));
|
||||
AddMenuItem(g_MapMenu, map, map);
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_MapMenu, false);
|
||||
}
|
@ -319,6 +319,7 @@ namespace builder
|
||||
plugins.Add(new Plugin("adminmenu"));
|
||||
plugins.Add(new Plugin("playercommands"));
|
||||
plugins.Add(new Plugin("clientprefs"));
|
||||
plugins.Add(new Plugin("nominations"), true);
|
||||
|
||||
return (Plugin [])plugins.ToArray(typeof(Plugin));
|
||||
}
|
||||
|
@ -12,17 +12,29 @@
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Map voting has finished. The next map will be {1}."
|
||||
"#format" "{1:s},{2:i},{3:i}"
|
||||
"en" "Map voting has finished. The next map will be {1}. (Received {2}%% of {3} votes)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"en" "The current map has been extended."
|
||||
"#format" "{1:i},{2:i}"
|
||||
"en" "The current map has been extended. (Received {1}%% of {2} votes)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"en" "Extend Current Map"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"en" "Don't Change"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"#format" "{1:i},{2:i}"
|
||||
"en" "Current map continues! The Vote has spoken! (Received {1}%% of {2} votes)"
|
||||
}
|
||||
}
|
||||
|
48
translations/nominations.phrases.txt
Normal file
48
translations/nominations.phrases.txt
Normal file
@ -0,0 +1,48 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Already Nominated"
|
||||
{
|
||||
"en" "You have already nominated a map."
|
||||
|
||||
}
|
||||
|
||||
"Max Nominations"
|
||||
{
|
||||
"en" "The maximum allowed nominations has been reached."
|
||||
}
|
||||
|
||||
|
||||
"Map Already In Vote"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Map '{1}' already in the Nominations list."
|
||||
}
|
||||
|
||||
"Map Inserted"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Map '{1}' added to the nominations list."
|
||||
}
|
||||
|
||||
"Map Already Nominated"
|
||||
{
|
||||
"en" "The map you chose has already been nominated."
|
||||
}
|
||||
|
||||
"Map Nominated"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "{1} has nominated {2}."
|
||||
}
|
||||
|
||||
"Map Nomination Changed"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "{1} has changed his nomination to {2}."
|
||||
}
|
||||
|
||||
"Nominate Title"
|
||||
{
|
||||
"en" "Nominate Map:"
|
||||
}
|
||||
}
|
@ -30,18 +30,7 @@
|
||||
{
|
||||
"en" "The minimal number of players required has not been met."
|
||||
}
|
||||
|
||||
"Map Already In Vote"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Map '{1}' already in the Rock the Vote list."
|
||||
}
|
||||
|
||||
"Map Inserted"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Map '{1}' added to Rock the Vote."
|
||||
}
|
||||
|
||||
"RTV Requested"
|
||||
{
|
||||
@ -60,16 +49,6 @@
|
||||
"en" "Keep Current Map"
|
||||
}
|
||||
|
||||
"Already Nominated"
|
||||
{
|
||||
"en" "You have already nominated a map."
|
||||
|
||||
}
|
||||
|
||||
"Max Nominations"
|
||||
{
|
||||
"en" "The maximum allowed nominations has been reached."
|
||||
}
|
||||
|
||||
"Selected Map"
|
||||
{
|
||||
@ -92,20 +71,4 @@
|
||||
"#format" "{1:s}"
|
||||
"en" "Changing map to {1}! Rock the Vote has spoken!"
|
||||
}
|
||||
|
||||
"Map Already Nominated"
|
||||
{
|
||||
"en" "The map you chose has already been nominated."
|
||||
}
|
||||
|
||||
"Map Nominated"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "{1} has nominated {2} for Rock the Vote."
|
||||
}
|
||||
|
||||
"Nominate Title"
|
||||
{
|
||||
"en" "Nominate Map:"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user