mapchooser_extended: mapchooser_extended: add reserved/random nomination slots (by Botox)

This commit is contained in:
neon
2018-08-10 12:43:49 +02:00
parent 679ba49402
commit 3c8d8c99f8
4 changed files with 728 additions and 163 deletions
@@ -111,6 +111,7 @@ ConVar g_Cvar_ExtendRoundStep;
ConVar g_Cvar_ExtendFragStep;
ConVar g_Cvar_ExcludeMaps;
ConVar g_Cvar_IncludeMaps;
ConVar g_Cvar_IncludeMapsReserved;
ConVar g_Cvar_NoVoteMode;
ConVar g_Cvar_Extend;
ConVar g_Cvar_DontChange;
@@ -141,6 +142,7 @@ bool g_HasIntermissionStarted = false;
int g_mapFileSerial = -1;
int g_NominateCount = 0;
int g_NominateReservedCount = 0;
MapChange g_ChangeTime;
Handle g_NominationsResetForward = INVALID_HANDLE;
@@ -238,7 +240,8 @@ public void OnPluginStart()
g_Cvar_ExtendRoundStep = CreateConVar("mce_extend_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 1.0);
g_Cvar_ExtendFragStep = CreateConVar("mce_extend_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0);
g_Cvar_ExcludeMaps = CreateConVar("mce_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0);
g_Cvar_IncludeMaps = CreateConVar("mce_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0);
g_Cvar_IncludeMaps = CreateConVar("mce_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 7.0);
g_Cvar_IncludeMapsReserved = CreateConVar("mce_include_reserved", "2", "Specifies how many private/random maps to include in the vote.", _, true, 0.0, true, 5.0);
g_Cvar_NoVoteMode = CreateConVar("mce_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("mce_extend", "0", "Number of extensions allowed each map.", _, true, 0.0);
g_Cvar_DontChange = CreateConVar("mce_dontchange", "1", "Specifies if a 'Don't Change' option should be added to early votes", _, true, 0.0);
@@ -249,7 +252,7 @@ public void OnPluginStart()
g_Cvar_RunOff = CreateConVar("mce_runoff", "1", "Hold run off votes if winning choice has less than a certain percentage of votes", _, true, 0.0, true, 1.0);
g_Cvar_RunOffPercent = CreateConVar("mce_runoffpercent", "50", "If winning choice has less than this percent of votes, hold a runoff", _, true, 0.0, true, 100.0);
g_Cvar_BlockSlots = CreateConVar("mce_blockslots", "1", "Block slots to prevent accidental votes. Only applies when Voice Command style menus are in use.", _, true, 0.0, true, 1.0);
g_Cvar_BlockSlots = CreateConVar("mce_blockslots", "0", "Block slots to prevent accidental votes. Only applies when Voice Command style menus are in use.", _, true, 0.0, true, 1.0);
//g_Cvar_BlockSlotsCount = CreateConVar("mce_blockslots_count", "2", "Number of slots to block.", _, true, 1.0, true, 3.0);
g_Cvar_MaxRunOffs = CreateConVar("mce_maxrunoffs", "1", "Number of run off votes allowed each map.", _, true, 0.0);
g_Cvar_StartTimePercent = CreateConVar("mce_start_percent", "35.0", "Specifies when to start the vote based on percents.", _, true, 0.0, true, 100.0);
@@ -405,7 +408,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
CreateNative("GetMapMaxPlayers", Native_GetMapMaxPlayers);
CreateNative("GetMapTimeRestriction", Native_GetMapTimeRestriction);
CreateNative("GetMapPlayerRestriction", Native_GetMapPlayerRestriction);
CreateNative("GetMapGroup", Native_GetMapGroup);
CreateNative("GetMapGroups", Native_GetMapGroups);
CreateNative("GetMapGroupRestriction", Native_GetMapGroupRestriction);
return APLRes_Success;
@@ -497,6 +500,7 @@ public void OnConfigsExecuted()
g_MapVoteCompleted = false;
g_NominateCount = 0;
g_NominateReservedCount = 0;
ClearArray(g_NominateList);
ClearArray(g_NominateOwners);
@@ -1072,7 +1076,7 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE)
int nominateCount = GetArraySize(g_NominateList);
int voteSize = GetVoteSize();
int voteSize = GetVoteSize(2);
// The if and else if could be combined, but it looks extremely messy
// This is a hack to lower the vote menu size by 1 when Don't Change or Extend Map should appear
@@ -1181,6 +1185,7 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE)
/* Wipe out our nominations list - Nominations have already been informed of this */
g_NominateCount = 0;
g_NominateReservedCount = 0;
ClearArray(g_NominateOwners);
ClearArray(g_NominateList);
@@ -1228,7 +1233,7 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE)
{
//SetMenuExitButton(g_VoteMenu, false);
if(GetVoteSize() <= GetMaxPageItems(GetMenuStyle(g_VoteMenu)))
if(GetVoteSize(2) <= GetMaxPageItems(GetMenuStyle(g_VoteMenu)))
{
//This is necessary to get items 9 and 0 as usable voting items
SetMenuPagination(g_VoteMenu, MENU_NO_PAGINATION);
@@ -1651,12 +1656,31 @@ void CreateNextVote()
delete OldMapListSnapshot;
}
int voteSize = GetVoteSize();
int voteSize = GetVoteSize(2);
int limit = (voteSize < GetArraySize(tempMaps) ? voteSize : GetArraySize(tempMaps));
StringMap groups = new StringMap();
char group[255];
// group -> number of maps nominated from group
StringMap groupmap = new StringMap();
char groupstr[8];
// populate groupmap with maps from nomination list
static char map_[PLATFORM_MAX_PATH];
int groups_[32];
for(int i = 0; i < GetArraySize(g_NominateList); i++)
{
GetArrayString(g_NominateList, i, map_, PLATFORM_MAX_PATH);
int groupsfound = InternalGetMapGroups(map_, groups_, sizeof(groups_));
for(int group = 0; group < groupsfound; group++)
{
IntToString(group, groupstr, sizeof(groupstr));
int groupcur = 0;
groupmap.GetValue(groupstr, groupcur);
groupcur++;
groupmap.SetValue(groupstr, groupcur, true);
}
}
// find random maps which honor all restrictions
for(int i = 0; i < limit; i++)
{
int b;
@@ -1668,23 +1692,39 @@ void CreateNextVote()
if(InternalGetMapPlayerRestriction(map) == 0)
break;
int groupmax = InternalGetMapGroup(map, group, sizeof(group));
if(groupmax >= 0)
{
int groupcur = 0;
groups.GetValue(group, groupcur);
bool okay = true;
if(groupcur >= groupmax)
break;
groupcur++;
groups.SetValue(group, groupcur, true);
int groups[32];
int groupsfound = InternalGetMapGroups(map, groups, sizeof(groups));
for(int group = 0; group < groupsfound; group++)
{
IntToString(group, groupstr, sizeof(groupstr));
int groupmax = InternalGetGroupMax(groups[group]);
if(groupmax >= 0)
{
int groupcur = 0;
groupmap.GetValue(groupstr, groupcur);
if(groupcur >= groupmax)
{
okay = false;
break;
}
groupcur++;
groupmap.SetValue(groupstr, groupcur, true);
}
}
if(okay)
break;
}
PushArrayString(g_NextMapList, map);
RemoveFromArray(tempMaps, b);
}
delete groups;
delete groupmap;
CloseHandle(tempMaps);
}
@@ -1733,20 +1773,27 @@ NominateResult InternalNominateMap(char[] map, bool force, int owner)
PushArrayString(g_NominateList, map);
PushArrayCell(g_NominateOwners, owner);
g_NominateCount++;
if(owner == 0 && g_NominateReservedCount < GetVoteSize(1))
g_NominateReservedCount++;
else
g_NominateCount++;
while(GetArraySize(g_NominateList) > GetVoteSize())
while(GetArraySize(g_NominateList) > GetVoteSize(2))
{
char oldmap[PLATFORM_MAX_PATH];
GetArrayString(g_NominateList, 0, oldmap, PLATFORM_MAX_PATH);
Call_StartForward(g_NominationsResetForward);
Call_PushString(oldmap);
Call_PushCell(GetArrayCell(g_NominateOwners, 0));
int owner_ = GetArrayCell(g_NominateOwners, 0);
Call_PushCell(owner_);
Call_Finish();
RemoveFromArray(g_NominateList, 0);
RemoveFromArray(g_NominateOwners, 0);
g_NominateCount--;
if(owner_ == 0)
g_NominateReservedCount--;
else
g_NominateCount--;
}
return Nominate_Added;
@@ -2165,7 +2212,7 @@ public int Native_GetMapPlayerRestriction(Handle plugin, int numParams)
return InternalGetMapPlayerRestriction(map);
}
public int Native_GetMapGroup(Handle plugin, int numParams)
public int Native_GetMapGroups(Handle plugin, int numParams)
{
int len;
GetNativeStringLength(1, len);
@@ -2177,11 +2224,11 @@ public int Native_GetMapGroup(Handle plugin, int numParams)
char[] map = new char[len+1];
GetNativeString(1, map, len+1);
char[] group = new char[size];
int groupmax = InternalGetMapGroup(map, group, size);
if(groupmax >= 0)
SetNativeString(2, group, size);
return groupmax;
int[] groups = new int[size];
int found = InternalGetMapGroups(map, groups, size);
if(found >= 0)
SetNativeArray(2, groups, size);
return found;
}
public int Native_GetMapGroupRestriction(Handle plugin, int numParams)
@@ -2196,45 +2243,51 @@ public int Native_GetMapGroupRestriction(Handle plugin, int numParams)
char[] map = new char[len+1];
GetNativeString(1, map, len+1);
static char group[255];
int groupmax = InternalGetMapGroup(map, group, sizeof(group));
int groupcur = 0;
if(groupmax >= 0)
{
static char map_[PLATFORM_MAX_PATH];
static char group_[255];
for(int i = 0; i < GetArraySize(g_NominateList); i++)
{
GetArrayString(g_NominateList, i, map_, PLATFORM_MAX_PATH);
int tmp = InternalGetMapGroup(map_, group_, sizeof(group_));
if(tmp == groupmax && StrEqual(group, group_))
groupcur++;
}
int groups[32];
int groupsfound = InternalGetMapGroups(map, groups, sizeof(groups));
if(groupcur >= groupmax)
for(int group = 0; group < groupsfound; group ++)
{
int groupcur = 0;
int groupmax = InternalGetGroupMax(groups[group]);
if(groupmax >= 0)
{
// Check if client has nominated a map in the same group and can change their nomination
if(client > 0 && client < MaxClients)
static char map_[PLATFORM_MAX_PATH];
int groups_[32];
for(int i = 0; i < GetArraySize(g_NominateList); i++)
{
int index = FindValueInArray(g_NominateOwners, client);
if(index != -1)
{
static char oldmap[PLATFORM_MAX_PATH];
GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH);
char oldgroup[255];
int tmp = InternalGetMapGroup(oldmap, oldgroup, sizeof(oldgroup));
if(tmp == groupmax && StrEqual(group, group_))
return -321;
}
GetArrayString(g_NominateList, i, map_, PLATFORM_MAX_PATH);
int tmp = InternalGetMapGroups(map_, groups_, sizeof(groups_));
if(FindIntInArray(groups_, tmp, groups[group]) != -1)
groupcur++;
}
return groupmax;
}
if(groupcur >= groupmax)
{
// Check if client has nominated a map in the same group and can change their nomination
bool okay = false;
if(client > 0 && client < MaxClients)
{
int index = FindValueInArray(g_NominateOwners, client);
if(index != -1)
{
static char oldmap[PLATFORM_MAX_PATH];
GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH);
static int oldgroups[32];
int tmp = InternalGetMapGroups(oldmap, oldgroups, sizeof(oldgroups));
if(FindIntInArray(groups_, tmp, groups[group]) != -1)
okay = true;
}
}
return -123;
if(!okay)
return groupmax;
}
}
}
return groupmax;
return -1;
}
@@ -2276,19 +2329,32 @@ stock void AddExtendToMenu(Handle menu, MapChange when)
}
}
stock int GetVoteSize()
// 0 = IncludeMaps, 1 = Reserved, 2 = IncludeMaps+Reserved
stock int GetVoteSize(int what=0)
{
int voteSize = GetConVarInt(g_Cvar_IncludeMaps);
int voteSize = 0;
int includeMaps = GetConVarInt(g_Cvar_IncludeMaps);
int includeMapsReserved = GetConVarInt(g_Cvar_IncludeMapsReserved);
if(what == 0 || what == 2)
voteSize += includeMaps;
if(what == 1 || what == 2)
voteSize += includeMapsReserved;
// New in 1.9.5 to let us bump up the included maps count
if(g_NativeVotes)
{
int max = NativeVotes_GetMaxItems();
if(max < voteSize)
if(voteSize > max)
voteSize = max;
if(includeMaps > max)
includeMaps = max;
}
if(what == 1)
return voteSize - includeMaps;
return voteSize;
}
@@ -2327,7 +2393,7 @@ void CheckMapRestrictions(bool time = false, bool players = false)
CPrintToChat(client, "[MCE] %t", "Nomination Removed Time Error", map);
}
}
if (players)
{
int PlayerRestriction = InternalGetMapPlayerRestriction(map);
@@ -2408,8 +2474,9 @@ stock int InternalGetMapMaxPlayers(const char[] map)
return MaxPlayers;
}
stock int InternalGetMapGroup(const char[] map, char[] group, int size)
stock int InternalGetMapGroups(const char[] map, int[] groups, int size)
{
int found = 0;
if(g_Config && g_Config.JumpToKey("_groups"))
{
if(!g_Config.GotoFirstSubKey(false))
@@ -2420,19 +2487,44 @@ stock int InternalGetMapGroup(const char[] map, char[] group, int size)
do
{
int ret = g_Config.GetNum("_max", 1);
g_Config.GetSectionName(group, size);
char groupstr[8];
g_Config.GetSectionName(groupstr, sizeof(groupstr));
int group = StringToInt(groupstr);
if(g_Config.JumpToKey(map, false))
{
g_Config.Rewind();
return ret;
groups[found++] = group;
if(found >= size)
{
g_Config.Rewind();
return found;
}
g_Config.GoBack();
}
} while(g_Config.GotoNextKey());
g_Config.Rewind();
}
return -999;
return found;
}
stock int InternalGetGroupMax(int group)
{
char groupstr[8];
IntToString(group, groupstr, sizeof(groupstr));
if(g_Config && g_Config.JumpToKey("_groups"))
{
if(g_Config.JumpToKey(groupstr, false))
{
int max = g_Config.GetNum("_max", -1);
g_Config.Rewind();
return max;
}
g_Config.Rewind();
}
return -1;
}
// 0 = Okay
@@ -2484,3 +2576,14 @@ stock int InternalGetMapPlayerRestriction(const char[] map)
return 0;
}
stock int FindIntInArray(int[] array, int size, int value)
{
for(int i = 0; i < size; i++)
{
if(array[i] == value)
return i;
}
return -1;
}