#include < amxmodx >
#include <amxmisc>
#include <cstrike>
#include <csx>
#include <hamsandwich>
#include <sqlx>
 
new const PLUGIN[ ] = "xxxx"
new const VERSION[ ] = "xxxx"
new const AUTHOR[ ] = "xxxxx"
 
#define ADMIN ADMIN_RCON
#define MAXCLASSES 1
#define MAXLEVELS 1
#define MAXPONTUATION 1090000000 // max skillpoints per player
 
new const CLASSES[ MAXCLASSES ][ ] = {
	"GAMER"
}
 
new const LEVELS[ MAXLEVELS ] = {
	1090000000 /* high value (not reachable) */
}
 
new const SQL_TABLE[ ] = "skillpoints_v1"
new const PREFIX[ ] = "[POINTS]"
 
new Trie:IgnoredAuthID // hltv, bots and non-steam users
 
new g_iMaxPlayers
new g_szAuthID[ 32 ][ 32 ]
new g_szName[ 32 ][ 32 ]
new g_szKillerName[ 32 ]
new g_szVictimName[ 32 ]
 
new Handle:g_SqlTuple
new g_iCount
new g_iRank
 
new g_Error[ 512 ]
 
new g_pcvarHost
new g_pcvaruUser
new g_pcvarPass
new g_pcvarDB
 
new g_szPoints[ 32 ]
new g_szLevels[ 32 ]
new g_szClasses[ 32 ]
 
new g_TimeBetweenAds
 
new bool:is_user_ignored[ 33 ]
 
new g_iAdsOnChat
new g_iEnableAnnounceOnChat
new g_iEnableShowSkillPointsOnNick
new g_iHideChangeNickNotification
new g_iEnableSkillPointsCmd
new g_iEnableSkillPointsCmdRank
new g_iHideCmds
new g_iEnableWonPointsHour
new g_iWonPointsHour
new g_iLostPointsTK
new g_iLostPointsSuicide
new g_iWonPointsKill
new g_iLostPointsDeath
new g_iWonPointsHeadshot
new g_iLostPointsHeadshot
new g_iWonPointsKnife
new g_iLostPointsKnife
new g_iWonPointsGrenade
new g_iLostPointsGrenade
new g_iWonPointsTerrorists
new g_iWonPointsCounterTerrorists
new g_iLostPointsTerrorists
new g_iLostPointsCounterTerrorists
new g_iWonPointsPlanter
new g_iWonPointsPlanterExplode
new g_iWonPointsDefuser
 
new g_iPugEnd
new pcvarToggle1
new pcvarToggle2
new g_iConnectPug
new g_iDisconnectPug
 
/////////////////////////////////////
// ColorChat Stuff by ConnorMcLeod //
/////////////////////////////////////
 
#define NORMAL DontChange
#define GREEN DontChange
#define TEAM_COLOR DontChange
#define RED Red
#define BLUE Blue
#define GREY Grey
#define ColorChat client_print_color
 
enum _:Colors {
	DontChange,
	Red,
	Blue,
	Grey
}
 
stock const g_szTeamName[Colors][] = {
	"UNASSIGNED",
	"TERRORIST",
	"CT",
	"SPECTATOR"
}
 
/////////////////////////////////////
 
public plugin_init( )
{
	register_plugin( PLUGIN, VERSION, AUTHOR )
 
	register_clcmd( "say .points", "GetSkillPoints" )
	register_clcmd( "say_team .points", "GetSkillPoints" )
 
	register_clcmd( "say .rank", "SkillRank" )
	register_clcmd( "say_team .rank", "SkillRank" )
 
	register_concmd("bps_give_pugend", "points_all_pugend", ADMIN, "_")
	// register_concmd("bps_give", "CmdGivePoints", ADMIN, "<target> <skillpoints to give>" )
	// register_concmd("bps_take", "CmdTakePoints", ADMIN, "<target> <skillpoints to take>" )
 
	RegisterHam( Ham_Spawn, "player", "FwdPlayerSpawnPost", 1 )
 
	register_message( get_user_msgid( "SayText" ), "MessageSayText" )
 
	register_event( "SendAudio", "TerroristsWin", "a", "2&%!MRAD_terwin" )
	register_event( "SendAudio", "CounterTerroristsWin", "a", "2&%!MRAD_ctwin" )
 
	register_logevent( "RoundEnd", 2, "1=Round_End" )
 
	g_iAdsOnChat = register_cvar( "bps_ads", "0" )
	g_TimeBetweenAds = register_cvar( "bps_time_between_ads", "300.0" )
	g_iEnableAnnounceOnChat = register_cvar( "bps_announce_on_chat", "0" )
	g_iEnableShowSkillPointsOnNick = register_cvar( "bps_skillpoints_on_nick", "0" )
	g_iHideChangeNickNotification = register_cvar( "bps_hide_change_nick_notification", "0" )
	g_iEnableSkillPointsCmd = register_cvar( "bps_skillpoints_cmd", "1" )
	g_iEnableSkillPointsCmdRank = register_cvar( "bps_skillpoints_cmd_rank", "1" )
	g_iHideCmds = register_cvar( "bps_hide_cmd", "0" )
	g_iEnableWonPointsHour = register_cvar( "bps_enable_win_per_hour", "0" )
	g_iWonPointsHour = register_cvar( "bps_won_points_hour", "0" )
	g_iLostPointsTK = register_cvar( "bps_lost_points_tk", "0" )
	g_iLostPointsSuicide = register_cvar( "bps_lost_points_suicide", "0" )
	g_iWonPointsKill = register_cvar( "bps_won_points_kill", "0" )
	g_iLostPointsDeath = register_cvar( "bps_lost_points_kill", "0" )
	g_iWonPointsHeadshot = register_cvar( "bps_won_points_headshot", "0" )
	g_iLostPointsHeadshot = register_cvar( "bps_lost_points_headshot", "0" )
	g_iWonPointsKnife = register_cvar( "bps_won_points_knife", "0" )
	g_iLostPointsKnife = register_cvar( "bps_lost_points_knife", "0" )
	g_iWonPointsGrenade = register_cvar( "bps_won_points_grenade", "0" )
	g_iLostPointsGrenade = register_cvar( "bps_lost_points_grenade", "0" )
	g_iWonPointsTerrorists = register_cvar( "bps_won_points_ts", "0" )
	g_iWonPointsCounterTerrorists = register_cvar( "bps_won_points_cts", "0" )
	g_iLostPointsTerrorists = register_cvar( "bps_lost_points_ts", "0" )
	g_iLostPointsCounterTerrorists = register_cvar( "bps_lost_points_cts", "0" )
	g_iWonPointsPlanter = register_cvar( "bps_won_points_planter", "0" )
	g_iWonPointsPlanterExplode = register_cvar( "bps_won_points_planter_explode", "0" ) 
	g_iWonPointsDefuser = register_cvar( "bps_won_points_defuser", "0" )
	g_pcvarHost = register_cvar( "bps_sql_host", "192.168.1.51" )
	g_pcvaruUser = register_cvar( "bps_sql_user", "xxxx" )
	g_pcvarPass = register_cvar( "bps_sql_pass", "xxxxxxxxxxx" )
	g_pcvarDB = register_cvar( "bps_sql_db", "SkillPoints" )
 
	pcvarToggle1 = register_cvar("pug_leave_points", "1")
	pcvarToggle2 = register_cvar("round_save_points", "1")
	g_iPugEnd = register_cvar( "bps_won_points_pugend", "10" )
	g_iConnectPug = register_cvar( "bps_won_points_connect", "10" )
	g_iDisconnectPug = register_cvar( "bps_won_points_disconnect", "20" )
 
	g_iMaxPlayers = get_maxplayers( )
 
	IgnoredAuthID = TrieCreate( )
	TrieSetCell( IgnoredAuthID, "VALVE_ID_LAN", 1 )
	TrieSetCell( IgnoredAuthID, "VALVE_ID_PENDING", 1 )
	TrieSetCell( IgnoredAuthID, "STEAM_ID_LAN", 1 )
	TrieSetCell( IgnoredAuthID, "STEAM_ID_PENDING", 1 )
	TrieSetCell( IgnoredAuthID, "BOT", 1 )
	TrieSetCell( IgnoredAuthID, "HLTV", 1 )
 
	set_task( 0.1, "SqlInit" )
}
 
public plugin_natives( )
{
	register_library( "skillpoints" )
 
	register_native( "skillpoints", "_skillpoints" )
}
 
 
public _skillpoints( plugin, params )
{
	if( params != 1 )
		return PLUGIN_CONTINUE
 
	new id = get_param( 1 )
	if( !id )
		return PLUGIN_CONTINUE
 
	return g_szPoints[ id ]
}
 
public plugin_cfg( )
{
	if( get_pcvar_num( g_iAdsOnChat ) > 0 )
		set_task( get_pcvar_float( g_TimeBetweenAds ), "AdvertisementCmdMySkill" )
}
 
public SqlInit( )
{
	new szHost[ 32 ]
	new szUser[ 32 ]
	new szPass[ 32 ]
	new szDB[ 32 ]
 
	get_pcvar_string( g_pcvarHost, szHost, charsmax( szHost ) )
	get_pcvar_string( g_pcvaruUser, szUser, charsmax( szUser ) )
	get_pcvar_string( g_pcvarPass, szPass, charsmax( szPass ) )
	get_pcvar_string( g_pcvarDB, szDB, charsmax( szDB ) )
 
	g_SqlTuple = SQL_MakeDbTuple( szHost, szUser, szPass, szDB )
 
	new ErrorCode
	new Handle:SqlConnection = SQL_Connect( g_SqlTuple, ErrorCode, g_Error, charsmax( g_Error ) )
 
	if( SqlConnection == Empty_Handle )
		set_fail_state( g_Error )
 
	new Handle:Queries
	Queries = SQL_PrepareQuery( SqlConnection, "CREATE TABLE IF NOT EXISTS %s ( authid VARCHAR( 32 ) PRIMARY KEY, nick VARCHAR( 32 ), skillpoints INT( 7 ), level INT( 2 ) )", SQL_TABLE )
 
	if( !SQL_Execute( Queries ) )
	{
		SQL_QueryError( Queries, g_Error, charsmax( g_Error ) )
		set_fail_state( g_Error )
	}
 
	SQL_FreeHandle( Queries )
	SQL_FreeHandle( SqlConnection ) 
}
 
public plugin_end( )
{
	SQL_FreeHandle( g_SqlTuple )
}
 
public client_authorized( id )
{
	get_user_authid( id , g_szAuthID[ id ], charsmax( g_szAuthID[ ] ) )
	get_user_name( id, g_szName[ id ], charsmax( g_szName[ ] ) )
 
	replace_all( g_szName[ id ], charsmax( g_szName[ ] ), "'", "*" )
	replace_all( g_szName[ id ], charsmax( g_szName[ ] ), "^"", "*" )
	replace_all( g_szName[ id ], charsmax( g_szName[ ] ), "`", "*" )
	replace_all( g_szName[ id ], charsmax( g_szName[ ] ), "´", "*" )
 
	if( TrieKeyExists( IgnoredAuthID, g_szAuthID[ id ] ) )
		is_user_ignored[ id ] = true
 
	else
		is_user_ignored[ id ] = false
 
	if( is_user_ignored[ id ] )
		return PLUGIN_HANDLED_MAIN
 
	g_szPoints[ id ] = 0
	g_szLevels[ id ] = 0
	g_szClasses[ id ] = 0
 
	LoadPoints( id )
 
	if( get_pcvar_num( g_iEnableWonPointsHour ) > 0 && get_pcvar_num( g_iWonPointsHour ) > 0 )
		set_task( 3600.0, "GiveSkillPointsHour", id, _, _, "b" )
 
	return PLUGIN_CONTINUE
}
 
public client_putinserver(id)
{
	if( get_pcvar_num( pcvarToggle1 ) > 0 )
	{
		g_szPoints[ id ] += get_pcvar_num( g_iConnectPug )
	}
	CheckLevelAndSave(id)
 
	return PLUGIN_CONTINUE
}
 
public client_disconnect(id)
{
	if( get_pcvar_num( pcvarToggle1 ) > 0 )
	{
		g_szPoints[ id ] -= get_pcvar_num( g_iDisconnectPug )
	}
	CheckLevelAndSave(id)
 
	return PLUGIN_CONTINUE
}
 
public GiveSkillPointsHour( id )
{
	g_szPoints[ id ] += get_pcvar_num( g_iWonPointsHour )
 
	if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
		ColorChat( id, GREEN, "%s^1 You earned %i point%s for playing more one hour", PREFIX, get_pcvar_num( g_iWonPointsHour ), get_pcvar_num( g_iWonPointsHour ) > 1 ? "s" : "" )
}
 
public client_death( killer, victim, wpnindex, hitplace, TK )
{	
	if( is_user_ignored[ killer ] )
		return PLUGIN_HANDLED_MAIN
 
	get_user_name( killer, g_szKillerName, charsmax( g_szKillerName ) )
	get_user_name( victim, g_szVictimName, charsmax( g_szVictimName ) )
 
	if( TK == 1 )
	{
		g_szPoints[ killer ] -= get_pcvar_num( g_iLostPointsTK )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iLostPointsTK ) > 0 )
			ColorChat( killer, GREEN, "%s^1 You have lost^3 %i^1 point%s by killing a teammate", PREFIX, get_pcvar_num( g_iLostPointsTK ), get_pcvar_num( g_iLostPointsTK ) > 1 ? "s" : ""  )
	}
 
	if( killer == victim )
	{
		g_szPoints[ killer ] -= get_pcvar_num( g_iLostPointsSuicide )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iLostPointsSuicide ) > 0 )
			ColorChat( killer, GREEN, "%s^1 You have lost^3 %i^1 point%s for committing suicide", PREFIX, get_pcvar_num( g_iLostPointsSuicide ), get_pcvar_num( g_iLostPointsSuicide ) > 1 ? "s" : ""  )
	}
 
	if( killer != victim && ( 1 <= killer <= g_iMaxPlayers ) && ( 1 <= victim <= g_iMaxPlayers ) && !( hitplace == HIT_HEAD ) && !( wpnindex == CSW_KNIFE ) && !( wpnindex == CSW_HEGRENADE ) && TK == 0 )
	{
		g_szPoints[ killer ] += get_pcvar_num( g_iWonPointsKill )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iWonPointsKill ) > 0 )
			ColorChat( killer, GREEN, "%s^1 You earned^3 %i^1 point%s by killing %s", PREFIX, get_pcvar_num( g_iWonPointsKill ), get_pcvar_num( g_iWonPointsKill ) > 1 ? "s" : "", g_szVictimName )
 
		if( !is_user_ignored[ victim ] )
		{
			g_szPoints[ victim ] -= get_pcvar_num( g_iLostPointsDeath )
 
			if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iLostPointsDeath ) > 0 )
				ColorChat( victim, GREEN, "%s^1 You have lost^3 %i^1 point%s for dying", PREFIX, get_pcvar_num( g_iLostPointsDeath ), get_pcvar_num( g_iLostPointsDeath ) > 1 ? "s" : "" )
		}
	}
 
	if( hitplace == HIT_HEAD && wpnindex != CSW_KNIFE && TK == 0 )
	{
		g_szPoints[ killer ] += get_pcvar_num( g_iWonPointsHeadshot )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iWonPointsHeadshot ) > 0 )
			ColorChat( killer, GREEN, "%s^1 You earned^3 %i^1 point%s by killing %s with a headshot", PREFIX, get_pcvar_num( g_iWonPointsHeadshot ), get_pcvar_num( g_iWonPointsHeadshot ) > 1 ? "s" : "" ,g_szVictimName )
 
		if( !is_user_ignored[ victim ] )
		{
			g_szPoints[ victim ] -= get_pcvar_num( g_iLostPointsHeadshot )
 
			if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iLostPointsHeadshot ) > 0 )
				ColorChat( victim, GREEN, "%s^1 You have lost^3 %i^1 point%s for dying with a headshot", PREFIX, get_pcvar_num( g_iLostPointsHeadshot ), get_pcvar_num( g_iLostPointsHeadshot ) > 1 ? "s" : "" )
		}
	}
 
	if( wpnindex == CSW_KNIFE && TK == 0 )
	{
		g_szPoints[ killer ] += get_pcvar_num( g_iWonPointsKnife )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iWonPointsKnife ) > 0 )
			ColorChat( killer, GREEN, "%s^1 You earned^3 %i^1 point%s by killing %s with knife", PREFIX, get_pcvar_num( g_iWonPointsKnife ), get_pcvar_num( g_iWonPointsKnife ) > 1 ? "s" : "" ,g_szVictimName )
 
		if( !is_user_ignored[ victim ] )
		{
			g_szPoints[ victim ] -= get_pcvar_num( g_iLostPointsKnife )
 
			if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iLostPointsKnife ) > 0 )
				ColorChat( victim, GREEN, "%s^1 You have lost^3 %i^1 point%s for dying with knife", PREFIX, get_pcvar_num( g_iLostPointsKnife ), get_pcvar_num( g_iLostPointsKnife ) > 1 ? "s" : "" )
		}
	}
 
	if( wpnindex == CSW_HEGRENADE && killer != victim && TK == 0 )
	{
		g_szPoints[ killer ] += get_pcvar_num( g_iWonPointsGrenade )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iWonPointsGrenade ) > 0 )
			ColorChat( killer, GREEN, "%s^1 You earned^3 %i^1 point%s by killing %s with a grenade", PREFIX, get_pcvar_num( g_iWonPointsGrenade ), get_pcvar_num( g_iWonPointsGrenade ) > 1 ? "s" : "" ,g_szVictimName )
 
		if( !is_user_ignored[ victim ] )
		{
			g_szPoints[ victim ] -= get_pcvar_num( g_iLostPointsGrenade )
 
			if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 && get_pcvar_num( g_iLostPointsGrenade ) > 0 )
				ColorChat( victim, GREEN, "%s^1 You have lost^3 %i^1 point%s for dying with a grenade", PREFIX, get_pcvar_num( g_iLostPointsGrenade ), get_pcvar_num( g_iLostPointsGrenade ) > 1 ? "s" : "" )
		}
	}
 
	return PLUGIN_CONTINUE
}
 
public TerroristsWin( )
{
	new players[ 32 ]
	new num
	new i
 
	get_players( players, num, "ch" )
 
	for( --num; num >= 0; num-- )
	{
		i = players[ num ]
 
		if( !is_user_ignored[ i ] )
		{
			switch( cs_get_user_team( i ) )
			{
				case( CS_TEAM_T ):
				{
					if( get_pcvar_num( g_iWonPointsTerrorists ) > 0 )
					{
						g_szPoints[ i ] += get_pcvar_num( g_iWonPointsTerrorists )
 
						if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
							ColorChat( i, GREEN, "%s^1 Your team^3 (T)^1 have won^3 %i^1 point%s for winning the round", PREFIX, get_pcvar_num( g_iWonPointsTerrorists ), get_pcvar_num( g_iWonPointsTerrorists ) > 1 ? "s" : "" )
					}
				}
 
				case( CS_TEAM_CT ):
				{
					if( get_pcvar_num( g_iLostPointsCounterTerrorists ) > 0 )
					{
						g_szPoints[ i ] -= get_pcvar_num( g_iLostPointsCounterTerrorists )
 
						if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
							ColorChat( i, GREEN, "%s^1 Your team^3 (CT)^1 have lost^3 %i^1 point%s for losing the round", PREFIX, get_pcvar_num( g_iLostPointsCounterTerrorists ), get_pcvar_num( g_iLostPointsCounterTerrorists ) > 1 ? "s" : "" )
					}
				}
			}
		}
	}
}
 
public CounterTerroristsWin( )
{
	new players[ 32 ]
	new num
	new i
 
	get_players( players, num, "ch" )
 
	for( --num; num >= 0; num-- )
	{
		i = players[ num ]
 
		if( !is_user_ignored[ i ] )
		{
			switch( cs_get_user_team( i ) )
			{
				case( CS_TEAM_T ):
				{
					if( get_pcvar_num( g_iLostPointsTerrorists ) > 0 )
					{
						g_szPoints[ i ] -= get_pcvar_num( g_iLostPointsTerrorists )
 
						if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
							ColorChat( i, GREEN, "%s^1 Your team^3 (T)^1 have lost^3 %i^1 point%s for losing the round", PREFIX, get_pcvar_num( g_iLostPointsTerrorists ), get_pcvar_num( g_iLostPointsTerrorists ) > 1 ? "s" : "" )
					}
				}
 
				case( CS_TEAM_CT ):
				{
					if( get_pcvar_num( g_iWonPointsCounterTerrorists ) > 0 )
					{
						g_szPoints[ i ] += get_pcvar_num( g_iWonPointsCounterTerrorists )
 
						if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
							ColorChat( i, GREEN, "%s^1 Your team^3 (CT)^1 have won^3 %i^1 point%s for winning the round", PREFIX, get_pcvar_num( g_iWonPointsCounterTerrorists ), get_pcvar_num( g_iWonPointsCounterTerrorists ) > 1 ? "s" : "" )
					}
				}
			}
		}
	}
}
 
public points_all_pugend( id, level, cid )
{
	if ( !cmd_access( id, level, cid, 1 ) ) return PLUGIN_HANDLED
 
	new players[ 32 ]
	new num
	new i
 
	get_players( players, num, "ch" )
 
	for( --num; num >= 0; num-- )
	{
		i = players[ num ]
 
		if( !is_user_ignored[ i ] )
		{
			switch( cs_get_user_team( i ) )
			{
				case( CS_TEAM_T ):
				{
					if( get_pcvar_num( g_iPugEnd ) > 0 )
					{
						g_szPoints[ i ] += get_pcvar_num( g_iPugEnd )
 
						if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
							ColorChat( i, GREEN, "%s^1 Your team^3 (T)^1 have lost^3 %i^1 point%s for losing the round", PREFIX, get_pcvar_num( g_iLostPointsTerrorists ), get_pcvar_num( g_iLostPointsTerrorists ) > 1 ? "s" : "" )
					}
				}
 
				case( CS_TEAM_CT ):
				{
					if( get_pcvar_num( g_iPugEnd ) > 0 )
					{
						g_szPoints[ i ] += get_pcvar_num( g_iPugEnd )
 
						if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
							ColorChat( i, GREEN, "%s^1 Your team^3 (CT)^1 have won^3 %i^1 point%s for winning the round", PREFIX, get_pcvar_num( g_iWonPointsCounterTerrorists ), get_pcvar_num( g_iWonPointsCounterTerrorists ) > 1 ? "s" : "" )
					}
				}
			}
		}
	}
	SavePointsAtRoundEnd()
 
	return PLUGIN_CONTINUE
}
 
public bomb_planted( planter )
{
	if( !is_user_ignored[ planter ] && get_pcvar_num( g_iWonPointsPlanter ) > 0 )
	{
		g_szPoints[ planter ] += get_pcvar_num( g_iWonPointsPlanter )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
			ColorChat( planter, GREEN, "%s^1 You earned^3 %i^1 point%s for planting the bomb", PREFIX, get_pcvar_num( g_iWonPointsPlanter ), get_pcvar_num( g_iWonPointsPlanter ) > 1 ? "s" : "" )
	}
}
 
public bomb_explode( planter, defuser )
{
	if( !is_user_ignored[ planter ] && get_pcvar_num( g_iWonPointsPlanterExplode ) > 0 )
	{
		g_szPoints[ planter ] += get_pcvar_num( g_iWonPointsPlanterExplode )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
			ColorChat( planter, GREEN, "%s^1 You earned^3 %i^1 point%s with the bomb explosion", PREFIX, get_pcvar_num( g_iWonPointsPlanterExplode ), get_pcvar_num( g_iWonPointsPlanterExplode ) > 1 ? "s" : "" )
	}
}
 
public bomb_defused( defuser )
{
	if( !is_user_ignored[ defuser ] && get_pcvar_num( g_iWonPointsDefuser ) > 0 )
	{
		g_szPoints[ defuser ] += get_pcvar_num( g_iWonPointsDefuser )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
			ColorChat( defuser, GREEN, "%s^1 You earned^3 %i^1 point%s for disarming the bomb", PREFIX, get_pcvar_num( g_iWonPointsDefuser ), get_pcvar_num( g_iWonPointsDefuser ) > 1 ? "s" : "" )
	}
}
 
public RoundEnd( )
{
	if( get_pcvar_num( pcvarToggle2 ) > 0 )
	{
		set_task( 0.5, "SavePointsAtRoundEnd" )
	}
}
 
public SavePointsAtRoundEnd( )
{
	new players[ 32 ]
	new num
	new i
 
	get_players( players, num, "ch" )
 
	for( --num; num >= 0; num-- )
	{
		i = players[ num ]
 
		if( !is_user_ignored[ i ] )
			CheckLevelAndSave( i )
	}
}
 
public CheckLevelAndSave( id )
{
	while( g_szPoints[ id ] >= LEVELS[ g_szLevels[ id ] ] )
	{
		g_szLevels[ id ] += 1
		g_szClasses[ id ] += 1
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0 )
		{
			new szName[ 32 ]
			get_user_name( id, szName, charsmax( szName ) )
 
			ColorChat( 0, GREEN, "%s^1 %s increased one level! Level:^3 %s^1 Total points:^3 %d", PREFIX, szName, CLASSES[ g_szLevels[ id ] ], g_szPoints[ id ] )
		}
	}
 
	new szTemp[ 512 ]
	format( szTemp, charsmax( szTemp ), "UPDATE %s SET nick = '%s', skillpoints = '%i', level = '%i' WHERE authid = '%s'", SQL_TABLE, g_szName[ id ], g_szPoints[ id ], g_szLevels[ id ], g_szAuthID[ id ] )
 
	SQL_ThreadQuery( g_SqlTuple, "IgnoreHandle", szTemp )
 
	if( g_szPoints[ id ] >= MAXPONTUATION )
	{
		CheckLevelAndSave( id )
	}
}
 
public LoadPoints( id )
{
	new Data[ 1 ]
	Data[ 0 ] = id
 
	new szTemp[ 512 ]
	format( szTemp, charsmax( szTemp ), "SELECT skillpoints, level FROM %s WHERE authid = '%s'", SQL_TABLE, g_szAuthID[ id ] )
 
	SQL_ThreadQuery( g_SqlTuple, "RegisterClient", szTemp, Data, 1 )
}
 
public RegisterClient( FailState, Handle:Query, Error[ ], Errcode, Data[ ], DataSize )
{
	if( SQL_IsFail( FailState, Errcode, Error ) )
		return PLUGIN_HANDLED_MAIN
 
	new id
	id = Data[ 0 ]
 
	if( SQL_NumResults( Query ) < 1 )
	{
		new szTemp[ 512 ]
		format( szTemp, charsmax( szTemp ), "INSERT INTO %s ( authid, nick, skillpoints, level ) VALUES( '%s', '%s', '%i', '%i' )", SQL_TABLE, g_szAuthID[ id ], g_szName[ id ], g_szPoints[ id ], g_szLevels[ id ]  )
 
		SQL_ThreadQuery( g_SqlTuple, "IgnoreHandle", szTemp )
	} 
 
	else
	{
		g_szPoints[ id ] = SQL_ReadResult( Query, 0 )
		g_szLevels[ id ] = SQL_ReadResult( Query, 1 )
	}
 
	return PLUGIN_CONTINUE
}
 
public IgnoreHandle( FailState, Handle:Query, Error[ ], Errcode, Data[ ], DataSize )
	SQL_FreeHandle( Query )
 
public SkillRank( id )
{
	if( get_pcvar_num( g_iEnableSkillPointsCmdRank ) == 0 )
		ColorChat( id, GREEN, "%s^1 Command disabled", PREFIX )
 
	else if( get_pcvar_num( g_iEnableSkillPointsCmdRank ) > 0 )
	{
		if( is_user_ignored[ id ] )
		{
			ColorChat( id, GREEN, "%s^1 Only for Steam accounts ", PREFIX )
			return PLUGIN_HANDLED_MAIN
		}
 
		new Data[ 1 ]
		Data[ 0 ] = id
 
		new szTemp[ 512 ]
		format( szTemp, charsmax( szTemp ), "SELECT COUNT(*) FROM %s WHERE skillpoints >= %i", SQL_TABLE, g_szPoints[ id ] )
 
		SQL_ThreadQuery( g_SqlTuple, "GetSkillRank", szTemp, Data, 1 )
	}
 
	if( get_pcvar_num( g_iHideCmds ) == 0 )
		return PLUGIN_CONTINUE
 
	else if( get_pcvar_num( g_iHideCmds ) > 0 )
		return PLUGIN_HANDLED_MAIN
 
	return PLUGIN_CONTINUE
}
 
public GetSkillRank( FailState, Handle:Query, Error[ ], Errcode, Data[ ], DataSize )
{
	if( SQL_IsFail( FailState, Errcode, Error ) )
		return PLUGIN_HANDLED_MAIN
 
	new id
	id = Data[ 0 ]
 
	g_iRank = SQL_ReadResult( Query, 0 )
 
	if( g_iRank == 0 )
		g_iRank = 1
 
	TotalRows( id )
 
	return PLUGIN_CONTINUE
}
 
public TotalRows( id )
{
	new Data[ 1 ]
	Data[ 0 ] = id
 
	new szTemp[ 512 ]
	format( szTemp, charsmax( szTemp ), "SELECT COUNT(*) FROM %s", SQL_TABLE )
 
	SQL_ThreadQuery( g_SqlTuple, "GetTotalRows", szTemp, Data, 1 )
}
 
public GetTotalRows( FailState, Handle:Query, Error[ ], Errcode, Data[ ], DataSize )
{
	if( SQL_IsFail( FailState, Errcode, Error ) )
		return PLUGIN_HANDLED_MAIN
 
	new id
	id = Data[ 0 ]
 
	g_iCount = SQL_ReadResult( Query, 0 )
 
	ColorChat( id, GREEN, "%s^1 Your rank is^3 %i^1 of^3 %i^1 players with^3 %i^1 points ", PREFIX, g_iRank, g_iCount, g_szPoints[ id ] )
 
	return PLUGIN_CONTINUE
}
 
SQL_IsFail( const FailState, const Errcode, const Error[ ] )
{
	if( FailState == TQUERY_CONNECT_FAILED )
	{
		log_amx( "[Error] Could not connect to SQL database: %s", Error )
		return true
	}
 
	else if( FailState == TQUERY_QUERY_FAILED )
	{
		log_amx( "[Error] Query failed: %s", Error )
		return true
	}
 
	else if( Errcode )
	{
		log_amx( "[Error] Error on query: %s", Error )
		return true
	}
 
	return false
}
 
public GetSkillPoints( id )
{
	if( get_pcvar_num( g_iEnableSkillPointsCmd ) == 0 )
		ColorChat( id, GREEN, "%s^1 Command disabled", PREFIX )
 
	else if( get_pcvar_num( g_iEnableSkillPointsCmd ) > 0 )
	{
		if( is_user_ignored[ id ] )
		{
			ColorChat( id, GREEN, "%s^1 Only for Steam accounts ", PREFIX )
			return PLUGIN_HANDLED_MAIN
		}
 
		if( g_szLevels[ id ] < ( MAXLEVELS - 1 ) )
		{
			ColorChat( id, GREEN, "%s^1 Total points:^3 %d", PREFIX, g_szPoints[ id ] )
		}
 
		else
			ColorChat( id, GREEN, "%s^1 Total points:^3 %d", PREFIX, g_szPoints[ id ] )
	}
 
	if( get_pcvar_num( g_iHideCmds ) == 0 )
		return PLUGIN_CONTINUE
 
	else if( get_pcvar_num( g_iHideCmds ) > 0 )
		return PLUGIN_HANDLED_MAIN
 
	return PLUGIN_CONTINUE
}
 
public AdvertisementCmdMySkill( )
{
	for( new m = 1; m <= g_iMaxPlayers; m++ )
	{
		if( !is_user_ignored[ m ] )
			ColorChat( m, GREEN, "%s^1 Write^3 /myskill^1 to see your SkillPoints", PREFIX )
	}
 
	set_task( get_pcvar_float( g_TimeBetweenAds ), "AdvertisementCmdRestartSkill" )
}
 
public AdvertisementCmdRestartSkill( )
{
	for( new n = 1; n <= g_iMaxPlayers; n++ )
	{
		if( !is_user_ignored[ n ] )
			ColorChat( n, GREEN, "%s^1 Write^3 /restartskill^1 to restart your SkillPoints and level", PREFIX )
	}
 
	set_task( get_pcvar_float( g_TimeBetweenAds ), "AdvertisementCmdRank" )
}
 
public AdvertisementCmdRank( )
{
	for( new o = 1; o <= g_iMaxPlayers; o++ )
	{
		if( !is_user_ignored[ o ] )
			ColorChat( o, GREEN, "%s^1 Write^3 /rankskill^1 to see your rank", PREFIX )
	}
 
	set_task( get_pcvar_float( g_TimeBetweenAds ), "AdvertisementCmdMySkill" )
}
 
public CmdGivePoints( id, level, cid )
{
	if ( !cmd_access( id, level, cid, 3 ) )
		return PLUGIN_HANDLED
 
	new Arg1[ 32 ]
	new Arg2[ 6 ]
 
	read_argv( 1, Arg1, charsmax( Arg1 ) )
	read_argv( 2, Arg2, charsmax( Arg2 ) )
 
	new iPoints = str_to_num( Arg2 )
 
	new iPlayer = cmd_target( id, Arg1, 1 )
 
	if ( !iPlayer )
	{
		console_print( id, "Sorry, player %s could not be found or targetted!", Arg1 )
		return PLUGIN_HANDLED
	}
 
	else if( iPoints > 0 )
	{
		g_szPoints[ iPlayer ] += iPoints
		CheckLevelAndSave( iPlayer )
 
		new szAdminName[ 32 ]
		get_user_name( id, szAdminName, charsmax( szAdminName ) )
 
		new szPlayerName[ 32 ]
		get_user_name( iPlayer, szPlayerName, charsmax( szPlayerName ) )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0)
			ColorChat( 0, GREEN, "%s^1 %s gave^3 %i^1 SkillPoint%s to %s", PREFIX, szAdminName, iPoints, iPoints > 1 ? "s" : "", szPlayerName )
	}
 
	return PLUGIN_HANDLED
}
 
public CmdTakePoints( id, level, cid )
{
	if ( !cmd_access( id, level, cid, 3 ) )
		return PLUGIN_HANDLED
 
	new Arg1[ 32 ]
	new Arg2[ 6 ]
 
	read_argv( 1, Arg1, charsmax( Arg1 ) )
	read_argv( 2, Arg2, charsmax( Arg2 ) )
 
	new iPoints = str_to_num( Arg2 )
 
	new iPlayer = cmd_target( id, Arg1, 1 )
 
	if ( !iPlayer )
	{
		console_print( id, "Sorry, player %s could not be found or targetted!", Arg1 )
		return PLUGIN_HANDLED
	}
 
	else if( iPoints > 0 )
	{
		g_szPoints[ iPlayer ] -= iPoints
		CheckLevelAndSave( iPlayer )
 
		new szAdminName[ 32 ]
		get_user_name( id, szAdminName, charsmax( szAdminName ) )
 
		new szPlayerName[ 32 ]
		get_user_name( iPlayer, szPlayerName, charsmax( szPlayerName ) )
 
		if( get_pcvar_num( g_iEnableAnnounceOnChat ) > 0)
			ColorChat( 0, GREEN, "%s^1 %s take^3 %i^1 SkillPoint%s from %s", PREFIX, szAdminName, iPoints, iPoints > 1 ? "s" : "", szPlayerName )
	}
 
	return PLUGIN_HANDLED
}
 
public FwdPlayerSpawnPost( id )
{	
	if( is_user_ignored[ id ] || !is_user_alive( id ) )
		return HAM_SUPERCEDE
 
	if( get_pcvar_num( g_iEnableShowSkillPointsOnNick ) > 0 )
	{
		new szName[ 32 ]
		get_user_info( id, "name", szName, charsmax( szName ) )
 
		new iLen = strlen( szName )
 
		new iPos = iLen - 1
 
		if( szName[ iPos ] == '>' )
		{    
			for( new i = 1; i < 7; i++)
			{    
				if( szName[ iPos - i ] == '<' )
				{    
					iLen = iPos - i
					szName[ iLen ] = '^0'
					break
				}
			}
		}
 
		format( szName[ iLen ], charsmax( szName ) - iLen, szName[ iLen-1 ] == ' ' ? "<%d>" : " <%d>", g_szPoints[ id ] )    
		set_user_info( id, "name", szName )
	}	
 
	return HAM_IGNORED
}
 
public MessageSayText( iMsgID, iDest, iReceiver )
{
	if( get_pcvar_num( g_iHideChangeNickNotification ) > 0 )
	{
		new const Cstrike_Name_Change[ ] = "#Cstrike_Name_Change"
 
		new szMessage[ sizeof( Cstrike_Name_Change ) + 1 ]
		get_msg_arg_string( 2, szMessage, charsmax( szMessage ) )
 
		return equal( szMessage, Cstrike_Name_Change ) ? PLUGIN_HANDLED : PLUGIN_CONTINUE
	}
 
	return PLUGIN_CONTINUE
}
 
/////////////////////////////////////
// ColorChat Stuff by ConnorMcLeod //
/////////////////////////////////////
 
stock client_print_color(id, iColor=DontChange, const szMsg[], any:...)
{
	// check if id is different from 0
	if( id && !is_user_connected(id) )
	{
		return 0;
	}
 
	if( iColor > Grey )
	{
		iColor = DontChange;
	}
 
	new szMessage[192];
	if( iColor == DontChange )
	{
		szMessage[0] = 0x04;
	}
	else
	{
		szMessage[0] = 0x03;
	}
 
	new iParams = numargs();
	// Specific player code
	if(id)
	{
		if( iParams == 3 )
		{
			copy(szMessage[1], charsmax(szMessage)-1, szMsg);
		}
		else
		{
			vformat(szMessage[1], charsmax(szMessage)-1, szMsg, 4);
		}
 
		if( iColor )
		{
			new szTeam[11]; // store current team so we can restore it
			get_user_team(id, szTeam, charsmax(szTeam));
 
			// set id TeamInfo in consequence
			// so SayText msg gonna show the right color
			Send_TeamInfo(id, id, g_szTeamName[iColor]);
 
			// Send the message
			Send_SayText(id, id, szMessage);
 
			// restore TeamInfo
			Send_TeamInfo(id, id, szTeam);
		}
		else
		{
			Send_SayText(id, id, szMessage);
		}
	} 
 
	// Send message to all players
	else
	{
		// Figure out if at least 1 player is connected
		// so we don't send useless message if not
		// and we gonna use that player as team reference (aka SayText message sender) for color change
		new iPlayers[32], iNum;
		get_players(iPlayers, iNum, "ch");
		if( !iNum )
		{
			return 0;
		}
 
		new iFool = iPlayers[0];
 
		new iMlNumber, i, j;
		new Array:aStoreML = ArrayCreate();
		if( iParams >= 5 ) // ML can be used
		{
			for(j=4; j<iParams; j++)
			{
				// retrieve original param value and check if it's LANG_PLAYER value
				if( getarg(j) == LANG_PLAYER )
				{
					i=0;
					// as LANG_PLAYER == -1, check if next parm string is a registered language translation
					while( ( szMessage[ i ] = getarg( j + 1, i++ ) ) ) {}
					if( GetLangTransKey(szMessage) != TransKey_Bad )
					{
						// Store that arg as LANG_PLAYER so we can alter it later
						ArrayPushCell(aStoreML, j++);
 
						// Update ML array saire so we'll know 1st if ML is used,
						// 2nd how many args we have to alterate
						iMlNumber++;
					}
				}
			}
		}
 
		// If arraysize == 0, ML is not used
		// we can only send 1 MSG_BROADCAST message
		if( !iMlNumber )
		{
			if( iParams == 3 )
			{
				copy(szMessage[1], charsmax(szMessage)-1, szMsg);
			}
			else
			{
				vformat(szMessage[1], charsmax(szMessage)-1, szMsg, 4);
			}
 
			if( iColor )
			{
				new szTeam[11];
				get_user_team(iFool, szTeam, charsmax(szTeam));
				Send_TeamInfo(0, iFool, g_szTeamName[iColor]);
				Send_SayText(0, iFool, szMessage);
				Send_TeamInfo(0, iFool, szTeam);
			}
			else
			{
				Send_SayText(0, iFool, szMessage);
			}
		}
 
		// ML is used, we need to loop through all players,
		// format text and send a MSG_ONE_UNRELIABLE SayText message
		else
		{
			new szTeam[11], szFakeTeam[10];
 
			if( iColor )
			{
				get_user_team(iFool, szTeam, charsmax(szTeam));
				copy(szFakeTeam, charsmax(szFakeTeam), g_szTeamName[iColor]);
			}
 
			for( i = 0; i < iNum; i++ )
			{
				id = iPlayers[i];
 
				for(j=0; j<iMlNumber; j++)
				{
					// Set all LANG_PLAYER args to player index ( = id )
					// so we can format the text for that specific player
					setarg(ArrayGetCell(aStoreML, j), _, id);
				}
 
				// format string for specific player
				vformat(szMessage[1], charsmax(szMessage)-1, szMsg, 4);
 
				if( iColor )
				{
					Send_TeamInfo(id, iFool, szFakeTeam);
					Send_SayText(id, iFool, szMessage);
					Send_TeamInfo(id, iFool, szTeam);
				}
				else
				{
					Send_SayText(id, iFool, szMessage);
				}
			}
			ArrayDestroy(aStoreML);
		}
	}
	return 1;
}
 
stock Send_TeamInfo(iReceiver, iPlayerId, szTeam[])
{
	static iTeamInfo = 0;
	if( !iTeamInfo )
	{
		iTeamInfo = get_user_msgid("TeamInfo");
	}
	message_begin(iReceiver ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, iTeamInfo, .player=iReceiver);
	write_byte(iPlayerId);
	write_string(szTeam);
	message_end();
}
 
stock Send_SayText(iReceiver, iPlayerId, szMessage[])
{
	static iSayText = 0;
	if( !iSayText )
	{
		iSayText = get_user_msgid("SayText");
	}
	message_begin(iReceiver ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, iSayText, .player=iReceiver);
	write_byte(iPlayerId);
	write_string(szMessage);
	message_end();
}
 
/////////////////////////////////////