/*
 * Public War v1.0beta (May 19th, 2002)
 * Tested with Counter-Strike 1.4
 *
 * Author: <[NN]>Soul (sefanja_severin@hotmail.com, http://nn.kicks-ass.net/)
 *
 * You can easily put your clan in one team and the rest of the players in the other team (and keep it that way).
 *
 *
 *
 * Commands:
 * admin_war <ct|t> <clantag>: Puts a clan in one team, locks the teams and restarts the map.
 * admin_war_ct <target>: Like admin_ct, but this one should be used instead during a public clan war.
 * admin_war_t <target>: Like admin_t, but this one should be used instead during a public clan war.
 * admin_war_stop: Ends a public clan war.
 *
 * IMPORTANT notes:
 * - The maximum possible amount of players during a war is 10 per team. If the team of the opponents is full
 *   (10 or more), a password is set on the server. You can edit that password further on in this script.
 * - The Admin Mod access level of ordinary players is set to 0 during a war.
 * - Players are well informed about a possible war going on: in the console as they connect, and when
 *   they are forced to join another team.
 *
 */
 
#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
 
#define ACCESS_CONSOLE 131072
#define ACCESS_WAR 8192
 
new STRING_VERSION[MAX_DATA_LENGTH] = "1.0beta";
 
 
 
// Edit these
//
new WarPass[MAX_DATA_LENGTH] = "rise";
//
// Stop editing
 
 
 
new ClanTag[MAX_DATA_LENGTH];   // Your clan tag as specified by the user in the admin_war command
new ClanTeam[MAX_DATA_LENGTH];  // The clan team as specified by the user in the admin_war command
new bool:War = false;	        // A public war is (not) going on
 
new CvarDefaultAccess;	              // Server cvar: default_access (set to "0" during war)
new CvarSvPassword[MAX_DATA_LENGTH];  // Server cvar: sv_password (set to <WarPass> during war)
new CvarMpAutoteambalance;            // Server cvar: mp_autoteambalance (set to "0" during war)
new CvarMpLimitteams;                 // Server cvar: mp_limitteams (set to "0" during war)
 
new bool:ClanMember[MAX_PLAYERS];	// Is (not) a member of the war clan
 
 
 
/* * * * * * * * * * *
 * Helper Functions  *
 * * * * * * * * * * */
 
public SetPass() {
	// Description of this function: Determines what the value of cvar sv_password should be: the warr pass or the default server pass
	// - Counts the players in the "not-war-team"
	// - If the number of those players is more or than equal to 10: put the war pass on, else: remove it
 
	new PlayerIndex;
	new MaxPlayerCount = maxplayercount();
	new PlayerCount = playercount();
	new ClanmembersCount = 0;               // Number of players on the war team
	new CurrentPass[MAX_DATA_LENGTH];       // Current value of cvar sv_password
 
	getstrvar("sv_password", CurrentPass, MAX_DATA_LENGTH);
 
	for (PlayerIndex=1; PlayerIndex <= MaxPlayerCount; PlayerIndex++) {
		if (ClanMember[PlayerIndex] == true) {
			ClanmembersCount++;
		}
	}
 
	if ( ClanmembersCount + 10 > PlayerCount && streq(CurrentPass,WarPass) ) {
		setstrvar("sv_password","none");
	} else if ( ClanmembersCount + 10 <= PlayerCount && !streq(CurrentPass,WarPass) ) {
		setstrvar("sv_password",WarPass);
	}
 
	return PLUGIN_CONTINUE;
}
 
public SelectTeam(TargetIndex) {
	// Description of this function: puts a player in the right team
	// - Retrieves the following information:
	//   o If the player is (not) a member of the war clan
	//   o The team the war clan is playing on
	//   o The team the player is playing on
	// - Based on that information the player will (not) be moved to the other team
	// - If the player is moved, he gets a clear message: Public Clan War: <clantag> vs Rest
 
	new TargetName[MAX_NAME_LENGTH];
	new iTargetID;
	new sTargetID[MAX_NUMBER_LENGTH];
	new WONID;
	new Team;
 
	new Text[MAX_TEXT_LENGTH];
 
	snprintf(Text, MAX_TEXT_LENGTH, "Public Clan War: %s vs Rest", ClanTag);
 
	if ( !playerinfo(TargetIndex, TargetName, MAX_NAME_LENGTH, iTargetID, WONID, Team) ) {
		return PLUGIN_CONTINUE;
	}
	numtostr(iTargetID,sTargetID);
 
	if (ClanMember[TargetIndex]) {
		if (ClanTeam[0] == 't') {
			if (Team != 1) {
				execclient(sTargetID, "chooseteam;menuselect 1;menuselect 2");
				messageex(sTargetID, Text, print_tty);
			}
		} else {
			if (Team == 1) {
				execclient(sTargetID, "chooseteam;menuselect 2;menuselect 3");
				messageex(sTargetID, Text, print_tty);
			}
		}
	} else {
		if (ClanTeam[0] == 't') {
			if (Team == 1) {
				execclient(sTargetID, "chooseteam;menuselect 2;menuselect 3");
				messageex(sTargetID, Text, print_tty);
			}
		} else {
			if (Team != 1) {
				execclient(sTargetID, "chooseteam;menuselect 1;menuselect 2");
				messageex(sTargetID, Text, print_tty);
			}
		}
	}
 
	return PLUGIN_CONTINUE;
}
 
public StartWar() {
	// Description of this function: starts a public clan war
	// - Compares the names of players to the clan tag as it was specified in the admin_war command
	// - If the tag exists in the player's name, he will be identified as a member of the war clan
	// - All players will be put in the right team by calling the function SelectTeam() on all players
	// - A centersay will appear: Public Clan War: <clantag> vs Rest
	// - The cvars default_access, mp_autoteambalance and mp_limitteams will be set to 0
	// - The round restarts in 10 seconds, so all players get the chance to see the message just displayed
	// - The war pass will be set if needed
 
	new TargetIndex;
	new TargetName[MAX_NAME_LENGTH];
 
	new MaxPlayerCount = maxplayercount();
	new Text[MAX_TEXT_LENGTH];
 
	for (TargetIndex=1; TargetIndex <= MaxPlayerCount; TargetIndex++) {
		if ( playerinfo(TargetIndex,TargetName,MAX_NAME_LENGTH) ) {
			if ( strcasestr(TargetName,ClanTag) != -1 ) {
				ClanMember[TargetIndex] = true;
			} else {
				ClanMember[TargetIndex] = false;
			}
		}
	}
 
	for (TargetIndex=1; TargetIndex <= MaxPlayerCount; TargetIndex++) {
		SelectTeam(TargetIndex);
	}
 
	snprintf(Text, MAX_TEXT_LENGTH, "Public Clan War^n^n%s vs Rest", ClanTag);
	centersay(Text, 10, 250,250,250);
 
	setstrvar("default_access","0");
	setstrvar("mp_autoteambalance","0");
	setstrvar("mp_limitteams","0");
	setstrvar("sv_restartround","10");
 
	War = true;
	SetPass();
 
	return PLUGIN_CONTINUE;
}
 
 
 
/* * * * * * * * * *
 * LogD Functions  *
 * * * * * * * * * */
 
public logd_checkteams(HLCommand,HLData,HLUserName,UserIndex) {
	// Description of this function: checks if every player is still in the right team
	// - Activated on round end and round start
	// - The function SelectTeam() is called for every player
 
	if (!War) {
		return PLUGIN_HANDLED;
	}
 
	new TargetIndex;
	new MaxPlayerCount = maxplayercount();
 
	for (TargetIndex=1; TargetIndex <= MaxPlayerCount; TargetIndex++) {
		SelectTeam(TargetIndex);
	}
 
	return PLUGIN_HANDLED;
}
 
 
 
/* * * * * * * * * * * *
 * Admin Mod Functions *
 * * * * * * * * * * * */
 
public admin_war_team(HLCommand,HLData,HLUserName,UserIndex) {
	// Description of this function: same as admin_t/admin_ct, but this one should be used during a war
	// - Will refuse to proceed if no war is going on: There is no war going on. Use admin_t or admin_ct instead.
	// - Echo the command used as a chat message on the server
	// - Checks which commad has been used: adminct or admin_t, and compares it to the clan team: based on this the player will (not) be identified as a clan member
	// - The function SelectTeam() will be called for the player
 
	if (!War) {
		selfmessage("There is no war going on. Use admin_t or admin_ct instead.");
		return PLUGIN_CONTINUE;
	}
 
	new Command[MAX_COMMAND_LENGTH];
	new Data[MAX_DATA_LENGTH];
	new User[MAX_NAME_LENGTH];
	new TargetIndex;
	new TargetName[MAX_NAME_LENGTH];
 
	convert_string(HLCommand,Command,MAX_NAME_LENGTH);
	convert_string(HLData,Data,MAX_NAME_LENGTH);
	convert_string(HLUserName,User,MAX_NAME_LENGTH);
 
	if ( check_user(Data) ) {
		get_username(Data, TargetName, MAX_NAME_LENGTH);
		get_userindex(TargetName, TargetIndex);
 
		if ( streq(Command,"admin_war_ct") ) {
			if (ClanTeam[0] == 't') {
				ClanMember[TargetIndex] = false;
			} else {
				ClanMember[TargetIndex] = true;
			}
		} else {
			if (ClanTeam[0] == 't') {
				ClanMember[TargetIndex] = true;
			} else {
				ClanMember[TargetIndex] = false;
			}
		}
 
		SelectTeam(TargetIndex);
		say_command(User, Command, TargetName);
	} else {
		selfmessage("Unrecognized player: ");
		selfmessage(Data);
	}
 
	return PLUGIN_HANDLED;
}
 
public admin_war(HLCommand,HLData,HLUserName,UserIndex) {
	// Description of this function: Starts a public clan war
	// - If the user specified no arguments, echo the war status to him
	// - Check the clan team and clan tag the user specified
	// - Echo the command used as a chat message
	// - Restart the round and start the war (putting players in the right teams, 1 second after restarting the round)
 
	new Command[MAX_COMMAND_LENGTH];
	new Data[MAX_DATA_LENGTH];
	new User[MAX_NAME_LENGTH];
 
	new clan_tag[MAX_DATA_LENGTH];
	new clan_team[MAX_DATA_LENGTH];
	new Text[MAX_TEXT_LENGTH];
 
	convert_string(HLCommand, Command, MAX_COMMAND_LENGTH);
	convert_string(HLData, Data, MAX_DATA_LENGTH);
	convert_string(HLUserName, User, MAX_NAME_LENGTH);
 
	if ( streq(Data,"") ) {
		if (War) {
			snprintf(Text, MAX_TEXT_LENGTH, "Public war: %s vs Rest", ClanTag);
			selfmessage(Text);
		} else {
			selfmessage("No public war going on right now.");
		}
 
		return PLUGIN_HANDLED;
	}
 
	strbreak(Data, clan_team, clan_tag, MAX_DATA_LENGTH);
 
	if ( streq(clan_team,"t") != 1 && streq(clan_team,"ct") != 1 ) {
		snprintf(Text, MAX_TEXT_LENGTH, "Unrecognized team: %s. Valid teams are t and ct.", clan_team);
		selfmessage(Text);
 
		return PLUGIN_HANDLED;
	}
 
	strcpy(ClanTag, clan_tag, MAX_DATA_LENGTH);
	strcpy(ClanTeam, clan_team, MAX_DATA_LENGTH);
 
	say_command(User, Command, Data);
 
	setstrvar("sv_restartround","1");
	set_timer("StartWar", 2, 0);
 
	return PLUGIN_HANDLED;
}
 
public admin_war_stop(HLCommand,HLData,HLUserName,UserIndex) {
	// Description of this function: Ends a public clan war
	// - Echo the command used as a chat message
	// - Restore the cvars default_access, sv_password, mp_autoteambalance and mp_limitteams to their original settings
	// - Centersay: Public clan war is over. Players can switch teams again.
 
	new Command[MAX_COMMAND_LENGTH];
	new Data[MAX_DATA_LENGTH];
	new User[MAX_NAME_LENGTH];
 
	new strNumber[MAX_NUMBER_LENGTH];
 
	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);
 
	numtostr(CvarDefaultAccess,strNumber);
	setstrvar("default_access",strNumber);
 
	setstrvar("sv_password",CvarSvPassword);
 
	numtostr(CvarMpAutoteambalance,strNumber);
	setstrvar("mp_autoteambalance",strNumber);
 
	numtostr(CvarMpLimitteams,strNumber);
	setstrvar("mp_limitteams",strNumber);
 
	War = false;
 
	centersay("Public clan war is over^n^nPlayers can switch teams again", 10, 250,250,250);
 
	return PLUGIN_HANDLED;
}
 
 
 
/* * * * * * * * * * *
 * Handle Functions  *
 * * * * * * * * * * */
 
public HandleChooseTeam(HLCommand,HLData,HLUserName,UserIndex) {
	// Description of this function: (Dis)allow players to switch teams
	// - Retrieves the following information about the player who's trying to switch teams:
	//   o Is he a clanmember?
	//   o What is the clan's team?
	//   o What is the player's current team?
	// - Based on this information, the player will (not) be allowed to switch teams (it will only be allowed if the player is in the wrong team)
 
	if ( !War || UserIndex < 1 ) {
		return PLUGIN_CONTINUE;
	}
 
	new iUserID;
	new sUserID[MAX_NUMBER_LENGTH];
	new UserName[MAX_NAME_LENGTH];
	new WONID;
	new Team;
 
	new Text[MAX_TEXT_LENGTH];
 
	if ( !playerinfo(UserIndex, UserName, MAX_NAME_LENGTH, iUserID, WONID, Team) ) {
		return PLUGIN_CONTINUE;
	}
	numtostr(iUserID,sUserID);
 
	snprintf(Text, MAX_TEXT_LENGTH, "Team change not allowed^n^n%s vs Rest", ClanTag);
 
	if (ClanMember[UserIndex]) {
		if (ClanTeam[0] == 't') {
			if (Team == 1) {
				messageex(sUserID, "Team change not allowed^n^nUse admin_war_t or admin_war_ct", print_center);
				return PLUGIN_HANDLED;
			}
		} else {
			if (Team != 1) {
				messageex(sUserID, "Team change not allowed^n^nUse admin_war_t or admin_war_ct", print_center);
				return PLUGIN_HANDLED;
			}
		}
	} else {
		if (ClanTeam[0] == 't') {
			if (Team != 1) {
				messageex(sUserID, Text, print_center);
				return PLUGIN_HANDLED;
			}
		} else {
			if (Team == 1) {
				messageex(sUserID, Text, print_center);
				return PLUGIN_HANDLED;
			}
		}
	}
 
	return PLUGIN_CONTINUE;
}
 
public plugin_connect(HLUserName,HLIP,UserIndex) {
	// Description of this function: Warns the player through his console about some war going on while he's connecting (if it really is goin on)
	// - Fired when a player connects
	// - Displays some info about the war in the player's console
	// - Checks the player's name and decides to (not) give him the status of a clan member
 
	if (!War) {
		return PLUGIN_CONTINUE;
	}
 
	new UserName[MAX_NAME_LENGTH];
	new Text[MAX_TEXT_LENGTH];
 
	consgreet("");
	consgreet("================================================================");
	consgreet(" Warning!");
	consgreet("================================================================");
	snprintf(Text, MAX_TEXT_LENGTH, "   There's a public clan war against %s going on right now.", ClanTag);
	consgreet(Text);
	consgreet("   You'll be forced to join a team.");
	consgreet("   So don't walk away now, or you'll *DIE* !");
	consgreet("================================================================");
	consgreet(" Warning!");
	consgreet("================================================================");
	consgreet("");
 
	if ( playerinfo(UserIndex, UserName, MAX_NAME_LENGTH) ) {
		if ( strcasestr(UserName,ClanTag) != -1 ) {
			ClanMember[UserIndex] = true;
		} else {
			ClanMember[UserIndex] = false;
		}
	}
 
	SetPass();
 
	return PLUGIN_CONTINUE;
}
 
public plugin_disconnect(HLUserName, UserIndex) {
	// Description of this function: When a player leaves, the slot he was in will not longer be known as a slot of a clan member
	// - Additionally the server will check what value the cvar sv_password should have: SetPass()
 
	if (!War) {
		return PLUGIN_CONTINUE;
	}
 
	ClanMember[UserIndex] = false;
	SetPass();
 
	return PLUGIN_CONTINUE;
}
 
public plugin_info(HLOldName, HLNewName, UserIndex) {
	// Description of this function: Let the server check what the value of sv_password should be
	// - Fired as players change team, name, ...
 
	if (!War) {
		return PLUGIN_CONTINUE;
	}
 
	SetPass();
 
	return PLUGIN_CONTINUE;
}
 
public plugin_init() {
	plugin_registerinfo("Public War - by <[NN]>Soul", "Your clan vs the Rest!", STRING_VERSION);
	plugin_registercmd("chooseteam", "HandleChooseTeam", ACCESS_ALL);
 
	return PLUGIN_CONTINUE;
}