/*
For Team Fortress 2

Description: Hidders are only Spys

*/

//CVARS
new Handle:CVAR_RoundTime;
new Handle:RoundTimer;

//Sounds
new String:SoundWonPath[256] = "misc/your_team_won.mp3";
new String:SoundLostPath[256] = "misc/your_team_lost.mp3";

//Vars
new countalive_team1 = 1;
new countalive_team2 = 1;

new bool:PlayerLive[MAXPLAYERS];

new PlayerTeam[MAXPLAYERS]; //Save the old Players Team

public EnableHookEvents()
{
	HookEvent("teamplay_round_start", Event_RoundStart,EventHookMode_Pre);
	HookEvent("teamplay_restart_round", Event_RoundRestart);
	HookEvent("player_death", Event_PlayerDeath);
	
	HookEvent("ctf_flag_captured", Event_Blocking,EventHookMode_Pre);
	HookEvent("controlpoint_starttouch", Event_Blocking,EventHookMode_Pre);
	HookEvent("controlpoint_initialized", Event_Blocking,EventHookMode_Pre);
	
	HookEvent("player_spawn", Event_PlayerSpawnPre, EventHookMode_Pre);	//To block Respawn
	HookEvent("player_changeclass", Event_PlayerChangeClass)
	HookEvent("player_connect", Event_PlayerConnect)
	HookEvent("player_disconnect", Event_PlayerDisconnect)
	
	ServerCommand("mp_autoteambalance 0");
}

public DisableHookEvents()
{
	UnhookEvent("teamplay_round_start", Event_RoundStart);
	UnhookEvent("teamplay_restart_round", Event_RoundRestart);
	UnhookEvent("player_death", Event_PlayerDeath);
	
	UnhookEvent("ctf_flag_captured", Event_Blocking,EventHookMode_Pre);
	UnhookEvent("controlpoint_starttouch", Event_Blocking,EventHookMode_Pre);
	UnhookEvent("controlpoint_initialized", Event_Blocking,EventHookMode_Pre);
	
	UnhookEvent("player_spawn", Event_PlayerSpawnPre, EventHookMode_Pre);
	UnhookEvent("player_changeclass", Event_PlayerChangeClass)
	UnhookEvent("player_connect", Event_PlayerConnect)
	UnhookEvent("player_disconnect", Event_PlayerDisconnect)
	
}

public GamePluginStart()
{
	//TF_LoadOffsets();
	//RegConsoleCmd("testcommand", TestCommand);
	
	//TF2 Only
	CVAR_RoundTime = CreateConVar("sm_roundtime", "4", "TF2 Only: How long have Seekers time to find Hidders. 0=Disabled else time in minutes.",FCVAR_PLUGIN);

	new String:SoundWonPathdownload[256];
	new String:SoundLostPathdownload[256];
	
	PrecacheSound(SoundWonPath, true)	
	Format(SoundWonPathdownload,gMaxLength,"sound/%s",SoundWonPath);
	AddFileToDownloadsTable(SoundWonPathdownload);
	
	PrecacheSound(SoundLostPath, true)
	Format(SoundLostPathdownload,gMaxLength,"sound/%s",SoundLostPath);
	AddFileToDownloadsTable(SoundLostPathdownload);	
	
	//Setup the flame dinstance  " sm_cvar tf_flamethrower_maxdamagedist"
	new Handle:hndl = FindConVar("tf_flamethrower_maxdamagedist");
	SetConVarInt(hndl, 150,true);	//Dont Respawn in a Round, is like CSS
}

public GameMapStart()
{
	PrecacheSound(SoundWonPath, true)	
	PrecacheSound(SoundLostPath, true)
	
	for(new i=0;i<MAXPLAYERS;i++)
	{
		PlayerLive[i] = false;
	}
}

public GameRoundStart()
{
	PrintToServer("GameRoundStart");
	new Handle:hndl = FindConVar("mp_respawnwavetime");
	SetConVarInt(hndl,1000,true);	//Dont Respawn in a Round, is like CSS
	new Float:roundtime = GetConVarFloat(CVAR_RoundTime);

	if(roundtime > 0)
	{
		RoundTimer = CreateTimer(roundtime*60,Timer_RoundRestart,0,TIMER_HNDL_CLOSE);
		PrintToChatAll("Round end after %i minutes!",GetConVarInt(CVAR_RoundTime));
		
		StartFreezeTimer(GetConVarInt(CVAR_FreezeTime));
	}
}

public Event_RoundRestart(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(MapRound >= GetConVarInt(CVAR_SwapRound) && GetConVarInt(CVAR_SwapRound) > 0)
	{
		//SwapPlayerAll();
		MapRound = 0;
	}
}

public Action:Timer_RoundRestart(Handle:timer, any:value)
{	
	if(RoundTimer)
	{
		KillTimer(RoundTimer);
		RoundTimer = INVALID_HANDLE;
		//CloseHandle(RoundTimer);
	}
	
	new client;
	//new Handle:hndl2 = FindConVar("mp_restartround");
	//SetConVarInt(hndl2, 5,true);
	ServerCommand("mp_restartround 5");
	if(countalive_team1 > 0 && countalive_team2 > 0)
	{
		for(new i=0;i<MAXPLAYERS+1;i++)
		{
			client = GetClientOfUserId(i);
			if(client > 0 && IsClientInGame(client))
			{
				if(GetClientTeam(client) == TEAM_1 || PlayerTeam[i] == TEAM_1)
					EmitSoundToAll(SoundWonPath,client,SNDCHAN_AUTO,SNDLEVEL_NORMAL,SND_NOFLAGS,SNDVOL_NORMAL,SNDPITCH_NORMAL,-1,NULL_VECTOR,NULL_VECTOR, true,0.0);
				if(GetClientTeam(client) == TEAM_2 || PlayerTeam[i] == TEAM_2)
					EmitSoundToAll(SoundLostPath,client,SNDCHAN_AUTO,SNDLEVEL_NORMAL,SND_NOFLAGS,SNDVOL_NORMAL,SNDPITCH_NORMAL,-1,NULL_VECTOR,NULL_VECTOR, true,0.0);
			}
		}		
	}
}

public Action:Timer_CheckWinningTeam(Handle:timer, any:value)
{	
	new client;
	
	countalive_team1 = 0;
	countalive_team2 = 0;
	
	
	for(new i=0;i<MAXPLAYERS+1;i++)
	{
		client = GetClientOfUserId(i);
		if(client > 0 && IsClientInGame(client))
		{
			if(PlayerLive[i])
			{
				if(GetClientTeam(client) == TEAM_1)
					countalive_team1++;
				if(GetClientTeam(client) == TEAM_2)
					countalive_team2++;
			}
		}
	}

	if(countalive_team1 == 0)
	{
		for(new i=0;i<MAXPLAYERS+1;i++)
		{
			client = GetClientOfUserId(i);
			if(client > 0 && IsClientInGame(client))
			{
				if(GetClientTeam(client) == TEAM_1 || PlayerTeam[i] == TEAM_1)
					EmitSoundToAll(SoundLostPath,client,SNDCHAN_AUTO,SNDLEVEL_NORMAL,SND_NOFLAGS,SNDVOL_NORMAL,SNDPITCH_NORMAL,-1,NULL_VECTOR,NULL_VECTOR, true,0.0);
				if(GetClientTeam(client) == TEAM_2 || PlayerTeam[i] == TEAM_2)
					EmitSoundToAll(SoundWonPath,client,SNDCHAN_AUTO,SNDLEVEL_NORMAL,SND_NOFLAGS,SNDVOL_NORMAL,SNDPITCH_NORMAL,-1,NULL_VECTOR,NULL_VECTOR, true,0.0);
			}
		}		
		//TriggerTimer(RoundTimer,true);
		ServerCommand("mp_restartround 5");
	}
	else if(countalive_team2 == 0)
	{
		for(new i=0;i<MAXPLAYERS+1;i++)
		{
			client = GetClientOfUserId(i);
			if(client > 0 && IsClientInGame(client))
			{
				if(GetClientTeam(client) == TEAM_1 || PlayerTeam[i] == TEAM_1)
					EmitSoundToAll(SoundWonPath,client,SNDCHAN_AUTO,SNDLEVEL_NORMAL,SND_NOFLAGS,SNDVOL_NORMAL,SNDPITCH_NORMAL,-1,NULL_VECTOR,NULL_VECTOR, true,0.0);
				if(GetClientTeam(client) == TEAM_2 || PlayerTeam[i] == TEAM_2)
					EmitSoundToAll(SoundLostPath,client,SNDCHAN_AUTO,SNDLEVEL_NORMAL,SND_NOFLAGS,SNDVOL_NORMAL,SNDPITCH_NORMAL,-1,NULL_VECTOR,NULL_VECTOR, true,0.0);
			}
		}	
		//TriggerTimer(RoundTimer,true);
		ServerCommand("mp_restartround 5");
	}
}

public Action:Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	new client_team = GetClientTeam(client);

	PlayerLive[GetEventInt(event, "userid")] = true;
	
	if(client_team == TEAM_SPECTATOR || client_team == TEAM_NONE)
		return Plugin_Continue;
    
   	if(!IsPlayerAlive(client))
        	return Plugin_Continue;

	if(InFreezeRound == true)
	{
		PlayerTeam[GetEventInt(event, "userid")] = client_team;
		ChangeClientTeam(client,TEAM_SPECTATOR);	//Go to spec and wait for roundend
		
		CreateTimer(1.0,Timer_CheckWinningTeam,0,TIMER_HNDL_CLOSE);
	}
	
	if(client_team == TEAM_1)
	{
		TF2_SetPlayerClass(client,TFClass_Spy)
		SetEntProp(client, Prop_Data, "m_takedamage", 2 , 1);
		PrintToChat(client,"Go and hide now!");
	}
	else if(client_team == TEAM_2)
	{
		FreezeClient(client)
		SetEntProp(client, Prop_Data, "m_takedamage", 0 , 1); //Team Blue dont get damage
		
		//Disallow Class Spy and Engineer
		if(TF2_GetPlayerClass(client) == TFClass_Spy || TF2_GetPlayerClass(client) == TFClass_Engineer)
		{
			TF2_SetPlayerClass(client,TFClass_Medic)
			PrintToChat(client,"The Class Spy and Engineer is not allowed.!");
		}
		PrintToChat(client,"You are now Seeker, wait %i seconds to find the Spys!",GetConVarInt(CVAR_FreezeTime));
	}

	return Plugin_Continue;
}

public Action:Event_PlayerSpawnPre(Handle:event, const String:name[], bool:dontBroadcast)
{
	/*new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if(AllowPlayerSpawn[client])
	{
		PrintToChat(client,"Respawn Allowed.");
		AllowPlayerSpawn[client] = false;
		return Plugin_Continue;
	}
	else
	{
		PrintToChat(client,"Respawn Blocked.");
		return Plugin_Handled;
	}*/
}

public Action:Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	//countalive_team1 = 0;
	//countalive_team2 = 0;
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	
	PlayerLive[GetEventInt(event, "userid")] = false;
	
	PlayerTeam[GetEventInt(event, "userid")] = GetClientTeam(client);
	ChangeClientTeam(client,TEAM_SPECTATOR);	//Go to spec and wait for roundend
	
	CreateTimer(1.0,Timer_CheckWinningTeam,0,TIMER_HNDL_CLOSE);
}

//Player change Class and all team player are death
//-> Restart Round
public Action:Event_PlayerChangeClass(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));

	if(PlayerLive[GetEventInt(event, "userid")] == true)
	{
		TF2_RespawnPlayer(client);
	}
	
}

public Action:Event_PlayerConnect(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client;
	
	countalive_team1 = 0;
	countalive_team2 = 0;	
	
	for(new i=0;i<MAXPLAYERS+1;i++)
	{
		client = GetClientOfUserId(i);
		if(client > 0 && IsClientInGame(client))
		{
			if(PlayerLive[i])
			{
				if(GetClientTeam(client) == TEAM_1)
					countalive_team1++;
				if(GetClientTeam(client) == TEAM_2)
					countalive_team2++;
			}
		}
	}
	
	if(countalive_team1 == 0 || countalive_team2 == 0)
	{
		PlayerLive[GetEventInt(event, "userid")] = true;
	}
}

public Action:Event_PlayerDisconnect(Handle:event, const String:name[], bool:dontBroadcast)
{
	PlayerLive[GetEventInt(event, "userid")] = false;
}

public Action:Event_Timeout(Handle:event, const String:name[], bool:dontBroadcast)
{
	new seconds = GetClientOfUserId(GetEventInt(event, "seconds"));
	if(seconds < 2)
	{
		Timer_RoundRestart(RoundTimer,0);
		return Plugin_Handled;
	}
	else
	{
		return Plugin_Continue;
	}
}

public Action:Event_Blocking(Handle:event, const String:name[], bool:dontBroadcast)
{
	return Plugin_Handled;
}	