/*
plugin_kwan_mapvote.sma
 
Abstract:
This adminmod plugin delivers a better map vote interface 5 minutes before the end of a game (mp_timelimit).
 
Introduction:
plugin_kwan_mapvote.sma is a replacement for plugin_hldsld_mapvote.sma that comes packaged with Adminmod.
As well written and robust hlds_ld style voting is, it seems that some players don't vote since they
do not realize an hlds_ld style vote is in progress, or that an hlds_ld style map vote requires too many keystrokes.
 
The command admin_vote_map seems to alleviate these problems.  admin_vote_map appears on every client until
a vote has been cast or until voting is closed, thus fixing the ignorance problem.  In addition, in order
to vote, the client simply needs only 1 keystroke to enter a vote.  However, admin_vote_map does have
a couple of drawbacks.  admin_vote_map only allows for only 1 map to vote on and does NOT autostart.
 
I present this plugin to the Adminmod community.  plugin_kwan_mapote.sma is a plugin which starts a vote
in the same format as admin_vote_map, however, a list of maps (up to 9) appears as voting options
as opposed to "1.yes 2.no" that admin_vote_map only allows.  This gives your clients a wider choice of
maps to vote on with simply 1 keystroke.
 
The list of maps are customizable and robust.
 
Instructions:
 
Usage - admin_map_vote2 - to kick off a map vote.
 
Advanced users:
If you want to autostart the vote enable admin_vote_autostart in your adminmod.cfg, also disable other auto map_voting schemes.
Place a list of maps to be voted on in your cstrike directory called map_vote2_pool.ini, one map
per line.
 
Newbies: See Compiling/installation instructions under GNU/Linux -or-
         See Compiling/installation instructions under Windows.
 
***
Compiling/installation instructions under GNU/Linux:
  -place this file in "Adminmod/scripting/myscripts".
  -execute ./compile plugin_kwan_mapvote.sma.
  -copy the binary .amx file (called plugin_kwan_mapvote.amx) into your cstrike/addons/adminmod/scripts directory.
  -open cstrike/addons/adminmod/config/plugins.ini with a text editor
  -comment out (with #) or remove the line containing plugin_hldsld_mapvote.amx
  -replace with "addons/adminmod/scrips/plugin_kwan_mapvote.amx" (without the quotes)
  -save the changes and exit the text editor
  -open cstrike/addons/adminmod/config/adminmod.cfg with a text editor
  -OPTION: if you want this vote to automatically start five minutes before the end of a game, then
          find the line containing admin_vote_autostart and ensure the value is set to 1.
  -OPTION: if you want to adjust the vote ratio for a winning map, change map_ratio to a value of your liking.
  -Create a text file in your cstrike directory called map_vote2_pool.ini and populate the file with the list of
    maps that you want in the vote list (one map per line).
  -restart your server
 
Compiling/installation instructions under Windows:
  -Get a real OS
  -See Compiling/installation instructions under GNU/Linux
***
 
Questions? Comments? Contact me at bsrslash@yahoo.com
*/
 
#include <core>
#include <string>
#include <admin>
#include <adminlib>
 
#define ACCESS_MAP_VOTE 2
#define max_options 9 // Since there are only a limited amount of number keys
#define start_vote_time 300  // Number of seconds to start map voting at the end of the round
 
new AM_VERSION_STRING[MAX_DATA_LENGTH] = "2.50.59";
new map_name[max_options][MAX_TEXT_LENGTH];
new time_remaining;
new ExtendCount;
new ExtendTime;
new auto_vote_count;
 
public HandleMapVote(WinningOption, strDummy, VoteCount, UserCount)
{
	new Text[MAX_TEXT_LENGTH];
	new ExecCommand[MAX_DATA_LENGTH];
	new MaxExtend;
	new newTimeLimit;
	new vote_ratio;
 
	vote_ratio = getvar("map_ratio");
	if (VoteCount>=vote_ratio*UserCount/100) {	
		if (WinningOption == 1) {
			if (time_remaining>start_vote_time) {
				snprintf(Text, MAX_TEXT_LENGTH, "No map change");
				typesay(Text, 10, 250, 250, 250);
				return PLUGIN_HANDLED;
			} else {
				ExtendCount++;
				MaxExtend=getvar("admin_vote_maxtend");
				if (ExtendCount<=MaxExtend || MaxExtend==0) {
					newTimeLimit=getvar("mp_timelimit");
					newTimeLimit+=ExtendTime;
					snprintf(Text, MAX_TEXT_LENGTH, "Extending current map %d minutes (%d total)", ExtendTime, newTimeLimit);
					typesay(Text, 10, 250, 250, 250);
					auto_vote_count = 0;
					snprintf(ExecCommand, MAX_DATA_LENGTH, "mp_timelimit %i", newTimeLimit);
					exec(ExecCommand);
					return PLUGIN_HANDLED;
				} else {
					snprintf(Text, MAX_TEXT_LENGTH, "No more map extending.  Following map cycle");
					typesay(Text, 10, 250, 250, 250);
					return PLUGIN_HANDLED;
				}
			}
		}
		else {
			WinningOption--;
			snprintf(Text, MAX_TEXT_LENGTH, "%s won the vote", map_name[WinningOption]);
			typesay(Text, 10, 250, 250, 250);
			set_timer("HandleMapChange", 10, 1, map_name[WinningOption]);
			return PLUGIN_HANDLED;
		}
	} else {
		new strNumber[MAX_NUMBER_LENGTH];
 
		numtostr(vote_ratio*UserCount/100,strNumber);
		snprintf(Text, MAX_TEXT_LENGTH, "Map vote succeeded, but not enough votes for change (needed %s)", strNumber);
		say(Text);
	}
	return PLUGIN_HANDLED;
}
 
public HandleMapChange(Timer, Repeat, HLUser, Parameter) {
	new map_name_str[MAX_TEXT_LENGTH];
	new ExecCommand[MAX_DATA_LENGTH];
 
	convert_string(Parameter, map_name_str, MAX_TEXT_LENGTH);
	snprintf(ExecCommand, MAX_DATA_LENGTH, "mp_timelimit %i", getvar("mp_timelimit")-(ExtendCount*ExtendTime));
	exec(ExecCommand);
	changelevel(map_name_str,4);
	return PLUGIN_HANDLED;
}
 
public start_vote2()
{
	new Text[MAX_TEXT_LENGTH];
	new i, file_lines;
	new scanline[MAX_TEXT_LENGTH];
	new num_valid_maps;
	new MAP_LIST_FILE[MAX_TEXT_LENGTH] = "map_vote2_pool.ini";
	new current[MAX_TEXT_LENGTH];
 
	if (vote_allowed()!=1) {
		selfmessage("Vote not allowed at this time.");
		return PLUGIN_CONTINUE;
	}
 
	if (fileexists(MAP_LIST_FILE)!=1) {
		selfmessage("Cannot find map pool.");
		return PLUGIN_CONTINUE;
	}
 
	file_lines=filesize(MAP_LIST_FILE,lines);
	if (file_lines>max_options) {
		snprintf(Text, MAX_TEXT_LENGTH, "Choosing first %d valid maps from %s", max_options, MAP_LIST_FILE);
		selfmessage(Text);
	}
 
	currentmap(current, MAX_TEXT_LENGTH);
	i=1;
	num_valid_maps=0;
	snprintf(map_name[num_valid_maps], MAX_TEXT_LENGTH, "No change");
	while (i<=file_lines) {
		if (num_valid_maps<max_options) {
			readfile(MAP_LIST_FILE, scanline, i, MAX_TEXT_LENGTH);
			if (valid_map(scanline) && streq(current, scanline)!=1) {
				num_valid_maps++;
				snprintf(map_name[num_valid_maps], MAX_TEXT_LENGTH, "%s", scanline);
			} else {
				if (streq(current, scanline)!=1) {
					snprintf(Text, MAX_TEXT_LENGTH, "Invalid map name in %s: %s", MAP_LIST_FILE, scanline);
					selfmessage(Text);
				}
			}	
		}
		i++;
	}
 
	if (num_valid_maps==0) {
		snprintf(Text, MAX_TEXT_LENGTH, "No valid maps found.");
		return PLUGIN_HANDLED;
	}
	new strDummy[10];
	time_remaining=timeleft(0);
	snprintf(Text, MAX_TEXT_LENGTH, "Change map to:");
	switch(num_valid_maps) {
		case 1:vote(Text, map_name[0], map_name[1], "HandleMapVote", strDummy);
		case 2:vote(Text, map_name[0], map_name[1], map_name[2], "HandleMapVote", strDummy);
		case 3:vote(Text, map_name[0], map_name[1], map_name[2], map_name[3], "HandleMapVote", strDummy);
		case 4:vote(Text, map_name[0], map_name[1], map_name[2], map_name[3], map_name[4], "HandleMapVote", strDummy);
		case 5:vote(Text, map_name[0], map_name[1], map_name[2], map_name[3], map_name[4], map_name[5], "HandleMapVote", strDummy);
		case 6:vote(Text, map_name[0], map_name[1], map_name[2], map_name[3], map_name[4], map_name[5], map_name[6], "HandleMapVote", strDummy);
		case 7:vote(Text, map_name[0], map_name[1], map_name[2], map_name[3], map_name[4], map_name[5], map_name[6], map_name[7], "HandleMapVote", strDummy);
		case 8:vote(Text, map_name[0], map_name[1], map_name[2], map_name[3], map_name[4], map_name[5], map_name[6], map_name[7], map_name[8], "HandleMapVote", strDummy);
	} 
	return PLUGIN_HANDLED;
}
 
public admin_map_vote2(HLCommand,HLData,HLUserName,UserIndex) 
{
	new Text[MAX_TEXT_LENGTH];
	new User[MAX_NAME_LENGTH];
 
	if (vote_allowed()!=1) {
		snprintf(Text, MAX_TEXT_LENGTH, "Vote not allowed at this time.");
		selfmessage(Text);
		return PLUGIN_HANDLED;
	}
	convert_string(HLUserName, User, MAX_NAME_LENGTH);
	snprintf(Text, MAX_TEXT_LENGTH, "%s used admin_map_vote2.");
	log(Text);
	start_vote2();
	return PLUGIN_HANDLED;
}
 
public auto_vote2_start() 
{
 
	if (timeleft(0)<start_vote_time && auto_vote_count==0) {
		auto_vote_count++;
		start_vote2();
	}
}
 
public plugin_init()
{
 
	new iTimer;
 
	plugin_registerinfo("Kwan's map vote","Better map voting system.", AM_VERSION_STRING);
	plugin_registercmd("admin_map_vote2", "admin_map_vote2",ACCESS_MAP_VOTE,"admin_map_vote2: Starts a vote to change the map.");
	plugin_registerhelp("admin_map_vote2", ACCESS_MAP_VOTE, "admin_map_vote2: Starts a vote to change the map.");
	ExtendTime=getvar("mp_timelimit");
	auto_vote_count = 0;
	ExtendCount = 0;
	if (getvar("admin_vote_autostart")!=0) {
		iTimer = getvar("vote_freq");
		set_timer("auto_vote2_start", iTimer, 99999);
	}
	return PLUGIN_CONTINUE;
}