diff --git a/mapchooser_extended/configs/mapchooser_extended.cfg b/mapchooser_extended/configs/mapchooser_extended.cfg index 8c53f82e..b81cf029 100644 --- a/mapchooser_extended/configs/mapchooser_extended.cfg +++ b/mapchooser_extended/configs/mapchooser_extended.cfg @@ -2,7 +2,7 @@ { "_groups" { - "final_fantasy" + "1" // final fantasy { "_max" "2" "ze_ffvii_cosmo_canyon_v1beta1" {} @@ -32,7 +32,7 @@ "ze_FFXIV_Wanderers_Palace_v5_2f" {} "ze_FFVII_Temple_Ancient_v3_3" {} } - "cosmo" + "2" // cosmo { "_max" "1" "ze_ffvii_cosmo_canyon_v1beta1" {} @@ -42,7 +42,7 @@ "ze_ffvii_cosmo_canyon_v5test2" {} "ze_ffvii_cosmo_canyon_v5fix" {} } - "wester" + "3" // wester { "_max" "1" "ze_ffxii_westersand_v2_11a" {} @@ -51,7 +51,7 @@ "ze_FFXII_Westersand_v7" {} "ze_FFXII_Westersand_v7_2" {} } - "mako" + "4" // mako { "_max" "1" "ze_FFVII_Mako_Reactor_b2" {} @@ -60,20 +60,20 @@ "ze_FFVII_Mako_Reactor_v5_3" {} "ZE_FFVII_Mako_Reactor_V6_B08" {} } - "wanderes" + "5" // wanderes { "_max" "1" "ze_ffxiv_wanderers_palace_css" {} "ze_ffxiv_wanderers_palace_v4_5s" {} "ze_FFXIV_Wanderers_Palace_v5_2f" {} } - "minas" + "6" // minas { "_max" "1" "ze_lotr_minas_tirith_v2_2fix" {} "ze_lotr_minas_tirith_v3_3" {} } - "rooftop" + "7" // rooftop { "_max" "2" "ze_gargantua_v2_0" {} @@ -294,4 +294,4 @@ { "MinPlayers" "20" } -} \ No newline at end of file +} diff --git a/mapchooser_extended/scripting/include/mapchooser_extended.inc b/mapchooser_extended/scripting/include/mapchooser_extended.inc index 93ee089e..d1c3804e 100644 --- a/mapchooser_extended/scripting/include/mapchooser_extended.inc +++ b/mapchooser_extended/scripting/include/mapchooser_extended.inc @@ -122,9 +122,9 @@ native int GetMapTimeRestriction(const char[] map); // >0 = More than MaxPlayers native int GetMapPlayerRestriction(const char[] map); -// <0 = No group -// >=0 = Group _max -native int GetMapGroup(const char[] map, char[] group, int size); +// <=0 = No group +// >0 = Groups found +native int GetMapGroups(const char[] map, int[] groups, int size); // <0 = No restriction // >=0 = Group _max -> Group full diff --git a/mapchooser_extended/scripting/mapchooser_extended.sp b/mapchooser_extended/scripting/mapchooser_extended.sp index 430e6d8e..7d711f93 100644 --- a/mapchooser_extended/scripting/mapchooser_extended.sp +++ b/mapchooser_extended/scripting/mapchooser_extended.sp @@ -408,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; @@ -1659,9 +1659,28 @@ void CreateNextVote() 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; @@ -1673,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); } @@ -2177,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); @@ -2189,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) @@ -2208,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; } @@ -2433,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)) @@ -2445,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 @@ -2509,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; +}