/***************************************************************************
 * plugin_ejl_hurryup.sma   version 1.6                Date: 10/26/2002
 *  Author: Eric Lidman      ejlmozart@hotmail.com
 *  Alias: Ludwig van        Upgrade: http://lidmanmusic.com/cs/plugins.html          
 *
 * LogD is required for this plugin to work. Get it at:
 *  http://logd.sourceforge.net/      make sure you turn on logging in your
 *  server.cfg  ---      log on
 *
 * This plugin is only useful on larger servers. If there are more than 9
 *  players connected, and one of the teams only has one player left, warning 
 *  messages will be given by the server to hurry up. After a warning or
 *  maybe a few warnings depending of if there are other votes going on, a
 *  vote will be put up to either have the server kill the lone player, kill
 *  the opposite team (both options ending the round of course), or just
 *  leave them alone and let them finish.
 *
 * By default it is off. But if you have plugin_matrix and matrix style
 *  jumping is enabled, admin_hurryup will be activated automatically 
 *  although for something to happen, the requiremnts above must still be
 *  met. Why, because matrix jumping games tend to drag on and on because
 *  nobody can hit anything. 
 *
 * COMMANDS:
 *
 *  admin_hurryup <1|0>      --- 1 turns it on, 0 turns it back off.
 *  admin_vote_hurryup       --- starts a vote to turn hurryup on.
 *
 * Additional: There are sounds you can use with this if you want. They
 *  are in the .zip. They are to go in the ..sounds\misc  folder. In order
 *  to get them to your clients, you need to generate .res files. Just start
 *  a new file in a text editor. The contents:
 *    sound/misc/hurryup1.wav
 *    sound/misc/hurryup2.wav
 *  Save that with the name of the map you want it to d/l the sounds on, like
 *  de_dust.res    Make sure it is a .res file and not a .txt file. Put this
 *  .res file in your maps directory.
 *
 * Oh, and one more thing. To assist in hurrying things up, there are now
 *  provisions in this plugin to make certain locations in selected maps
 *  illegal. These are points I have noticed players taking advantage of 
 *  which are really off the map (not fair). They are only accessible by
 *  noclip, teleport, and low gravity, so a normal server wouldnt have to
 *  worry about this. Actually, I am guessing that a normal server probably
 *  would not be runnng this plugin anyway. The points are listed below in
 *  the "public plugin_init()" function:     
 *
 **************************************************************************/ 
 
#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
#include <sound>
 
////////////////////////////////////////////////////////////////////////////
//
// Change these values below to whatever you want.
//
////////////////////////////////////////////////////////////////////////////
 
new bool:bHurryUpEnabled = false;
 
new roundstart = 1;
 
#define ACCESS_CONSOLE 131072
#define ROUND_START_TIME1 35
new team1_indx;
new team2_indx;
new who_die;
new dont_bother_TE = 0;
new TE_delay_time = 0;
new TE_delay_switch =0;
new map_watch =0;
new map_tolerance_dn = -20000;
new map_tolerance_up = 20000;
new map_tolerance_lt = 20000;
new map_tolerance_rt = -20000;
new map_tolerance_bk = -20000;
new map_tolerance_ft = 20000;
new ThisMap[MAX_NAME_LENGTH];
new punishments[MAX_PLAYERS];
// Access required to start a hurryup vote
#define ACCESS_VOTE_HURRYUP 1
 
// Access required to control hurryup
#define ACCESS_HURRYUP 2 // 8192
 
#define HURRYUP_VOTE_RATIO 50
 
new STRING_VERSION[MAX_DATA_LENGTH] = "2.51";
 
public plugin_init() 
{
	plugin_registerinfo("Hurry up and die Plugin", "Keeps 1 player from holding up the game.", STRING_VERSION);
	plugin_registercmd("admin_hurryup", "admin_hurryup", ACCESS_HURRYUP, "admin_hurry_up <0|1> : Turns on or off the hurry up if one player is left");
	plugin_registercmd("admin_vote_hurryup","admin_vote_hurryup",ACCESS_VOTE_HURRYUP,"admin_vote_hurryup : Starts a vote to hurry things along.");
	plugin_registercmd("pre_worldstart_te", "pre_worldstart_te", ACCESS_CONSOLE);
	exec( "logd_reg 61 admin_command pre_worldstart_te" );
	currentmap(ThisMap, MAX_NAME_LENGTH);
	if (streq(ThisMap, "fy_pool_day") == 1) {
		map_watch =1;
		map_tolerance_dn = -180;
	}
	if (streq(ThisMap, "he_pool_night") == 1) {
		map_watch =1;
		map_tolerance_dn = -180;
	}
	if (streq(ThisMap, "de_dust") == 1) {
		map_watch =1;
		map_tolerance_up = 228;
	}
	if (streq(ThisMap, "de_jeepathon10k") == 1) {
		map_watch =1;
		map_tolerance_up = 690;
	}
	if (streq(ThisMap, "cs_assault") == 1) {
		map_watch =1;
		map_tolerance_up = 630;
	}
	if (streq(ThisMap, "de_cbble") == 1) {
		map_watch =1;
		map_tolerance_up = 476;
	}
	if (streq(ThisMap, "cs_italy") == 1) {
		map_watch =1;
		map_tolerance_bk = -2093;
	}
	if (streq(ThisMap, "de_driveby") == 1) {
		map_watch =1;
		map_tolerance_up = 1100;
		map_tolerance_dn = -260;
		map_tolerance_lt = 3440;
		map_tolerance_rt = -1745;
		map_tolerance_bk = -3121;
		map_tolerance_ft = 3792;
	}
	if (streq(ThisMap, "de_driver2k") == 1) {
		map_watch =1;
		map_tolerance_up = 451;
		map_tolerance_dn = -800;
		map_tolerance_lt = 3856;
		map_tolerance_rt = -3857;
		map_tolerance_bk = -2257;
		map_tolerance_ft = 2800;
	}
	if (streq(ThisMap, "scout_map") == 1) {
		map_watch =1;
		map_tolerance_lt = 1412;
		map_tolerance_rt = -457;
		map_tolerance_bk = -392;
		map_tolerance_ft = 2312;
	}
	if (streq(ThisMap, "starwars") == 1) {
		map_watch =1;
		map_tolerance_lt = 3312;
		map_tolerance_rt = -3497;
		map_tolerance_bk = -1521;
		map_tolerance_ft = 2544;
	}
	if (streq(ThisMap, "cs_funpark") == 1) {
		map_watch =1;
		map_tolerance_lt = 2416;
		map_tolerance_rt = -3697;
		map_tolerance_bk = -3937;
		map_tolerance_ft = 2160;
		map_tolerance_dn = -1759;
	}
	set_timer("map_watch_action", 3, 99999);
	set_timer("is_that_enuf", 30, 99999);
	return PLUGIN_CONTINUE;
}
 
public plugin_connect(HLUserName, HLIP, UserIndex) 
{
	if (UserIndex >= 1 && UserIndex <= MAX_PLAYERS)
	{
		punishments[UserIndex] = 0;
	}
	return PLUGIN_CONTINUE;
}
 
public plugin_disconnect(HLUserName, UserIndex) 
{
	if (UserIndex >= 1 && UserIndex <= MAX_PLAYERS)
	{
		punishments[UserIndex] = 0;
	}
	return PLUGIN_CONTINUE;
}
 
 
 
public admin_hurryup(HLCommand, HLData, HLUserName, UserIndex){
 
	new Data[MAX_DATA_LENGTH];
	new User[MAX_NAME_LENGTH];
	new Command[MAX_COMMAND_LENGTH];
 
	convert_string(HLData, Data, MAX_DATA_LENGTH);
	convert_string(HLUserName, User, MAX_NAME_LENGTH);
	convert_string(HLCommand, Command, MAX_COMMAND_LENGTH);
 
	if (check_param(Data) == 1){
		bHurryUpEnabled = true;
	}
	else{
		bHurryUpEnabled = false;
	}
	say_command(User,Command,Data);
 
	return PLUGIN_HANDLED;
}
 
public admin_vote_hurryup(HLCommand,HLData,HLUserName,UserIndex) {
	new Command[MAX_COMMAND_LENGTH];
	new Data[MAX_DATA_LENGTH];
	new User[MAX_NAME_LENGTH];
 
	if (vote_allowed()!=1) {
		selfmessage( "Vote not allowed at this time.");
		return PLUGIN_HANDLED;
	}
 
	convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);
	convert_string(HLData,Data,MAX_DATA_LENGTH);
	convert_string(HLUserName,User,MAX_NAME_LENGTH);
	say_command(User,Command,Data);		
	HurryUpVote();
	return PLUGIN_HANDLED;
}
 
public HurryUpVote() {
	new strDummy[10];
 
	// 1 = on   2 = off  
	new VaultData;
	new vote_in_progress;	
	if(get_vaultnumdata("EJL_VOTES_ONOFF", VaultData) != 0){
		vote_in_progress = VaultData;
	} else {
		vote_in_progress = 2;
		set_vaultnumdata("EJL_VOTES_ONOFF", 2);
	}
 
	if(vote_allowed()!=1){
		selfmessage("Voting not allowed at this time.");
		return PLUGIN_HANDLED;
	}
 
	if(vote_in_progress == 1){
		selfmessage("[001] Sorry, a previous vote has not yet completed. It may be stuck.");
		log("[001] Sorry, a previous vote has not yet completed. It may be stuck.");
		return PLUGIN_HANDLED;
	}
 
	set_vaultnumdata("EJL_VOTES_ONOFF", 1);
	vote("Should we use admin_hurryup to keep games moving?", "Yes, for the good of the game!", "No thanks, let it drag on and on.", "HandleHurryVote",strDummy);
	return PLUGIN_HANDLED;
}
 
public HandleHurryVote(WinningOption,HLData,VoteCount,UserCount) {
	new Text[MAX_TEXT_LENGTH];
	new strNumber[MAX_NUMBER_LENGTH];
	new Ratio = HURRYUP_VOTE_RATIO;
	new strData[MAX_DATA_LENGTH];
	convert_string(HLData, strData,MAX_DATA_LENGTH);
 
	set_vaultnumdata("EJL_VOTES_ONOFF", 2);
 
	if (VoteCount >= Ratio*UserCount/100) {	
		if (WinningOption==1) {
			if(bHurryUpEnabled == true) {
				centersay("Vote over. 'Hurry Up'  will stay.",18,249,244,0);
			} else {
				centersay("Vote successful. Let's keep the game moving.",18,249,244,0);
				bHurryUpEnabled = true;
			}
		} else {
			if(bHurryUpEnabled == true) {
				centersay("Vote over. You dont have to hurry up anymore.",18,63,187,239);
				bHurryUpEnabled = false;
			} else {
				centersay("Vote over. Just keep letting the round draaaaag out.",18,63,187,239);
			}
		}
	} else {
		numtostr(Ratio*UserCount/100,strNumber);
		if(bHurryUpEnabled == true) {
			snprintf(Text, MAX_TEXT_LENGTH, "Not enough votes for change (needed %s)^n Keep the game moving.", strNumber);
		} else {
			snprintf(Text, MAX_TEXT_LENGTH, "Not enough votes for change (needed %s)^n Let the round drag out as loooong as you want.", strNumber);
		}
		centersay(Text,18,63,187,239);
	}
}
 
public is_that_enuf(){
 
	if ((playercount() < 9) || (dont_bother_TE == 1) || (roundstart == 1) || (bHurryUpEnabled == false) ){
		return PLUGIN_HANDLED;
	}
	if((getvar("sv_airaccelerate")==-15) || (bHurryUpEnabled == true)){
		thats_enuf();
	}
	return PLUGIN_HANDLED;
}
 
public thats_enuf(){
 
	new team1 = 0; 
	new team2 = 0;
	new i;
	new maxplayers = maxplayercount();
	new Name[MAX_NAME_LENGTH];
	new SessionID;
	new WONID;
	new AUTHID[MAX_AUTHID_LENGTH];
	new Team;
	new Dead;
	new allplaying = 0;
 
	for (i=1; i<=maxplayers; i++){
		if( playerinfo(i,Name,MAX_NAME_LENGTH,SessionID,WONID,Team,Dead,AUTHID)!=0){
			if((Team ==1) || (Team ==2)){	
				allplaying +=1;
			}
			if(Dead ==0){
				if(Team==1){
					team1 +=1;
					team1_indx =i;
				}
				if(Team==2){
					team2 +=1;
					team2_indx =i;
				}
			}
		}
	}
	if(allplaying < 9){
		return PLUGIN_HANDLED;
	}
	if(team1 == 1){
		say("<Server>  Ok, thats long enough, people are waiting!  Die already!");
		who_die=1;
		thats_enuf_vote();
		return PLUGIN_CONTINUE;
	}
	if(team2 == 1){
		say("<Server>  Ok, thats long enough, people are waiting!  Die already!");
		who_die=2;
		thats_enuf_vote();
	}
	return PLUGIN_CONTINUE;
}
 
public thats_enuf_vote() {
 
	new rand = random(2);
	switch(rand){
		case 0: playsoundall("gnyso\doverass.wav");
		case 1: playsoundall("vox\wtf.wav");
	}
	if(TE_delay_switch == 0){
		TE_delay_switch = 1;
		TE_delay_time = systemtime();
	}
	new strDummy[10];
	if (vote_allowed() != 1) {
		return PLUGIN_HANDLED;
	}
	if (systemtime()-30 < TE_delay_time){
		return PLUGIN_HANDLED;
	}
	set_vaultnumdata("EJL_VOTES_ONOFF", 1);		
	vote("OK thats enough! What should we do?", "KILL that lone player", "KILL team opposite of lone player", "Leave them alone", "Handle_TE_vote", strDummy);
	return PLUGIN_HANDLED;
}
 
 
public Handle_TE_vote(WinningOption,HLData,VoteCount,UserCount) {
 
	new Text[MAX_TEXT_LENGTH];
	new i;
	new maxplayers = maxplayercount();
	new Name[MAX_NAME_LENGTH];
	new SessionID;
	new WONID;
	new AUTHID[MAX_AUTHID_LENGTH];
	new Team;
	new Dead;
 
	set_vaultnumdata("EJL_VOTES_ONOFF", 2);
 
	if(roundstart == 1){
		return PLUGIN_HANDLED;
	}
 
	if(WinningOption == 1){
		snprintf(Text, MAX_TEXT_LENGTH, "The choice is made: ^"Kill the lone player^" won with %i / %i votes.", VoteCount, UserCount);
		say(Text);
		if(who_die == 1){	
			if( playerinfo(team1_indx,Name,MAX_NAME_LENGTH)!=0){
				slay(Name);
			}
		}else{
			if( playerinfo(team2_indx,Name,MAX_NAME_LENGTH)!=0){
				slay(Name);
			}
		}
		return PLUGIN_HANDLED;
	} 
	if(WinningOption == 2){
		snprintf(Text, MAX_TEXT_LENGTH, "The choice is made: ^"Kill team opposite of lone player^" won with %i / %i votes.", VoteCount, UserCount);
		say(Text);
		if(who_die == 1){
			for (i=1; i<=maxplayers; i++){
				if( playerinfo(i,Name,MAX_NAME_LENGTH,SessionID,WONID,Team,Dead,AUTHID)!=0){
					if((Dead ==0) && (Team == 2)){						
						slay(Name);
					}
				}
			}	
		}else{
			for (i=1; i<=maxplayers; i++){
				if( playerinfo(i,Name,MAX_NAME_LENGTH,SessionID,WONID,Team,Dead,AUTHID)!=0){
					if((Dead ==0) && (Team == 1)){
						slay(Name);
					}
				}
			}
		}
		return PLUGIN_HANDLED;		
	}
	if(WinningOption == 3){
		snprintf(Text, MAX_TEXT_LENGTH, "The choice is made: ^"Leave them alone^" won with %i / %i votes.", VoteCount, UserCount);
		say(Text);
		dont_bother_TE = 1;
		return PLUGIN_HANDLED;	
	}else{
		say("<Server> Couldnt decide?  Well I'll just leave them alone then.");
		dont_bother_TE = 1;
		return PLUGIN_HANDLED;
	}
	return PLUGIN_HANDLED;
}
 
public pre_worldstart_te(HLCommand,HLData,HLUserName,UserIndex){
 
	TE_delay_switch = 0;
	roundstart = 1;
	set_timer("roundstartover1", ROUND_START_TIME1, 0);
	dont_bother_TE = 0;	
	return PLUGIN_HANDLED;
}
 
public roundstartover1() {
	roundstart = 0;
}
 
public map_watch_action(){
	if(map_watch == 0){
		return PLUGIN_CONTINUE;
	}
	new Dead;
	new maxplayers = maxplayercount();
	new SessionID;
	new Team;
	new WONID;
	new AUTHID[MAX_AUTHID_LENGTH];
	new iC;
	new Name[MAX_NAME_LENGTH];
	new x,y,z;
	new text[MAX_TEXT_LENGTH];
 
	for (iC=1; iC<=maxplayers; iC++){
		if( playerinfo(iC,Name,MAX_NAME_LENGTH,SessionID,WONID,Team,Dead,AUTHID)!=0){
			if(Dead==0){
				get_userorigin(Name,x,y,z);
				if((x > map_tolerance_lt) || (x < map_tolerance_rt) || 
			   	       (y > map_tolerance_ft) || (y < map_tolerance_bk) ||
			   	       (z > map_tolerance_up) || (z < map_tolerance_dn) ){
					if(z != 3700){
						punish(Name,iC);
						if (streq(ThisMap, "de_dust") == 1) {
							messageex(Name, "<Message from the map, de_dust>  No sky-walking!", print_chat);							
						}
						if (streq(ThisMap, "cs_assault") == 1) {
							messageex(Name, "<Message from the map, cs_assault>  No sky-walking!", print_chat);							
						}			
						if (streq(ThisMap, "de_jeepathon10k") == 1) {
							messageex(Name, "<Message from the map, de_jeepathon10k>  No wall-whoring!", print_chat);							
						}
						messageex(Name, "<Server>  You were outside of the legal bounds.", print_chat);
						snprintf(text, MAX_TEXT_LENGTH, "MAPWATCH %i %i %i %i %i %i USER %i %i %i",map_tolerance_lt, map_tolerance_rt, map_tolerance_ft, map_tolerance_bk, map_tolerance_up, map_tolerance_dn, x , y, z);
						log(text);
						snprintf( text, MAX_TEXT_LENGTH, "%s has been punished^nbecause he went out of bounds.", Name);
						centersay (text,7,0,255,0);
					}
				}
			}
		}
	}
	return PLUGIN_CONTINUE;
}
 
public punish(Name[],iC){
	new i;
	punishments[iC] += 1;
	if(punishments[iC] > 2){
		slay(Name);
		punishments[iC] = 1;
	}else{
		for (i = 1; i <= 7; i++) {
			slap(Name);
		}
	}
}