added feature for leader to nominate a map which skips the restrictions

This commit is contained in:
jenz 2023-11-04 20:48:13 +01:00
parent 0394a2a402
commit 04ab4f9602
3 changed files with 170 additions and 84 deletions

View File

@ -9,6 +9,11 @@ native int PushMapsIntoNominationPool(ArrayList maps);
native int RemoveMapFromNominationPool(char[] map);
native int RemoveMapsFromNominationPool(ArrayList maps);
/**
* @MapleaderNominatedMapname is the map nominated from a map leader
*/
native void GetMapleaderNominatedMap(char[] MapleaderNominatedMapname);
public SharedPlugin __pl_nominations_extended =
{
name = "nominations",

View File

@ -51,6 +51,7 @@
#include <sdktools>
#include <multicolors>
#include <PlayerManager>
#include <nominations_extended>
#include <rockthevote_extended>
#pragma semicolon 1
@ -236,6 +237,7 @@ public void OnPluginEnd()
Call_StartForward(g_NominationsResetForward);
GetArrayString(g_NominateList[i], j, oldmap, PLATFORM_MAX_PATH);
Call_PushString(oldmap);
Call_PushCell(i);
Call_Finish();
}
}
@ -640,6 +642,7 @@ public void OnClientDisconnect(int client)
char oldmap[PLATFORM_MAX_PATH];
GetArrayString(g_NominateList[client], i, oldmap, PLATFORM_MAX_PATH);
Call_PushString(oldmap);
Call_PushCell(client);
Call_Finish();
}
@ -1021,6 +1024,11 @@ public Handle get_most_nominated_maps()
Handle most_nominated_maps = CreateArray(arraySize);
StringMap sm = new StringMap();
//november 2023 edit: now the leader can nominate one map per map played that can skip requirements: Expectation is the leader will want to lead the map.
//if leaders abuse the feature they should simply be removed from the feature.
char MapleaderNominatedMap[PLATFORM_MAX_PATH];
GetMapleaderNominatedMap(MapleaderNominatedMap);
for (int i = 0; i < MaxClients; i++)
{
for (int j = 0; j < GetArraySize(g_NominateList[i]); j++)
@ -1030,12 +1038,19 @@ public Handle get_most_nominated_maps()
int nominate_count_for_particular_map = 0;
sm.GetValue(map_iteration, nominate_count_for_particular_map);
nominate_count_for_particular_map++;
//if i is 0 its admin nominated map that must come into the vote
if(!i)
//if i is 0 its admin nominated map that must come into the vote.
//if strequal the map was nominated by a leader and most be forced on the vote.
if(!i || StrEqual(map_iteration, MapleaderNominatedMap, false))
{
nominate_count_for_particular_map = 999;
}
sm.SetValue(map_iteration, nominate_count_for_particular_map, true);
/* Notify Nominations that this map is now free */
Call_StartForward(g_NominationsResetForward);
Call_PushString(map_iteration);
Call_PushCell(i + 100); //differentiate between all other calls and the call invoked by get_most_nominated_maps()
Call_Finish();
}
}
static char map_[PLATFORM_MAX_PATH];
@ -1245,27 +1260,9 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE)
if(randomizeList == INVALID_HANDLE)
AddMapItem(map);
RemoveStringFromArray(g_NextMapList, map);
/* Notify Nominations that this map is now free */
Call_StartForward(g_NominationsResetForward);
Call_PushString(map);
Call_Finish();
}
/* Clear out the rest of the nominations array */
for(int i = nominationsToAdd; i < nominateCount; i++)
{
//2023 edit: might need to run all g_NominateList[client] through this instead
GetArrayString(most_nominated_maps, i, map, PLATFORM_MAX_PATH);
/* These maps shouldn't be excluded from the vote as they weren't really nominated at all */
/* Notify Nominations that this map is now free */
Call_StartForward(g_NominationsResetForward);
Call_PushString(map);
Call_Finish();
}
/* There should currently be 'nominationsToAdd' unique maps in the vote */
@ -1521,7 +1518,7 @@ public void Handler_VoteFinishedGeneric(char[] map,
if(fraglimit)
SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep));
CPrintToChatAll("[MCE] %t", "Current Map Extended", RoundToFloor((map_votes /num_votes)*100.0));
PrintToChatAll("The current map has been extended. (Received %i%s of votes)", RoundToFloor((map_votes /num_votes)*100.0), "%");
LogAction(-1, -1, "Voting for next map has finished. The current map has been extended.");
CPrintToChatAll("[MCE] Available Extends: %d", GetConVarInt(g_Cvar_Extend) - g_Extends);
@ -1532,7 +1529,7 @@ public void Handler_VoteFinishedGeneric(char[] map,
}
else if(strcmp(map, VOTE_DONTCHANGE, false) == 0)
{
CPrintToChatAll("[MCE] %t", "Current Map Stays", RoundToFloor((map_votes /num_votes)*100.0));
PrintToChatAll("Current map continues! The Vote has spoken! (Received %i%s of votes)", RoundToFloor((map_votes /num_votes)*100.0), "%");
LogAction(-1, -1, "Voting for next map has finished. 'No Change' was the winner");
g_RunoffCount = 0;
@ -2027,6 +2024,7 @@ NominateResult InternalNominateMap(char[] map, int owner)
GetArrayString(g_NominateList[owner], 0, oldmap, PLATFORM_MAX_PATH);
Call_StartForward(g_NominationsResetForward);
Call_PushString(oldmap);
Call_PushCell(owner);
Call_Finish();
RemoveFromArray(g_NominateList[owner], 0);
@ -2079,6 +2077,7 @@ NominateResult InternalNominateMap(char[] map, int owner)
GetArrayString(g_NominateList[owner], 0, oldmap, PLATFORM_MAX_PATH);
Call_StartForward(g_NominationsResetForward);
Call_PushString(oldmap);
Call_PushCell(owner);
int owner_ = GetArrayCell(g_NominateOwners, 0);
Call_Finish();
@ -2123,6 +2122,7 @@ bool InternalRemoveNominationByMap(char[] map)
{
Call_StartForward(g_NominationsResetForward);
Call_PushString(oldmap);
Call_PushCell(client);
Call_Finish();
int owner = GetArrayCell(g_NominateOwners, i);
@ -2158,26 +2158,27 @@ public int Native_RemoveNominationByMap(Handle plugin, int numParams)
bool InternalRemoveNominationByOwner(int owner)
{
int index;
int index;
if(owner && ((index = FindValueInArray(g_NominateOwners, owner)) != -1))
{
char oldmap[PLATFORM_MAX_PATH];
GetArrayString(g_NominateList[owner], index, oldmap, PLATFORM_MAX_PATH);
if(owner && ((index = FindValueInArray(g_NominateOwners, owner)) != -1))
{
char oldmap[PLATFORM_MAX_PATH];
GetArrayString(g_NominateList[owner], index, oldmap, PLATFORM_MAX_PATH);
Call_StartForward(g_NominationsResetForward);
Call_PushString(oldmap);
Call_Finish();
Call_StartForward(g_NominationsResetForward);
Call_PushString(oldmap);
Call_PushCell(owner);
Call_Finish();
RemoveFromArray(g_NominateList[owner], index);
RemoveFromArray(g_NominateList[owner], index);
//maybe only do once or change g_NominateOwners
RemoveFromArray(g_NominateOwners, index);
g_NominateCount--;
RemoveFromArray(g_NominateOwners, index);
g_NominateCount--;
return true;
}
return true;
}
return false;
return false;
}
/* native bool RemoveNominationByOwner(owner); */
@ -2867,6 +2868,7 @@ void CheckMapRestrictions(bool time = false, bool players = false)
{
Call_StartForward(g_NominationsResetForward);
Call_PushString(map);
Call_PushCell(client);
Call_Finish();
}

View File

@ -39,9 +39,10 @@
#include <mapchooser>
#include <mapchooser_extended>
#include <multicolors>
#include <leader>
#include <basecomm>
#define MCE_VERSION "1.3.1"
#define MCE_VERSION "1.4.1"
public Plugin myinfo =
{
@ -82,6 +83,8 @@ Handle g_Cvar_VIPTimeframeMaxTime = INVALID_HANDLE;
int g_Player_NominationDelay[MAXPLAYERS+1];
int g_NominationDelay;
int g_iMapleaderWhoNominatedMap = -1;
char g_cMapLeaderNominatedMap[256];
//clients ignoring maps that are unavailable
bool g_bClientsIgnoring[MAXPLAYERS + 1];
@ -135,6 +138,8 @@ public void OnPluginStart()
public void OnMapStart()
{
Format(g_cMapLeaderNominatedMap, sizeof(g_cMapLeaderNominatedMap), "");
g_iMapleaderWhoNominatedMap = -1;
if (!g_dDatabase)
{
//we have too many dbs so i am just re-using racetimercss
@ -259,6 +264,7 @@ public APLRes AskPluginLoad2(Handle hThis, bool bLate, char[] err, int iErrLen)
CreateNative("PushMapsIntoNominationPool", Native_PushMapsIntoNominationPool);
CreateNative("RemoveMapFromNominationPool", Native_RemoveMapFromNominationPool);
CreateNative("RemoveMapsFromNominationPool", Native_RemoveMapsFromNominationPool);
CreateNative("GetMapleaderNominatedMap", Native_GetMapleaderNominatedMap);
return APLRes_Success;
}
@ -362,17 +368,38 @@ void UpdateMapTrie()
delete excludeMaps;
}
public void OnNominationRemoved(const char[] map)
public void OnNominationRemoved(const char[] map, int client)
{
int status;
/* Is the map in our list? */
if(!GetTrieValue(g_mapTrie, map, status))
return;
int newclient = 0;
//just differientiating between if nomination was removed because of starting vote or because of anything else possible.
if (client > 100)
{
newclient = client - 100;
}
else
{
newclient = client;
}
if (newclient == g_iMapleaderWhoNominatedMap && StrEqual(map, g_cMapLeaderNominatedMap, false))
{
if (client > 100)
{
CPrintToChatAll("{darkorange}[UNLOZE Nominations] {white}The map leader {lightgreen}%N {white}nomination {red}%s {white}was forced into the mapvote.", newclient, map);
}
else
{
CPrintToChatAll("{darkorange}[UNLOZE Nominations] {white}The map leader {lightgreen}%N {white}has removed his Mapleader nomination {red}%s", newclient, map);
}
Format(g_cMapLeaderNominatedMap, sizeof(g_cMapLeaderNominatedMap), "");
g_iMapleaderWhoNominatedMap = -1;
}
/* Was the map disabled due to being nominated */
if((status & MAPSTATUS_EXCLUDE_NOMINATED) != MAPSTATUS_EXCLUDE_NOMINATED)
return;
SetTrieValue(g_mapTrie, map, MAPSTATUS_ENABLED);
}
@ -399,8 +426,8 @@ public Action Command_Addmap(int client, int args)
AttemptAdminNominate(client, mapname);
return Plugin_Handled;
}
if(!CheckCommandAccess(client, "sm_nominate_ignore", ADMFLAG_KICK, true))
if(!CheckCommandAccess(client, "sm_nominate_ignore", ADMFLAG_KICK, true) )
{
bool RestrictionsActive = AreRestrictionsActive();
@ -461,6 +488,7 @@ public Action Command_Addmap(int client, int args)
}
}
NominateResult result = NominateMap(mapname, true, 0);
if(result > Nominate_Replaced)
@ -697,49 +725,60 @@ public Action Command_Nominate(int client, int args)
return Plugin_Handled;
}
int Cooldown = GetMapCooldownTime(mapname);
if(RestrictionsActive && Cooldown > GetTime())
int mapLeader = Leader_CurrentLeader();
//2023 November edit: one map nominated by mapleader will automatically go to the vote.
if (client == mapLeader && StrEqual(g_cMapLeaderNominatedMap, ""))
{
int Seconds = Cooldown - GetTime();
CPrintToChat(client, "[NE] %t", "Map Cooldown Time Error", Seconds / 3600, (Seconds % 3600) / 60);
return Plugin_Handled;
CPrintToChatAll("{darkorange}[UNLOZE Nominations] {white}The map leader {lightgreen}%N {white}has nominated the map {red}%s{white}. The map will be in the next mapvote.", client, mapname);
CPrintToChatAll("{lightblue}If the map is nextmap and the leader wont play it he will be removed from leader access.");
Format(g_cMapLeaderNominatedMap, sizeof(g_cMapLeaderNominatedMap), mapname);
g_iMapleaderWhoNominatedMap = client;
}
bool VIPRestriction = GetMapVIPRestriction(mapname, client);
if(RestrictionsActive && VIPRestriction)
else
{
CPrintToChat(client, "[NE] %t", "Map Nominate VIP Error");
int Cooldown = GetMapCooldownTime(mapname);
if(RestrictionsActive && Cooldown > GetTime())
{
int Seconds = Cooldown - GetTime();
CPrintToChat(client, "[NE] %t", "Map Cooldown Time Error", Seconds / 3600, (Seconds % 3600) / 60);
return Plugin_Handled;
return Plugin_Handled;
}
bool VIPRestriction = GetMapVIPRestriction(mapname, client);
if(RestrictionsActive && VIPRestriction)
{
CPrintToChat(client, "[NE] %t", "Map Nominate VIP Error");
return Plugin_Handled;
}
int TimeRestriction = GetMapTimeRestriction(mapname);
if(RestrictionsActive && TimeRestriction)
{
CPrintToChat(client, "[NE] %t", "Map Nominate Time Error", TimeRestriction / 60, TimeRestriction % 60);
return Plugin_Handled;
}
int AverageHourRestricted = GetAveragePlayerTimeOnServerMapRestriction(mapname);
if (AverageHourRestricted > 0)
{
PrintToChat(client, "%s requires +%i hours average. Use sm_houravg to check average.", mapname, AverageHourRestricted);
return Plugin_Handled;
}
int PlayerRestriction = GetMapPlayerRestriction(mapname);
if(RestrictionsActive && PlayerRestriction)
{
if(PlayerRestriction < 0)
CPrintToChat(client, "[NE] %t", "Map Nominate MinPlayers Error", PlayerRestriction * -1);
else
CPrintToChat(client, "[NE] %t", "Map Nominate MaxPlayers Error", PlayerRestriction);
return Plugin_Handled;
}
}
int TimeRestriction = GetMapTimeRestriction(mapname);
if(RestrictionsActive && TimeRestriction)
{
CPrintToChat(client, "[NE] %t", "Map Nominate Time Error", TimeRestriction / 60, TimeRestriction % 60);
return Plugin_Handled;
}
int AverageHourRestricted = GetAveragePlayerTimeOnServerMapRestriction(mapname);
if (AverageHourRestricted > 0)
{
PrintToChat(client, "%s requires +%i hours average. Use sm_houravg to check average.", mapname, AverageHourRestricted);
return Plugin_Handled;
}
int PlayerRestriction = GetMapPlayerRestriction(mapname);
if(RestrictionsActive && PlayerRestriction)
{
if(PlayerRestriction < 0)
CPrintToChat(client, "[NE] %t", "Map Nominate MinPlayers Error", PlayerRestriction * -1);
else
CPrintToChat(client, "[NE] %t", "Map Nominate MaxPlayers Error", PlayerRestriction);
return Plugin_Handled;
}
NominateResult result = NominateMap(mapname, false, client);
if (result == Nominate_InvalidMap)
@ -768,7 +807,9 @@ public Action Command_Nominate(int client, int args)
if(result == Nominate_Added)
PrintToChatAll("[NE] %t", "Map Nominated", name, mapname);
else if(result == Nominate_Replaced)
{
PrintToChatAll("[NE] %t", "Map Nomination Changed", name, mapname);
}
LogMessage("%s nominated %s", name, mapname);
@ -835,7 +876,15 @@ void AttemptNominate(int client, const char[] filter = "")
Menu menu = g_MapMenu;
menu = BuildMapMenu(filter, client);
SetMenuTitle(menu, "%T", "Nominate Title", client);
int mapLeader = Leader_CurrentLeader();
if (client == mapLeader && StrEqual(g_cMapLeaderNominatedMap, ""))
{
SetMenuTitle(menu, "Nominate Map as Mapleader:", client);
}
else
{
SetMenuTitle(menu, "%T", "Nominate Title", client);
}
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
@ -918,7 +967,8 @@ bool PopulateNominateListMenu(Menu menu, int client, const char[] filter = "")
int owner = GetArrayCell(OwnerList, i);
int nominate_count_for_particular_map = 0;
sm.GetValue(map, nominate_count_for_particular_map);
if(!owner)
//if its console its admin nomination. if its g_iMapleaderWhoNominatedMap it was map nominated by leader, also has to be correct map out of 3.
if(!owner || (owner == g_iMapleaderWhoNominatedMap && StrEqual(map, g_cMapLeaderNominatedMap)))
{
nominate_count_for_particular_map = 999;
}
@ -958,6 +1008,12 @@ bool PopulateNominateListMenu(Menu menu, int client, const char[] filter = "")
if(!owner)
Format(display, sizeof(display), "%s (Admin)", display);
else if (StrEqual(map, g_cMapLeaderNominatedMap))
{
char leadername[MAX_NAME_LENGTH];
GetClientName(g_iMapleaderWhoNominatedMap, leadername, MAX_NAME_LENGTH);
Format(display, sizeof(display), "%s (Mapleader %s)", display, leadername);
}
else
Format(display, sizeof(display), "%s (%i %s)", display, nominate_count_for_particular_map, spelling);
@ -1094,7 +1150,7 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
{
case MenuAction_End:
{
if (menu != g_MapMenu)
if (menu != g_MapMenu && menu != null)
{
delete menu;
}
@ -1130,7 +1186,16 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
GetClientName(param1, name, MAX_NAME_LENGTH);
if(AreRestrictionsActive() && (
int mapLeader = Leader_CurrentLeader();
//2023 November edit: one map nominated by mapleader will automatically go to the vote.
if (param1 == mapLeader && StrEqual(g_cMapLeaderNominatedMap, ""))
{
CPrintToChatAll("{darkorange}[UNLOZE Nominations] {white}The map leader {lightgreen}%N {white}has nominated the map {red}%s{white}. The map will be in the next mapvote.", param1, map);
CPrintToChatAll("{lightblue}If the map is nextmap and the leader wont play it he will be removed from leader access.");
Format(g_cMapLeaderNominatedMap, sizeof(g_cMapLeaderNominatedMap), map);
g_iMapleaderWhoNominatedMap = param1;
}
else if(AreRestrictionsActive() && (
GetMapCooldownTime(map) > GetTime() ||
GetMapTimeRestriction(map) ||
GetMapPlayerRestriction(map) ||
@ -1166,7 +1231,9 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
if(result == Nominate_Added)
PrintToChatAll("[NE] %t", "Map Nominated", name, map);
else if(result == Nominate_Replaced)
{
PrintToChatAll("[NE] %t", "Map Nomination Changed", name, map);
}
LogMessage("%s nominated %s", name, map);
g_Player_NominationDelay[param1] = GetTime() + GetConVarInt(g_Cvar_NominateDelay);
@ -1200,6 +1267,12 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
}
}
int mapLeader = Leader_CurrentLeader();
if (param1 == mapLeader && StrEqual(g_cMapLeaderNominatedMap, ""))
{
return ITEMDRAW_DEFAULT;
}
if(AreRestrictionsActive() && (
GetMapCooldownTime(map) > GetTime() ||
GetMapTimeRestriction(map) ||
@ -1556,6 +1629,12 @@ public int Native_RemoveMapsFromNominationPool(Handle plugin, int numArgs)
return 0;
}
public int Native_GetMapleaderNominatedMap(Handle plugin, int numArgs)
{
SetNativeString(1, g_cMapLeaderNominatedMap, sizeof(g_cMapLeaderNominatedMap), true);
return 0;
}
stock int GetVIPTimeRestriction()
{
if (!GetConVarBool(g_Cvar_VIPTimeframe))