lots of changes
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Leader3 vote: !voteleader / !vl <name>. Passes at sm_leader_vote_ratio of eligible voters.
|
||||
// Eligible = in-game, not a bot, not AFK (AFKManager, when loaded).
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
int g_iVoteCount[MAXPLAYERS + 1]; // votes received, per candidate
|
||||
int g_iVotedForSerial[MAXPLAYERS + 1]; // per voter: client serial of their candidate
|
||||
|
||||
public Action Cmd_VoteLeader(int client, int args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "%s Cannot use this from the console.", PREFIX_PLAIN);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!g_cvAllowVotes.BoolValue)
|
||||
{
|
||||
ReplyToCommand(client, "%s Voting for leader is disabled.", PREFIX_PLAIN);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "%s Usage: sm_voteleader <player>", PREFIX_PLAIN);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
int target = FindTarget(client, arg, true, false);
|
||||
if (target == -1)
|
||||
return Plugin_Handled;
|
||||
|
||||
if (g_bIsLeader[target])
|
||||
{
|
||||
ReplyToCommand(client, "%s %N is already a leader!", PREFIX_PLAIN, target);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (g_alLeaders.Length >= g_cvMaxLeaders.IntValue)
|
||||
{
|
||||
ReplyToCommand(client, "%s The maximum of %d leaders is already reached.", PREFIX_PLAIN, g_cvMaxLeaders.IntValue);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
int previous = GetClientFromSerial(g_iVotedForSerial[client]);
|
||||
if (previous == target)
|
||||
{
|
||||
ReplyToCommand(client, "%s You have already voted for this player!", PREFIX_PLAIN);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (previous != 0)
|
||||
g_iVoteCount[previous]--;
|
||||
|
||||
g_iVoteCount[target]++;
|
||||
g_iVotedForSerial[client] = GetClientSerial(target);
|
||||
|
||||
PrintToChatAll("%s\x04%N\x01 voted for \x04%N\x01 to become a leader (\x04%d/%d\x01 votes).",
|
||||
PREFIX, client, target, g_iVoteCount[target], Vote_Needed());
|
||||
|
||||
Vote_Check(target);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
int Vote_EligibleCount()
|
||||
{
|
||||
int afkTime = g_cvVoteAfkTime.IntValue;
|
||||
int count = 0;
|
||||
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || IsFakeClient(i))
|
||||
continue;
|
||||
if (g_bAFKManager && afkTime > 0 && GetClientIdleTime(i) >= afkTime)
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int Vote_Needed()
|
||||
{
|
||||
int needed = RoundToCeil(float(Vote_EligibleCount()) * g_cvVoteRatio.FloatValue);
|
||||
return needed < 2 ? 2 : needed;
|
||||
}
|
||||
|
||||
void Vote_Check(int candidate)
|
||||
{
|
||||
if (!IsValidClient(candidate) || g_iVoteCount[candidate] <= 0)
|
||||
return;
|
||||
|
||||
if (g_iVoteCount[candidate] < Vote_Needed())
|
||||
return;
|
||||
|
||||
Vote_ClearCandidate(candidate);
|
||||
PrintToChatAll("%s\x04%N\x01 has been voted to become a leader!", PREFIX, candidate);
|
||||
if (AddLeader(candidate))
|
||||
ShowLeaderMenu(candidate);
|
||||
}
|
||||
|
||||
void Vote_ClearCandidate(int candidate)
|
||||
{
|
||||
g_iVoteCount[candidate] = 0;
|
||||
|
||||
int serial = GetClientSerial(candidate);
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (g_iVotedForSerial[i] == serial)
|
||||
g_iVotedForSerial[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// A shrinking voter pool can push a pending candidate over the threshold.
|
||||
void Vote_RecheckAll()
|
||||
{
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (g_iVoteCount[i] > 0)
|
||||
Vote_Check(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Vote_OnClientDisconnect(int client)
|
||||
{
|
||||
int previous = GetClientFromSerial(g_iVotedForSerial[client]);
|
||||
if (previous != 0)
|
||||
g_iVoteCount[previous]--;
|
||||
g_iVotedForSerial[client] = 0;
|
||||
|
||||
if (g_iVoteCount[client] > 0)
|
||||
Vote_ClearCandidate(client);
|
||||
|
||||
Vote_RecheckAll();
|
||||
}
|
||||
Reference in New Issue
Block a user