#include <amxmodx>
#include <colorchat>
#pragma semicolon 1
#define PLUGIN "Map Manager"
#define VERSION "1.5beta"
#define AUTHOR "Mistrick"
#define SELECT_MAPS 5// MAX 8
#define VOTE_TIME 15
#define NOMINATE_MAX 3
#define NOMINATE_PLAYER_MAX 3
#define MAP_BLOCK 5
#define TASK_VOTEMENU 100
#define FILE_MAPS "addons/amxmodx/configs/maps.ini"
#define FILE_LASTMAPS "addons/amxmodx/configs/rtv/lastmaps.ini"
#define PREFIX "[GTS-INFO]"
enum _:BLOCKED_DATA
{
MAP[33],
COUNT
}
new Array:MapsArray;
new Array:NominateArray;
new g_pLoadMaps;
new g_pChangeMap;
new g_pChangeMapRounds;
new g_pShowSelects;
new g_pTimeLimitMM;
new g_pTimeStartVote;
new g_pTimeStartVoteBeforeEnd;
new g_pTimeLimit;
new g_pExendedMax;
new g_pExendedTime;
new g_pRockChange;
new g_pRockPercent;
new g_pRockDelay;
new g_iExtendedMax;
new bool:g_bBeInVote;
new bool:g_bVoteFinished;
new g_iVote[SELECT_MAPS + 1];
new g_iInMenu[SELECT_MAPS];
new g_szInMenuMapName[SELECT_MAPS][33];
new g_iTotal;
new g_iVoteTime;
new bool:g_bHasVote[33];
new g_VotedMapId = -1;
new g_iStartPlugin;
new bool:g_bStartVote;
new bool:g_bRockVote;
new bool:g_bRockVoted[33];
new g_iRockVote;
new g_iNominatedMaps[33];
new g_szCurrentMap[33];
new g_iLoadMaps;
new g_iRound;
new g_szPrefixes[][] = {"deathrun_", "speedrun_"};
new g_szSound[][] =
{
"", "fvox/one.wav", "fvox/two.wav", "fvox/three.wav", "fvox/four.wav", "fvox/five.wav",
"fvox/six.wav", "fvox/seven.wav", "fvox/eight.wav", "fvox/nine.wav", "fvox/ten.wav",
"Gman/Gman_Choose2.wav"
};
new g_iPage[33];
new g_BlockedMaps[MAP_BLOCK][BLOCKED_DATA];
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
register_dictionary("map_manager.txt");
g_pLoadMaps = register_cvar("mm_loadmapstype", "1");//0 - load all maps from maps folder, 1 - load maps from file
g_pChangeMap = register_cvar("mm_changemap", "1");//0 - after end vote, 1 - in round end, 2 - after end map
g_pChangeMapRounds = register_cvar("mm_changemap_rounds", "0");// 0 - disable
g_pTimeLimitMM = register_cvar("mm_timelimit", "30");//duration of map(minutes)
g_pTimeStartVoteBeforeEnd = register_cvar("mm_timestartvote_before_end", "2");//minutes
g_pTimeStartVote = register_cvar("mm_timestartvote", "20");//if timelimit == 0
g_pShowSelects = register_cvar("mm_showselects", "0");//0 - disable, 1 - all, 2 - self
g_pExendedTime = register_cvar("mm_extendedtime", "15");//minutes
g_pExendedMax = register_cvar("mm_extendedmap_max", "3");
g_pRockPercent = register_cvar("mm_rtv_percent", "60");
g_pRockChange = register_cvar("mm_rtv_change", "0");//0 - after vote, 1 - in round end
g_pRockDelay = register_cvar("mm_rtv_delay", "0");//minutes
g_pTimeLimit = get_cvar_pointer("mp_timelimit");
register_concmd("mm_debug", "CmdDebug", ADMIN_MAP);
register_clcmd("mm_sound", "CmdSound", ADMIN_MAP);
register_clcmd("mm_startvote", "CmdStartVote", ADMIN_MAP);
register_clcmd("say maps", "CmdMaps");
register_clcmd("say /maps", "CmdMaps");
register_clcmd("say rtv", "CmdRtv");
register_clcmd("say /rtv", "CmdRtv");
register_clcmd("say rockthevote", "CmdRtv");
register_clcmd("say nextmap", "CmdNextmap");
register_clcmd("say timeleft", "CmdTimeleft");
register_clcmd("say currentmap", "CmdCurrentMap");
register_clcmd("say", "HookSay");
register_clcmd("say_team", "HookSay");
register_clcmd("votemap", "CmdVotemap");
register_event("SendAudio", "EventRoundEnd", "a", "2=%!MRAD_terwin", "2=%!MRAD_ctwin", "2=%!MRAD_rounddraw");
register_event("TextMsg", "EventRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
register_event("30", "EventMapEnd", "a");
register_menucmd(register_menuid("Vote_Menu"), 1023, "VoteMenu_Handler");
register_menucmd(register_menuid("Maps_Menu"), 1023, "MapsMenu_Handler");
g_iStartPlugin = get_systime();
NominateArray = ArrayCreate(64);
set_task(5.0, "CheckTime", _, _, _, "b");
set_task(5.0, "SetCvar");
LoadMaps();
}
public plugin_cfg()
{
if(!file_exists(FILE_LASTMAPS) || !MAP_BLOCK) return PLUGIN_HANDLED;
new TEMP_FILE[] = "addons/amxmodx/configs/rtv/temp.ini";
new file = fopen(FILE_LASTMAPS, "rt");
new temp = fopen(TEMP_FILE, "wt");
new szBuffer[128], szMap[33], szCount[8], iCount, i = 0;
while(!feof(file))
{
fgets(file, szBuffer, charsmax(szBuffer));
parse(szBuffer, szMap, charsmax(szMap), szCount, charsmax(szCount));
if(Blocked(szMap) || !is_map_valid(szMap)) continue;
iCount = str_to_num(szCount) - 1;
if(!iCount) continue;
if(iCount > MAP_BLOCK)
{
fprintf(temp, "^"%s^" ^"%d^"^n", szMap, MAP_BLOCK);
iCount = MAP_BLOCK;
}
else
{
fprintf(temp, "^"%s^" ^"%d^"^n", szMap, iCount);
}
formatex(g_BlockedMaps[i][MAP], charsmax(g_BlockedMaps[][MAP]), szMap);
g_BlockedMaps[i][COUNT] = iCount;
i++;
if(i >= MAP_BLOCK) break;
}
fclose(file);
fclose(temp);
delete_file(FILE_LASTMAPS);
while(!rename_file(TEMP_FILE, FILE_LASTMAPS, 1)) {}
return PLUGIN_HANDLED;
}
public plugin_end()
{
if(get_pcvar_num(g_pLoadMaps) == 1 && !InFile(g_szCurrentMap))
{
return PLUGIN_HANDLED;
}
if(!dir_exists("addons/amxmodx/configs/rtv/"))
{
mkdir("addons/amxmodx/configs/rtv/");
}
new TEMP_FILE[] = "addons/amxmodx/configs/rtv/temp.ini";
new file = fopen(FILE_LASTMAPS, "rt");
new temp = fopen(TEMP_FILE, "wt");
new data[128], key[64];
while(!feof(file))
{
fgets(file, data, charsmax(data));
parse(data, key, charsmax(key));
if(equal(key, g_szCurrentMap))
{
continue;
}
else
{
fputs(temp, data);
}
}
fprintf(temp, "^"%s^" ^"%d^"^n", g_szCurrentMap, MAP_BLOCK);
fclose(file);
fclose(temp);
delete_file(FILE_LASTMAPS);
while(!rename_file(TEMP_FILE, FILE_LASTMAPS, 1)) {}
return PLUGIN_HANDLED;
}
public client_disconnect(id)
{
if(task_exists(id+TASK_VOTEMENU)) remove_task(id+TASK_VOTEMENU);
if(g_bRockVoted[id])
{
g_bRockVoted[id] = false;
g_iRockVote--;
}
if(g_iNominatedMaps[id])
{
ClearNominatedMaps(id);
}
}
public SetCvar()
{
set_pcvar_num(g_pTimeLimit, get_pcvar_num(g_pTimeLimitMM));
set_cvar_string("mapcyclefile", "");
}
public LoadMaps()
{
MapsArray = ArrayCreate(33);
g_iLoadMaps = 0;
get_mapname(g_szCurrentMap, charsmax(g_szCurrentMap));
if(file_exists(FILE_MAPS) && get_pcvar_num(g_pLoadMaps))
{
new szMapName[33];
new f = fopen(FILE_MAPS, "rt");
while(!feof(f))
{
fgets(f, szMapName, charsmax(szMapName));
trim(szMapName);
remove_quotes(szMapName);
if(!szMapName[0] || szMapName[0] == ';' || szMapName[0] == '/' && szMapName[1] == '/'
|| !ValidMap(szMapName) || InArray(szMapName) || equali(szMapName, g_szCurrentMap))
continue;
g_iLoadMaps++;
ArrayPushString(MapsArray, szMapName);
}
}
else
{
new dir, len, szFileName[64];
new DirName[] = "maps";
dir = open_dir(DirName, szFileName, charsmax(szFileName));
if(dir)
{
while(next_file(dir, szFileName, charsmax(szFileName)))
{
len = strlen(szFileName) - 4;
if(len < 0) continue;
if(equali(szFileName[len], ".bsp") && !equali(szFileName, g_szCurrentMap))
{
szFileName[len] = '^0';
g_iLoadMaps++;
ArrayPushString(MapsArray, szFileName);
}
}
close_dir(dir);
}
}
}
public CheckTime()
{
if(!g_iLoadMaps || g_bVoteFinished || g_bBeInVote) return PLUGIN_HANDLED;
static TimeLimit;
TimeLimit = get_pcvar_num(g_pTimeLimit);
if(TimeLimit > 2)
{
if(get_systime() - g_iStartPlugin >= (TimeLimit - get_pcvar_num(g_pTimeStartVoteBeforeEnd)) * 60)
{
StartVote(0);
}
}
else if(TimeLimit == 0)
{
if(get_systime() - g_iStartPlugin >= get_pcvar_num(g_pTimeStartVote) * 60)
{
StartVote(0);
}
}
else if(!g_bStartVote)
{
g_bStartVote = true;
set_task(20.0, "StartVote", 0);
}
return PLUGIN_HANDLED;
}
public EventRoundEnd()
{
g_iRound++;
new iCvar = get_pcvar_num(g_pChangeMapRounds);
if(iCvar && g_iRound >= iCvar)
{
StartVote(0);
}
if(g_bVoteFinished && get_pcvar_num(g_pChangeMap) == 1
|| g_bVoteFinished && g_bRockVote && get_pcvar_num(g_pRockChange) == 1)
{
set_task(5.0, "ChangeLevel");
}
}
public EventRestart()
{
g_iRound = 0;
}
public EventMapEnd()
{
if(g_bVoteFinished)
{
set_task(5.0, "ChangeLevel");
}
}
public CmdDebug(id, flag)
{
if(~get_user_flags(id) & flag) return PLUGIN_HANDLED;
new szMapName[64], iMax = ArraySize(NominateArray);
console_print(id, "MapList");
for(new i = 0; i < g_iLoadMaps; i++)
{
ArrayGetString(MapsArray, i, szMapName, charsmax(szMapName));
console_print(id, "%d - %s", i+1, szMapName);
}
console_print(id, "^nNominatedMaps");
for(new i = 0; i < iMax; i++)
{
ArrayGetString(NominateArray, i, szMapName, charsmax(szMapName));
console_print(id, "%d - %s", i+1, szMapName);
}
console_print(id, "^nBlockedMaps");
for(new i = 0; i < MAP_BLOCK; i++)
{
console_print(id, "%s - %d", g_BlockedMaps[i][MAP], g_BlockedMaps[i][COUNT]);
}
return PLUGIN_HANDLED;
}
public CmdSound(id, flag)
{
if(~get_user_flags(id) & flag) return PLUGIN_HANDLED;
set_task(1.0, "SoundTimer", _, _, _, "a", 10);
return PLUGIN_HANDLED;
}
public CmdVotemap(id)
{
return PLUGIN_HANDLED;
}
public CmdStartVote(id, flag)
{
if(~get_user_flags(id) & flag) return PLUGIN_HANDLED;
StartVote(id);
return PLUGIN_HANDLED;
}
public CmdMaps(id)
{
ShowMapsMenu(id, g_iPage[id] = 0);
}
public ShowMapsMenu(id, iPage)
{
if(iPage < 0) return PLUGIN_HANDLED;
new iMax = ArraySize(MapsArray);
new i = min(iPage * 8, iMax);
new iStart = i - (i % 8);
new iEnd = min(iStart + 8, iMax);
iPage = iStart / 8;
g_iPage[id] = iPage;
new szMenu[512], iLen = 0, iLen_Max = charsmax(szMenu), szMapName[32];
iLen = formatex(szMenu, iLen_Max, "\y%L \w[%d/%d]^n", id, "MM_LISTMAP", iPage + 1, ((iMax - 1) / 8) + 1);
new Keys, Item, iBlock;
for (i = iStart; i < iEnd; i++)
{
ArrayGetString(MapsArray, i, szMapName, charsmax(szMapName));
iBlock = Blocked(szMapName);
if(iBlock)
{
iLen += formatex(szMenu[iLen], iLen_Max - iLen, "^n\r%d.\d %s[\r%d\d]", ++Item, szMapName, iBlock);
}
else if(IsNominated(szMapName))
{
iLen += formatex(szMenu[iLen], iLen_Max - iLen, "^n\r%d.\d %s[\y%L\d]", ++Item, szMapName, id, "MM_MENU_NOMINATED");
}
else
{
Keys |= (1 << Item);
iLen += formatex(szMenu[iLen], iLen_Max - iLen, "^n\r%d.\w %s", ++Item, szMapName);
}
}
while(Item <= 8)
{
Item++;
iLen += formatex(szMenu[iLen], iLen_Max - iLen, "^n");
}
if (iEnd < iMax)
{
Keys |= (1 << 8)|(1 << 9);
formatex(szMenu[iLen], iLen_Max - iLen, "^n\r9.\w %L^n\r0.\w %L", id, "MM_MENU_NEXT", id, iPage ? "MM_MENU_BACK" : "MM_MENU_EXIT");
}
else
{
Keys |= (1 << 9);
formatex(szMenu[iLen], iLen_Max - iLen, "^n^n\r0.\w %L", id, iPage ? "MM_MENU_BACK" : "MM_MENU_EXIT");
}
show_menu(id, Keys, szMenu, -1, "Maps_Menu");
return PLUGIN_HANDLED;
}
public MapsMenu_Handler(id, key)
{
switch (key)
{
case 8: ShowMapsMenu(id, ++g_iPage[id]);
case 9: ShowMapsMenu(id, --g_iPage[id]);
default:
{
new szMapName[33];
ArrayGetString(MapsArray, key + g_iPage[id] * 8, szMapName, charsmax(szMapName));
NominateMap(id, szMapName);
}
}
}
public CmdRtv(id)
{
if(g_bVoteFinished || g_bBeInVote) return PLUGIN_HANDLED;
if(get_systime() - g_iStartPlugin < get_pcvar_num(g_pRockDelay) * 60)
{
new szMin[16], iMin = 1 + (get_pcvar_num(g_pRockDelay) * 60 - (get_systime() - g_iStartPlugin)) / 60;
get_ending(iMin, "MM_MIN1", "MM_MIN2", "MM_MIN3", szMin, charsmax(szMin));
ColorChat(id, GREEN, "%s^1 %L %d %L.", PREFIX, id, "MM_RTV_CANT", iMin, id, szMin);
return PLUGIN_HANDLED;
}
if(!g_bRockVoted[id])
{
g_bRockVoted[id] = true;
g_iRockVote++;
new iVote = floatround(get_playersnum() * get_pcvar_num(g_pRockPercent) / 100.0, floatround_ceil) - g_iRockVote;
if(iVote)
{
new szVote[16];
get_ending(iVote, "MM_VOTE1", "MM_VOTE2", "MM_VOTE3", szVote, charsmax(szVote));
ColorChat(id, GREEN, "%s^1 %L %d %L.", PREFIX, id, "MM_RTV_VOTE", iVote, id, szVote);
}
else
{
ColorChat(0, GREEN, "%s^1 %L.", PREFIX, LANG_PLAYER, "MM_RTV_START");
}
if(floatround(g_iRockVote * 100.0 / get_playersnum()) >= get_pcvar_num(g_pRockPercent))
{
g_bRockVote = true;
StartVote(0);
}
}
else
{
new iVote = floatround(get_playersnum() * get_pcvar_num(g_pRockPercent) / 100.0, floatround_ceil) - g_iRockVote;
new szVote[16];
get_ending(iVote, "MM_VOTE1", "MM_VOTE2", "MM_VOTE3", szVote, charsmax(szVote));
ColorChat(id, GREEN, "%s^1 %L %d %L.", PREFIX, id, "MM_RTV_VOTED", iVote, id, szVote);
}
return PLUGIN_HANDLED;
}
public CmdNextmap(id)
{
if(g_VotedMapId == -1)
{
ColorChat(0, BLUE, "^4%s^1 %L.", PREFIX, LANG_PLAYER, "MM_NEXTMAP_NONE");
}
else
{
ColorChat(0, BLUE, "^4%s^1 %L ^3%s^1.", PREFIX, LANG_PLAYER, "MM_NEXTMAP", g_szInMenuMapName[g_VotedMapId]);
}
}
public CmdTimeleft(id)
{
if (get_pcvar_float(g_pTimeLimit))
{
new a = get_timeleft();
ColorChat(0, GREEN, "%s^1 %L %d:%02d", PREFIX, LANG_PLAYER, "MM_TIME_LEFT", (a / 60), (a % 60));
}
else
{
ColorChat(0, GREEN, "%s^1 %L.", LANG_PLAYER, "MM_NO_T_LIMIT");
}
}
public CmdCurrentMap(id)
{
ColorChat(0, BLUE, "^4%s^1 %L^3 %s", PREFIX, LANG_PLAYER, "MM_CURRENT_MAP", g_szCurrentMap);
}
public HookSay(id)
{
new szText[128];
read_args(szText, charsmax(szText));
remove_quotes(szText);
trim(szText);
if(InArray(szText))
{
NominateMap(id, szText);
}
else
{
for(new i = 0; i < sizeof(g_szPrefixes); i++)
{
format(szText, charsmax(szText), "%s%s", g_szPrefixes[i], szText);
if(InArray(szText))
{
NominateMap(id, szText);
break;
}
}
}
}
public NominateMap(id, map[])
{
if(g_bVoteFinished || equali(map, g_szCurrentMap))
{
return PLUGIN_HANDLED;
}
if(g_bBeInVote)
{
ColorChat(id, GREEN, "%s^1 %L.", PREFIX, id, "MM_NOMINATE_IN_VOTE");
return PLUGIN_HANDLED;
}
if(g_iNominatedMaps[id] == NOMINATE_PLAYER_MAX)
{
ColorChat(id, GREEN, "%s^1 %L.", PREFIX, id, "MM_NOMINATE_CANT");
return PLUGIN_HANDLED;
}
if(Blocked(map))
{
ColorChat(id, GREEN, "%s^1 %L.", PREFIX, id, "MM_NOMINATE_MAP_BLOCKED");
return PLUGIN_HANDLED;
}
if(IsNominated(map))
{
ColorChat(id, GREEN, "%s^1 %L.", PREFIX, id, "MM_NOMINATED");
return PLUGIN_HANDLED;
}
new szMap[33], i;
for(i = 0; i < g_iLoadMaps; i++)
{
ArrayGetString(MapsArray, i, szMap, charsmax(szMap));
if(equali(map, szMap))
{
break;
}
}
new szText[64];
formatex(szText, charsmax(szText), "^"%d^" ^"%d^" ^"%s^"", id, i, map);
ArrayPushString(NominateArray, szText);
g_iNominatedMaps[id]++;
new szName[33];
get_user_name(id, szName, charsmax(szName));
ColorChat(0, BLUE, "^4%s^3 %s^1 %L^3 %s^1.", PREFIX, szName, id, "MM_NOMINATE_VOTED", map);
return PLUGIN_HANDLED;
}
public StartVote(id)
{
if(!g_iLoadMaps)
{
if(id) ColorChat(id, GREEN, "%s^1 %L.", PREFIX, id, "MM_DONT_HAVE_VALIDMAP");
return PLUGIN_HANDLED;
}
if(g_bBeInVote)
{
if(id) ColorChat(id, GREEN, "%s^1 %L.", PREFIX, id, "MM_IN_VOTE");
return PLUGIN_HANDLED;
}
g_bBeInVote = true;
arrayset(g_iVote, 0, SELECT_MAPS + 1);
arrayset(g_iInMenu, -1, SELECT_MAPS);
arrayset(g_bHasVote, false, 33);
g_iTotal = 0;
new Num, NomInMenu = 0, szNom[64], szID[3], szIX[6];
new iMax = 8, Limits[2];
Limits[0] = SELECT_MAPS;
Limits[1] = g_iLoadMaps - BlockedCount();
if(Limits[1] <= 0)
{
Limits[1] = 8;
ClearNomList();
}
for(new i = 0; i < sizeof(Limits); i++)
{
if(iMax > Limits[i]) iMax = Limits[i];
}
new NomMax, NomNum = ArraySize(NominateArray);
NomMax = NomNum > NOMINATE_MAX ? NOMINATE_MAX : NomNum;
for(new i = 0; i < iMax; i++)
{
if(NomInMenu < NomMax)
{
Num = random_num(0, NomNum - 1);
while(InMenu(Num, 1))
{
Num = random_num(0, NomNum - 1);
}
ArrayGetString(NominateArray, Num, szNom, charsmax(szNom));
parse(szNom, szID, charsmax(szID), szIX, charsmax(szIX), g_szInMenuMapName[i], charsmax(g_szInMenuMapName[]));
g_iInMenu[i] = str_to_num(szIX);
NomInMenu++;
}
else
{
Num = random_num(0, g_iLoadMaps - 1);
while(InMenu(Num) || IsBlocked(Num))
{
Num = random_num(0, g_iLoadMaps - 1);
}
g_iInMenu[i] = Num;
ArrayGetString(MapsArray, Num, g_szInMenuMapName[i], 32);
}
}
set_task(1.0, "SoundTimer", 1111, _, _, "a", 10);
set_task(11.0, "ShowMenu", 1112);
return PLUGIN_HANDLED;
}
public SoundTimer()
{
static Timer;
if(Timer == 0) Timer = 10;
new szSec[16];
get_ending(Timer, "MM_SEC1", "MM_SEC2", "MM_SEC3", szSec, charsmax(szSec));
set_hudmessage(50, 255, 50, -1.0, 0.8, 0, 0.0, 1.0, 0.0, 0.0, 1);
show_hudmessage(0, "%L %d %L!", LANG_PLAYER, "MM_VOTE_IN", Timer, LANG_PLAYER, szSec);
client_cmd(0, "spk %s", g_szSound[Timer]);
Timer--;
}
public ShowMenu()
{
new Players[32], pNum;
get_players(Players, pNum, "ch");
g_iVoteTime = VOTE_TIME;
set_task(1.0, "Timer", 999, _, _, "a", VOTE_TIME+1);
for(new i = 0; i < pNum; i++)
{
VoteMenu(i + TASK_VOTEMENU);
set_task(1.0, "VoteMenu", Players[i] + TASK_VOTEMENU, _, _, "a", VOTE_TIME+1);
}
client_cmd(0, "spk %s", g_szSound[11]);
}
public VoteMenu(id)
{
id -= TASK_VOTEMENU;
if(g_iVoteTime == 0)
{
show_menu(id, 0, "^n", 1);
if(task_exists(id+TASK_VOTEMENU)) remove_task(id+TASK_VOTEMENU);
return PLUGIN_HANDLED;
}
new szMenu[512], len = 0;
len = formatex(szMenu[len], charsmax(szMenu) - len, "\y%L:^n^n", id, "MM_CHOOSE_MAP");
new Key, percent, i, iMax = MapsInMenu();
for(i = 0; i < iMax; i++)
{
percent = 0;
if(g_iTotal)
{
percent = floatround(g_iVote[i]*100.0/g_iTotal);
}
if(!g_bHasVote[id])
{
len += formatex(szMenu[len], charsmax(szMenu) - len, "\r%d.\w %s\d[\r%d%%\d]^n", i + 1, g_szInMenuMapName[i], percent);
Key |= (1 << i);
}
else
{
len += formatex(szMenu[len], charsmax(szMenu) - len, "\d%s[\r%d%%\d]^n", g_szInMenuMapName[i], percent);
}
}
if(!g_bRockVote && get_pcvar_num(g_pTimeLimitMM) != 0 && g_iExtendedMax < get_pcvar_num(g_pExendedMax))
{
percent = 0;
if(g_iTotal)
{
percent = floatround(g_iVote[i]*100.0/g_iTotal);
}
if(!g_bHasVote[id])
{
len += formatex(szMenu[len], charsmax(szMenu) - len, "^n\r%d.\w %s\d[\r%d%%\d]\y[%L]^n", i + 1, g_szCurrentMap, percent, id, "MM_EXTEND");
Key |= (1 << i);
}
else
{
len += formatex(szMenu[len], charsmax(szMenu) - len, "^n\d%s[\r%d%%\d]\y[%L]^n", g_szCurrentMap, percent, id, "MM_EXTEND");
}
}
new szSec[16];
get_ending(g_iVoteTime, "MM_SEC1", "MM_SEC2", "MM_SEC3", szSec, charsmax(szSec));
len += formatex(szMenu[len], charsmax(szMenu) - len, "^n\d%L \r%d\d %L", id, "MM_REMAINED",g_iVoteTime, id, szSec);
if(!Key) Key |= (1 << 9);
show_menu(id, Key, szMenu, -1, "Vote_Menu");
return PLUGIN_HANDLED;
}
public VoteMenu_Handler(id, key)
{
if(g_bHasVote[id])
{
VoteMenu(id+TASK_VOTEMENU);
return PLUGIN_HANDLED;
}
g_iVote[key]++;
g_iTotal++;
g_bHasVote[id] = true;
new iCvar = get_pcvar_num(g_pShowSelects);
if(iCvar)
{
new szName[32];
get_user_name(id, szName, charsmax(szName));
if(key == SELECT_MAPS)
{
switch(iCvar)
{
case 1: ColorChat(0, NORMAL, "^4%s^1 ^3%s^1 %L.", PREFIX, szName, LANG_PLAYER, "MM_VOTE_EXTENDED1");
case 2: ColorChat(id, NORMAL, "^4%s^1 %L.", PREFIX, id, "MM_VOTE_EXTENDED2");
}
}
else
{
switch(iCvar)
{
case 1: ColorChat(0, NORMAL, "^4%s^1 ^3%s^1 %L ^3%s^1.", PREFIX, szName, LANG_PLAYER, "MM_VOTED1",g_szInMenuMapName[key]);
case 2: ColorChat(id, NORMAL, "^4%s^1 %L ^3%s^1.", PREFIX, id, "MM_VOTED2", g_szInMenuMapName[key]);
}
}
}
VoteMenu(id+TASK_VOTEMENU);
return PLUGIN_HANDLED;
}
public Timer()
{
g_iVoteTime--;
if(g_iVoteTime == 0)
{
show_menu(0, 0, "^n", 1);
FinishVote();
if(task_exists(999)) remove_task(999);
}
}
public FinishVote()
{
new MaxVote = 0, iMax = g_bRockVote ? MapsInMenu() : MapsInMenu() + 1;
for(new i = 1; i < iMax ; i++)
{
if(g_iVote[MaxVote] < g_iVote[i])
{
MaxVote = i;
}
}
g_bBeInVote = false;
g_bVoteFinished = true;
g_bStartVote = false;
if(MaxVote != SELECT_MAPS)
{
if(g_iTotal)
{
ColorChat(0, BLUE, "^4%s^1 %L^3 %s^1.", PREFIX, LANG_PLAYER, "MM_NEXTMAP", g_szInMenuMapName[MaxVote]);
}
else
{
MaxVote = random_num(0, MapsInMenu() - 1);
ColorChat(0, BLUE, "^4%s^1 %L^3 %s^1.", PREFIX, LANG_PLAYER, "MM_VOTE_NOBODY", g_szInMenuMapName[MaxVote]);
}
g_VotedMapId = MaxVote;
if(g_bRockVote && get_pcvar_num(g_pRockChange) == 0 || get_pcvar_num(g_pChangeMap) == 0)
{
ColorChat(0, GREEN, "%s^1 %L.", PREFIX, LANG_PLAYER, "MM_VOTE_MAPCHANGE1");
set_task(10.0, "ChangeLevel");
}
else if(g_bRockVote && get_pcvar_num(g_pRockChange) == 1 || get_pcvar_num(g_pChangeMap) == 1)
{
ColorChat(0, GREEN, "%s^1 %L.", PREFIX, LANG_PLAYER, "MM_VOTE_MAPCHANGE2");
}
}
else
{
g_bVoteFinished = false;
g_iExtendedMax++;
new szMin[16], iMin = get_pcvar_num(g_pExendedTime);
get_ending(iMin, "MM_MIN1", "MM_MIN2", "MM_MIN3", szMin, charsmax(szMin));
ColorChat(0, GREEN, "%s^1 %L %d %s.", PREFIX, LANG_PLAYER, "MM_VOTE_EXTEND", iMin, LANG_PLAYER, szMin);
set_cvar_num("mp_timelimit", get_pcvar_num(g_pTimeLimit) + iMin);
}
}
public ChangeLevel()
{
server_cmd("changelevel %s", g_szInMenuMapName[g_VotedMapId]);
}
stock bool:ValidMap(mapname[])
{
if(is_map_valid(mapname))
{
return true;
}
new len = strlen(mapname) - 4;
if(len < 0)
{
return false;
}
if(equali(mapname[len], ".bsp"))
{
mapname[len] = '^0';
if(is_map_valid(mapname))
{
return true;
}
}
return false;
}
stock bool:InMenu(Num, nom = 0)
{
if(nom)
{
new szText[48], szID[3], szIX[6], szMap[33];
ArrayGetString(NominateArray, Num, szText, charsmax(szText));
parse(szText, szID, charsmax(szID), szIX, charsmax(szIX), szMap, charsmax(szMap));
for(new i = 0; i < SELECT_MAPS && i < 8; i++)
{
if(equali(g_szInMenuMapName[i], szMap))
{
return true;
}
}
}
else
{
for(new i = 0; i < SELECT_MAPS && i < 8; i++)
{
if(Num == g_iInMenu[i])
{
return true;
}
}
}
return false;
}
stock MapsInMenu()
{
new map;
for(new i = 0; i < SELECT_MAPS; i++)
{
if(g_iInMenu[i] != -1)
{
map++;
}
}
return map;
}
stock bool:IsNominated(map[])
{
new szText[48], szMap[33], szID[3], szIX[6], iMax = ArraySize(NominateArray);
for(new i = 0; i < iMax; i++)
{
ArrayGetString(NominateArray, i, szText, charsmax(szText));
parse(szText, szID, charsmax(szID), szIX, charsmax(szIX), szMap, charsmax(szMap));
if(equali(szMap, map))
{
return true;
}
}
return false;
}
stock ClearNominatedMaps(id)
{
new szText[48], iID, szID[3];
for(new i = 0; i < ArraySize(NominateArray); i++)
{
ArrayGetString(NominateArray, i, szText, charsmax(szText));
parse(szText, szID, charsmax(szID));
iID = str_to_num(szID);
if(iID == id)
{
ArrayDeleteItem(NominateArray, i);
i--;
g_iNominatedMaps[id]--;
if(!g_iNominatedMaps[id]) break;
}
}
}
stock ClearNomList()
{
delete_file(FILE_LASTMAPS);
}
stock bool:InArray(map[])
{
new szMap[33], iMax = ArraySize(MapsArray);
for(new i = 0; i < iMax; i++)
{
ArrayGetString(MapsArray, i, szMap, charsmax(szMap));
if(equali(szMap, map))
{
return true;
}
}
return false;
}
stock bool:InFile(map[])
{
if(!file_exists(FILE_MAPS)) return false;
new szMapName[33], bool:found = false;
get_mapname(g_szCurrentMap, charsmax(g_szCurrentMap));
new f = fopen(FILE_MAPS, "rt");
while(!feof(f))
{
fgets(f, szMapName, charsmax(szMapName));
trim(szMapName);
remove_quotes(szMapName);
if(!szMapName[0] || szMapName[0] == ';' || szMapName[0] == '/' && szMapName[1] == '/')
continue;
if(equali(map, szMapName))
{
found = true;
break;
}
}
fclose(f);
return found;
}
stock BlockedCount()
{
new Count = 0;
for(new i = 0; i < MAP_BLOCK; i++)
{
if(g_BlockedMaps[i][COUNT]) Count++;
}
return Count;
}
stock Blocked(szMap[])
{
for(new i = 0; i < MAP_BLOCK; i++)
{
if(equali(g_BlockedMaps[i][MAP], szMap)) return g_BlockedMaps[i][COUNT];
}
return 0;
}
stock bool:IsBlocked(num)
{
new szMap[33];
ArrayGetString(MapsArray, num, szMap, charsmax(szMap));
for(new i = 0; i < MAP_BLOCK; i++)
{
if(equali(g_BlockedMaps[i][MAP], szMap)) return true;
}
return false;
}
stock get_ending(num, const a[], const b[], const c[], output[], lenght)
{
new num100 = num % 100, num10 = num % 10;
if(num100 >=5 && num100 <= 20 || num10 == 0 || num10 >= 5 && num10 <= 9) format(output, lenght, "%s", a);
else if(num10 == 1) format(output, lenght, "%s", b);
else if(num10 >= 2 && num10 <= 4) format(output, lenght, "%s", c);
}
Слегка подредактировал под себя плагин, но переодически падает сервер. В чем причина?