//---------------------------------------------------------------------------------
// Purpose: Say to all
//---------------------------------------------------------------------------------
void SayToAll(const int colour, bool echo, const char	*fmt, ...)
{
	va_list		argptr;
	char		tempString[1024];
	player_t	server_player;
	bool		found_player = false;

	if (war_mode)
	{
		return;
	}

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;
	mrf.MakeReliable();
	mrf.RemoveAllRecipients();
	if (echo) OutputToConsole(NULL, "%s\n", tempString);

	for (int i = 1; i <= max_players; i++)
		{
		server_player.index = i;
		if (!FindPlayerByIndex(&server_player))
		{
			continue;
		}

		if (server_player.is_bot)
		{
			continue;
		}

		found_player = true;
		mrf.AddPlayer(i);

		if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
			gpManiGameType->IsGameType(MANI_GAME_CSGO)))
		{
			if (echo) OutputToConsole(&server_player, "%s\n", tempString);
		}
	}

	if (found_player)
	{
		UTIL_SayText(colour, &mrf, tempString);
	}
}
//---------------------------------------------------------------------------------
// Purpose: 
//---------------------------------------------------------------------------------
void ProcessPlayMenuSound( player_t *target_player_ptr, char *sound_name)
{
	if (!esounds) return;

	// Just do extended beep
	Vector pos = target_player_ptr->entity->GetCollideable()->GetCollisionOrigin();

	// Play the sound sound
	MRecipientFilter mrf; 
	mrf.MakeReliable();
	mrf.AddPlayer(target_player_ptr->index);
#if defined ( GAME_CSGO )
	esounds->EmitSound((IRecipientFilter &)mrf, target_player_ptr->index, CHAN_AUTO, NULL, 0, sound_name, 0.7,  0.0, 0, 0, 100, &pos);
#else
	esounds->EmitSound((IRecipientFilter &)mrf, target_player_ptr->index, CHAN_AUTO, sound_name, 0.7,  0.0, 0, 100, 0, &pos);
#endif

}
//---------------------------------------------------------------------------------
// Purpose: Say to player
//---------------------------------------------------------------------------------
void SayToPlayer(const int colour, player_t *player, const char	*fmt, ...)
{
	va_list		argptr;
	char		tempString[1024];
	player_t	recipient_player;
	
	if (war_mode)
	{
		return;
	}

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;
	mrf.MakeReliable();

	recipient_player.index = player->index;
	if (!FindPlayerByIndex(&recipient_player))
	{
		return;
	}

	if (recipient_player.is_bot)
	{
		return;
	}

	mrf.AddPlayer(player->index);
	if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
		 gpManiGameType->IsGameType(MANI_GAME_CSGO)))
	{
		OutputToConsole(player, "%s\n", tempString);
	}
//	OutputToConsole(NULL, "%s\n", tempString);

	UTIL_SayText(colour, &mrf, tempString);
}
//---------------------------------------------------------------------------------
// Purpose: Say string to single player in center of screen
//---------------------------------------------------------------------------------
void CSayToPlayer
(
player_t *player_ptr,
const char	*fmt, 
...
)
{
	va_list		argptr;
	char		tempString[1024];

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;
	mrf.MakeReliable();
	mrf.AddPlayer(player_ptr->index);

#if defined ( GAME_CSGO )
	CCSUsrMsg_TextMsg *msg = (CCSUsrMsg_TextMsg *)g_Cstrike15UsermessageHelpers.GetPrototype(CS_UM_TextMsg)->New(); // Show TextMsg type user message
	msg->set_msg_dst(4); // Center area
	// Client tries to read all 5 'params' and will crash if less
	msg->add_params(tempString);
	msg->add_params("");
	msg->add_params("");
	msg->add_params("");
	msg->add_params("");
	engine->SendUserMessage(mrf, CS_UM_TextMsg, *msg);
	delete msg;
#else
	msg_buffer = engine->UserMessageBegin( &mrf, text_message_index ); // Show TextMsg type user message

	msg_buffer->WriteByte(4); // Center area
	msg_buffer->WriteString(tempString);
	engine->MessageEnd();
#endif	
}
//---------------------------------------------------------------------------------
// Purpose: Process short cuts entered via player say
//---------------------------------------------------------------------------------
bool ProcessWebShortcuts(edict_t *pEntity, const char *say_string)
{
	for (int i = 0; i < web_shortcut_list_size; i++)
	{
		if (FStrEq(say_string, web_shortcut_list[i].shortcut))
		{
			char	substitute_url[2048];

			player_t player;

			player.entity = pEntity;
			if (!FindPlayerByEntity(&player)) return false;

			ParseSubstituteStrings(&player, web_shortcut_list[i].url_string, substitute_url);

			MRecipientFilter mrf;
			mrf.AddPlayer(player.index);
			DrawURL(&mrf, mani_version, substitute_url);
			return true;
		}
	}

	return false;
}
void RadarHackBlocker::RT_ProcessEntity ( SourceSdk::edict_t const * const pent )
{
	ClientRadarData * pData ( GetPlayerDataStructByIndex ( Helpers::IndexOfEdict ( pent ) ) );

	static MRecipientFilter filter;
	filter.RemoveAll ();

	filter.SetReliable ( false );

	if( pData->m_last_spotted_status == true )
	{
		/*
			Entity is spotted -> send approximative data to all players
		*/

		filter.AddAllPlayers ( NczPlayerManager::GetInstance ()->GetMaxIndex () );

		RT_SendApproximativeRadarUpdate ( filter, pData );
	}
	else
	{
		/*
			Entity is not spotted -> send approximative data to teammates and spectators, random for others.
		*/


		filter.AddTeam ( pData->m_team );
		filter.AddTeam ( TEAM_SPECTATOR );
		filter.AddTeam ( TEAM_NONE );

		filter.RemoveRecipient ( pData->m_origin_index );

		RT_SendApproximativeRadarUpdate ( filter, pData );

		filter.RemoveAll ();

		if( pData->m_team == TEAM_1 )
		{
			filter.AddTeam ( TEAM_2 );
		}
		else if( pData->m_team == TEAM_2 )
		{
			filter.AddTeam ( TEAM_1 );
		}
		else
		{
			return;
		}

		RT_SendRandomRadarUpdate ( filter, pData );
	}
}
//---------------------------------------------------------------------------------
// Purpose: Say string to specific teams
//---------------------------------------------------------------------------------
void SayToTeam
(
 const int colour,
bool	ct_side,
bool	t_side,
bool	spectator,
const char	*fmt, ...
)
{
	va_list		argptr;
	char		tempString[1024];

	if (war_mode)
	{
		return;
	}

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;
	player_t recipient_player;

	mrf.MakeReliable();
	mrf.RemoveAllRecipients();

	for (int i = 1; i <= max_players; i++)
	{
		recipient_player.index = i;
		if (!FindPlayerByIndex (&recipient_player))
		{
			continue;
		}

		if (recipient_player.is_bot)
		{
			continue;
		}

		if (ct_side)
		{
			if (recipient_player.team == TEAM_B)
			{
				mrf.AddPlayer(i);
			}
		}
		
		if (t_side)
		{
			if (recipient_player.team == TEAM_A)
			{
				mrf.AddPlayer(i);
			}
		}
		
		if (gpManiGameType->IsSpectatorAllowed() && spectator)
		{
			if (recipient_player.team == gpManiGameType->GetSpectatorIndex())
			{
				mrf.AddPlayer(i);
			}
		}
	}

	OutputToConsole(NULL, "%s\n", tempString);
	UTIL_SayText(colour, &mrf, tempString);
}
//---------------------------------------------------------------------------------
// Purpose: Say admin string to all
//---------------------------------------------------------------------------------
void AdminHSayToAll
(
player_t	*player,
int			anonymous,
const char	*fmt, 
...
)
{
	va_list		argptr;
	char		tempString[1024];
	char	admin_final_string[1024];
	char	non_admin_final_string[1024];
	bool	found_player = false;
	bool	found_admin = false;

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	player_t	server_player;

	if (!player)
	{
		snprintf(admin_final_string, sizeof (admin_final_string), "(CONSOLE) : %s", tempString);
		snprintf(non_admin_final_string, sizeof (non_admin_final_string), "(CONSOLE) %s", tempString);
	}
	else
	{
		snprintf(admin_final_string, sizeof (admin_final_string), "(ADMIN) %s: %s", player->name, tempString);
		snprintf(non_admin_final_string, sizeof (non_admin_final_string), "(ADMIN) %s", tempString);
	}

	OutputToConsole(NULL, "%s\n", admin_final_string);

	SplitHintString(admin_final_string, 34);
	SplitHintString(non_admin_final_string, 34);

	if (anonymous == 1)
	{
		MRecipientFilter mrfadmin;
		MRecipientFilter mrf;
		mrf.MakeReliable();
		mrfadmin.MakeReliable();

		for (int i = 1; i <= max_players; i++)
		{
			bool is_admin;

			is_admin = false;
			server_player.index = i;
			if (!FindPlayerByIndex(&server_player))
			{
				continue;
			}

			if (server_player.is_bot)
			{
				continue;
			}

			is_admin = gpManiClient->HasAccess(server_player.index, ADMIN, ADMIN_BASIC_ADMIN);
			if (is_admin)
			{
				found_admin = true;
				mrfadmin.AddPlayer(i);
//				OutputToConsole(server_player.entity, "%s\n", admin_final_string);
			}
			else
			{
				found_player = true;
				mrf.AddPlayer(i);
//				OutputToConsole(server_player.entity, "%s\n", non_admin_final_string);
			}
		}

		if (found_player)
		{
			UTIL_SayHint(&mrf, non_admin_final_string);
		}

		if (found_admin)
		{
			UTIL_SayHint(&mrfadmin, admin_final_string);
		}
	}
	else
	{
		for (int i = 1; i <= max_players; i++)
		{
			server_player.index = i;
			if (!FindPlayerByIndex(&server_player))
			{
				continue;
			}

			if (server_player.is_bot)
			{
				continue;
			}

			found_player = true;
//			OutputToConsole(server_player.entity, "%s\n", admin_final_string);
		}

		if (found_player)
		{
			MRecipientFilter mrf;
			mrf.MakeReliable();
			mrf.AddAllPlayers(max_players);

			UTIL_SayHint(&mrf, admin_final_string);
		}
	}
}
//---------------------------------------------------------------------------------
// Purpose: Say to Dead
//---------------------------------------------------------------------------------
void SayToDead(const int colour, const char	*fmt, ...)
{
	va_list		argptr;
	char		tempString[1024];
	player_t	recipient_player;
	bool		found_player = false;

	if (war_mode)
	{
		return;
	}

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;
	mrf.MakeReliable();
	mrf.RemoveAllRecipients();

	OutputToConsole(NULL, "%s\n", tempString);

	for (int i = 1; i <= max_players; i++)
	{
		recipient_player.index = i;
		if (!FindPlayerByIndex(&recipient_player))
		{
			continue;
		}

		if (recipient_player.is_bot)
		{
			continue;
		}

		// If player is spectator
		if (gpManiGameType->IsSpectatorAllowed() && 
			recipient_player.team == gpManiGameType->GetSpectatorIndex())
		{
			mrf.AddPlayer(i);
			found_player = true;
			if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
				gpManiGameType->IsGameType(MANI_GAME_CSGO)))
			{
				OutputToConsole(&recipient_player, "%s\n", tempString);
			}
			continue;
		}

		if (recipient_player.is_dead)
		{
			mrf.AddPlayer(i);
			found_player = true;
			if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
				gpManiGameType->IsGameType(MANI_GAME_CSGO)))
			{
				OutputToConsole(&recipient_player, "%s\n", tempString);
			}

			continue;
		}
	}

	if (found_player)
	{
		UTIL_SayText(colour, &mrf, tempString);
	}
}
//---------------------------------------------------------------------------------
// Purpose: Say admin string to all
//---------------------------------------------------------------------------------
void AdminCSayToAll
(
player_t	*player,
int			anonymous,
const char	*fmt, 
...
)
{
	va_list		argptr;
	char		tempString[1024];
	char	admin_final_string[2048];
	char	non_admin_final_string[2048];
	bool	found_player = false;
	bool	found_admin = false;

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	player_t	server_player;

	if (!player)
	{
		snprintf(admin_final_string, sizeof (admin_final_string), "(CONSOLE) : %s", tempString);
		snprintf(non_admin_final_string, sizeof (non_admin_final_string), "(CONSOLE) %s", tempString);
	}
	else
	{
		snprintf(admin_final_string, sizeof (admin_final_string), "(ADMIN) %s: %s", player->name, tempString);
		snprintf(non_admin_final_string, sizeof (non_admin_final_string), "(ADMIN) %s", tempString);
	}

	OutputToConsole(NULL, "%s\n", admin_final_string);

	if (anonymous == 1)
	{
		MRecipientFilter mrfadmin;
		MRecipientFilter mrf;
		mrf.MakeReliable();
		mrfadmin.MakeReliable();

		for (int i = 1; i <= max_players; i++)
		{
			bool is_admin;

			is_admin = false;
			server_player.index = i;
			if (!FindPlayerByIndex(&server_player))
			{
				continue;
			}

			if (server_player.is_bot)
			{
				continue;
			}

			is_admin = gpManiClient->HasAccess(server_player.index, ADMIN, ADMIN_BASIC_ADMIN);
			if (is_admin)
			{
				found_admin = true;
				mrfadmin.AddPlayer(i);
				if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
					  gpManiGameType->IsGameType(MANI_GAME_CSGO)))
				{
					OutputToConsole(&server_player, "%s\n", admin_final_string);
				}
			}
			else
			{
				found_player = true;
				mrf.AddPlayer(i);
				if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
					gpManiGameType->IsGameType(MANI_GAME_CSGO)))
				{
					OutputToConsole(&server_player, "%s\n", non_admin_final_string);
				}
			}
		}

		if (found_player)
		{
#if defined ( GAME_CSGO )
			CCSUsrMsg_TextMsg *msg = (CCSUsrMsg_TextMsg *)g_Cstrike15UsermessageHelpers.GetPrototype(CS_UM_TextMsg)->New(); // Show TextMsg type user message
			msg->set_msg_dst(4); // Center area
			// Client tries to read all 5 'params' and will crash if less
			msg->add_params(non_admin_final_string);
			msg->add_params("");
			msg->add_params("");
			msg->add_params("");
			msg->add_params("");
			engine->SendUserMessage(mrf, CS_UM_TextMsg, *msg);
			delete msg;
#else
			msg_buffer = engine->UserMessageBegin( &mrf, text_message_index ); // Show TextMsg type user message

			msg_buffer->WriteByte(4); // Center area
			msg_buffer->WriteString(non_admin_final_string);
			engine->MessageEnd();
#endif			
		}

		if (found_admin)
		{
#if defined ( GAME_CSGO )
			CCSUsrMsg_TextMsg *msg = (CCSUsrMsg_TextMsg *)g_Cstrike15UsermessageHelpers.GetPrototype(CS_UM_TextMsg)->New(); // Show TextMsg type user message
			msg->set_msg_dst(4); // Center area
			// Client tries to read all 5 'params' and will crash if less
			msg->add_params(admin_final_string);
			msg->add_params("");
			msg->add_params("");
			msg->add_params("");
			msg->add_params("");
			engine->SendUserMessage(mrfadmin, CS_UM_TextMsg, *msg);
			delete msg;
#else
			msg_buffer = engine->UserMessageBegin( &mrfadmin, text_message_index ); // Show TextMsg type user message

			msg_buffer->WriteByte(4); // Center area
			msg_buffer->WriteString(admin_final_string);
			engine->MessageEnd();
#endif			
		}
	}
	else
	{
		for (int i = 1; i <= max_players; i++)
		{
			server_player.index = i;
			if (!FindPlayerByIndex(&server_player))
			{
				continue;
			}

			if (server_player.is_bot)
			{
				continue;
			}

			found_player = true;
			if (!(gpManiGameType->IsGameType(MANI_GAME_CSS) ||
				gpManiGameType->IsGameType(MANI_GAME_CSGO)))
			{
				OutputToConsole(&server_player, "%s\n", admin_final_string);
			}
		}

		if (found_player)
		{
			MRecipientFilter mrf;
			mrf.MakeReliable();
			mrf.AddAllPlayers(max_players);

#if defined ( GAME_CSGO )
			CCSUsrMsg_TextMsg *msg = (CCSUsrMsg_TextMsg *)g_Cstrike15UsermessageHelpers.GetPrototype(CS_UM_TextMsg)->New(); // Show TextMsg type user message
			msg->set_msg_dst(4); // Center area
			// Client tries to read all 5 'params' and will crash if less
			msg->add_params(admin_final_string);
			msg->add_params("");
			msg->add_params("");
			msg->add_params("");
			msg->add_params("");
			engine->SendUserMessage(mrf, CS_UM_TextMsg, *msg);
			delete msg;
#else
			msg_buffer = engine->UserMessageBegin( &mrf, text_message_index ); // Show TextMsg type user message

			msg_buffer->WriteByte(4); // Center area
			msg_buffer->WriteString(admin_final_string);
			engine->MessageEnd();
#endif			
		}
	}
}
//---------------------------------------------------------------------------------
// Purpose: Say from player only to admin
//---------------------------------------------------------------------------------
void SayToAdmin
(
 const int colour,
player_t	*player,
const char	*fmt, 
...
)
{
	va_list		argptr;
	char		tempString[1024];
	char	final_string[2048];
	bool	found_player = false;
	player_t recipient_player;
	
	if (war_mode)
	{
		return;
	}

	va_start ( argptr, fmt );
	vsnprintf( tempString, sizeof(tempString), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;
	mrf.MakeReliable();
	mrf.RemoveAllRecipients();
	snprintf(final_string, sizeof (final_string), "(TO ADMIN) %s: %s", player->name, tempString);
	OutputToConsole(NULL, "%s\n", final_string);

	for (int i = 1; i <= max_players; i++)
	{
		recipient_player.index = i;
		if (!FindPlayerByIndex (&recipient_player))
		{
			continue;
		}

		if (recipient_player.is_bot)
		{
			continue;
		}

		if (player->index == i)
		{
				mrf.AddPlayer(i);
				found_player = true;
//				OutputToConsole(recipient_player.entity, "%s\n", final_string);
		}
		else
		{
			if (gpManiClient->HasAccess(recipient_player.index, ADMIN, ADMIN_BASIC_ADMIN))
			{
				// This is an admin player
				mrf.AddPlayer(i);
				found_player = true;
//				OutputToConsole(recipient_player.entity, "%s\n", final_string);
			}
		}
	}

	if (found_player)
	{
		UTIL_SayText(colour, &mrf, final_string);
	}

}
//---------------------------------------------------------------------------------
// Purpose: Show hud message for kill
//---------------------------------------------------------------------------------
static	
void ShowQuakeSound (player_t *attacker, player_t *victim, int mode, char *fmt, ...)
{
	va_list		argptr;
	char		temp_string[256];
	

	va_start ( argptr, fmt );
	vsnprintf( temp_string, sizeof(temp_string), fmt, argptr );
	va_end   ( argptr );

	MRecipientFilter mrf;

	if (mode == 1)
	{
		mrf.RemoveAllRecipients();
		mrf.MakeReliable();

		// All players must see
		for (int i = 1; i <= max_players; i++)
		{

			player_settings_t	*player_settings;
			player_t			sound_player;

			sound_player.index = i;
			if (!FindPlayerByIndex(&sound_player)) continue;
			if (sound_player.is_bot) continue;
			
			player_settings = FindPlayerSettings(&sound_player);
			if (player_settings && player_settings->quake_sounds) 
			{
				mrf.AddPlayer(sound_player.index);
			}
		}
	}
	else if (mode == 2)
	{
		player_settings_t	*player_settings;

		player_settings = FindPlayerSettings(attacker);
		if (player_settings && player_settings->quake_sounds)
		{
			mrf.AddPlayer(attacker->index);
		}

		player_settings = FindPlayerSettings(victim);
		if (player_settings && player_settings->quake_sounds)
		{
			mrf.AddPlayer(victim->index);
		}
	}
	else if (mode == 3)
	{
		player_settings_t	*player_settings;
		player_settings = FindPlayerSettings(attacker);
		if (player_settings && player_settings->quake_sounds)
		{
			// Attacker sees it.
			mrf.AddPlayer(attacker->index);
		}
	}
	else if (mode == 4)
	{
		player_settings_t	*player_settings;
		player_settings = FindPlayerSettings(victim);
		if (player_settings && player_settings->quake_sounds)
		{
			// Victim sees it.
			mrf.AddPlayer(victim->index);
		}
	}

#if defined ( GAME_CSGO )
	CCSUsrMsg_TextMsg *msg = (CCSUsrMsg_TextMsg *)g_Cstrike15UsermessageHelpers.GetPrototype(CS_UM_TextMsg)->New(); // Show TextMsg type user message
	msg->set_msg_dst(4); // Center area
	// Client tries to read all 5 'params' and will crash if less
	msg->add_params(temp_string);
	msg->add_params("");
	msg->add_params("");
	msg->add_params("");
	msg->add_params("");
	engine->SendUserMessage(mrf, CS_UM_TextMsg, *msg);
	delete msg;
#else
	msg_buffer = engine->UserMessageBegin( &mrf, text_message_index ); // Show TextMsg type user message

	msg_buffer->WriteByte(4); // Center area
	msg_buffer->WriteString(temp_string);
	engine->MessageEnd();
#endif	
}