CSDM_Sentry излизат ми грешки.

В този раздел можете да подавате всякакви заявки за намиране, изработка или преработка на плъгини/модове.
Аватар
cgozzie
На линия
Потребител
Потребител
Мнения: 1318
Регистриран на: 13 Окт 2016, 22:10
Местоположение: Варна
Се отблагодари: 244 пъти
Получена благодарност: 42 пъти

CSDM_Sentry излизат ми грешки.

Мнение от cgozzie » 01 Сеп 2021, 14:38

Плъгина се компелира но ми излизат тези грешки,фатални ли са за плугина да работи коректно или не.

Код за потвърждение: Избери целия код

Welcome to the AMX Mod X 1.8.1-300 Compiler.
Copyright (c) 1997-2013 ITB CompuPhase, AMX Mod X Team
 
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(484) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1420) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1421) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1439) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1440) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1449) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1657) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1663) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1671) : warning 217: loose indentation
/hlds/web/www/amxxpc/work/scripting/202135/1630496228/CSDM_Sentry.sma(1681) : warning 217: loose indentation
Header size:           3536 bytes
Code size:            78484 bytes
Data size:            23896 bytes
Stack/heap size:      16384 bytes; max. usage is unknown, due to recursion
Total requirements:  122300 bytes
 
10 Warnings.
Done.
CSDM_Sentry.sma

Код за потвърждение: Избери целия код

#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <fun>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <xs>

#define Z_ADMIN  ADMIN_USER    // флаг l
#define MAIN_ADMIN  ADMIN_LEVEL_H    // флаг l

#if AMXX_VERSION_NUM < 183
	#define message_begin_f(%0,%1,%2,%3)	engfunc(EngFunc_MessageBegin,%0,%1,%2,%3)
	#define write_coord_f(%0)		engfunc(EngFunc_WriteCoord,%0)
	
	#include <dhudmessage>
#endif


//native sh_set_hero ( id )
//native give_shield_grenade ( id )


#define is_valid_player(%1) ( 1 <= %1 <= g_iMaxPlayers )
#define is_valid_team(%1) ( 0 < %1 < 3 )

#define is_entity_on_ground(%1) ( entity_get_int ( %1, EV_INT_flags ) & FL_ONGROUND )

// сколько пушек у игрока уже построено
#define GetSentryCount(%1) g_iPlayerSentries[%1]

#define MAXUPGRADERANGE		75.0
#define SENTRYEXPLODERADIUS	250.0		// радиус отброса при взрыве
#define SENTRYTILTRADIUS	830.0		// likely you won't need to touch this. it's how accurate the cannon will aim at the target vertically (up/down, just for looks, aim is calculated differently)

#define SENTRYMINDISTANCE	256.0

#define MAXSENTRIES				32 * 3

#define TASK_GODMODE 114455

#define SENTRY_INT_PEOPLE		EV_INT_iuser2 // max 5 users using 6 bits!
#define SENTRY_INT_UGPRADERS		EV_INT_iuser3
#define SENTRY_PEOPLE_BITS		6
#define OWNER				0
#define UPGRADER_1			1
#define UPGRADER_2			2
#define TARGET				3
#define UPGRADER_3			4
#define MASK_OWNER			0xFFFFFFC0 // 11111111111111111111111111000000
#define MASK_UPGRADER_1			0xFFFFF03F // 11111111111111111111000000111111
#define MASK_UPGRADER_2			0xFFFC0FFF // 11111111111111000000111111111111
#define MASK_TARGET			0xFF03FFFF // 11111111000000111111111111111111
#define MASK_UPGRADER_3			0xC0FFFFFF // 11000000111111111111111111111111

new const MASKS_PEOPLE[5] = {MASK_OWNER, MASK_UPGRADER_1, MASK_UPGRADER_2, MASK_TARGET, MASK_UPGRADER_3}

GetSentryPeople(const SENTRY, const WHO) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_PEOPLE)
	data |= MASKS_PEOPLE[WHO]
	data ^= MASKS_PEOPLE[WHO]
	data = (data>>(WHO*SENTRY_PEOPLE_BITS))
	return data
}
SetSentryPeople(const SENTRY, const WHO, const IS) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_PEOPLE)
	data &= MASKS_PEOPLE[WHO] // nullify the setting
	data |= (IS<<(WHO*SENTRY_PEOPLE_BITS)) // set the setting
	entity_set_int(SENTRY, SENTRY_INT_PEOPLE, data) // store
}

#define SENTRY_INT_SETTINGS	EV_INT_iuser1
#define SENTRY_ROCKET_TIME	EV_FL_teleport_time
#define SENTRY_SETTINGS_BITS	2
#define SENTRY_SETTING_FIREMODE	0
#define SENTRY_SETTING_TEAM	1
#define SENTRY_SETTING_LEVEL	2
#define SENTRY_SETTING_PENDDIR	3
#define MASK_FIREMODE		0xFFFFFFFC // 11111111111111111111111111111100 = FFFFFFFC
#define MASK_TEAM		0xFFFFFFF3 // 11111111111111111111111111110011 = FFFFFFF3
#define MASK_LEVEL		0xFFFFFFCF // 11111111111111111111111111001111 = FFFFFFCF
#define MASK_PENDDIR		0xFFFFFF3F // 11111111111111111111111100111111 = FFFFFF3F

new const MASKS_SETTINGS[4] = {MASK_FIREMODE, MASK_TEAM, MASK_LEVEL, MASK_PENDDIR}

GetSentrySettings(const SENTRY, const SETTING) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_SETTINGS)
	data |= MASKS_SETTINGS[SETTING]
	data ^= MASKS_SETTINGS[SETTING]
	//data = (data>>(SETTING*SENTRY_SETTINGS_BITS))
	return (data>>(SETTING*SENTRY_SETTINGS_BITS))
}
SetSentrySettings(const SENTRY, const SETTING, const VALUE) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_SETTINGS)
	data &= MASKS_SETTINGS[SETTING] // nullify the setting
	//data |= (VALUE<<(SETTING*SENTRY_SETTINGS_BITS)) // set the setting
	entity_set_int(SENTRY, SENTRY_INT_SETTINGS, data | (VALUE<<(SETTING*SENTRY_SETTINGS_BITS))) // store
}

GetSentryFiremode(const SENTRY) 
{
	return GetSentrySettings(SENTRY, SENTRY_SETTING_FIREMODE)
}
SetSentryFiremode(const SENTRY, const MODE) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_FIREMODE, MODE)
}
CsTeams:GetSentryTeam(const SENTRY) 
{
	return CsTeams:GetSentrySettings(SENTRY, SENTRY_SETTING_TEAM)
}
SetSentryTeam(const SENTRY, const CsTeams:TEAM) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_TEAM, int:TEAM)
}
GetSentryLevel(const SENTRY) 
{
	return GetSentrySettings(SENTRY, SENTRY_SETTING_LEVEL)
}
SetSentryLevel(const SENTRY, const LEVEL) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_LEVEL, LEVEL)
}
GetSentryPenddir(const SENTRY) 
{
	return GetSentrySettings(SENTRY, SENTRY_SETTING_PENDDIR)
}
SetSentryPenddir(const SENTRY, const PENDDIR) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_PENDDIR, PENDDIR)
}

#define SENTRY_ENT_BASE			EV_ENT_euser1

#define SENTRY_FL_ANGLE			EV_FL_fuser1
#define SENTRY_FL_SPINSPEED		EV_FL_fuser2
#define SENTRY_FL_MAXSPIN		EV_FL_fuser3
#define SENTRY_FL_LASTTHINK		EV_FL_fuser4

#define SENTRY_DIR_CANNON		0

#define BASE_ENT_SENTRY			EV_ENT_euser1
#define BASE_INT_TEAM			EV_INT_iuser1

#define SENTRY_LEVEL_1			0
#define SENTRY_LEVEL_2			1
#define SENTRY_LEVEL_3			2
#define SENTRY_LEVEL_4			3
#define SENTRY_FIREMODE_NO		0
#define SENTRY_FIREMODE_YES		1
#define SENTRY_FIREMODE_NUTS	        2
#define TARGETUPMODIFIER		18.0 // if player ducks on ground, traces don't hit...
#define DMG_BULLET			(1<<1)	//выстрел
#define DMG_BLAST			(1<<6)	// explosive blast damage
#define TE_EXPLFLAG_NONE		0
#define TE_EXPLOSION			3
#define TE_TRACER			6
#define TE_BREAKMODEL			108
#define PENDULUM_MAX			45.0 // how far sentry turret turns in each direction when idle, before turning back
#define PENDULUM_INCREMENT		10.0 // speed of turret turning...
#define SENTRYSHOCKPOWER		3.0  // multiplier, increase to make exploding sentries throw stuff further away
#define CANNONHEIGHTFROMFEET	        20.0 // tweakable to make tracer originate from the same height as the sentry's cannon. Also traces rely on this Y-wise offset.
#define PLAYERORIGINHEIGHT		36.0 // this is the distance from a player's EV_VEC_origin to ground, if standing up
#define HEIGHTDIFFERENCEALLOWED	        20.0 // increase value to allow building in slopes with higher angles. You can set to 0.0 and you will only be able to build on exact flat ground. note: mostly applies to downhill building, uphill is still likely to "collide" with ground...

#define PLACE_RANGE 45.0

#define SENTRY_RADAR			20 // use as high as possible but should still be working (ie be able to see sentries plotted on radar while in menu, too high values doesn't seem to work)
#define SENTRY_RADAR_TEAMBUILT	        21 // same as above

#define RPG_RADIUS	250.0
#define RPG_DAMAGE	150.0
#define RPG_DISTANCE	400.0

new const szModels[][] =
{
	"models/SecondNewCSDM/Sentry/base_s.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_1te.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_2te.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_1ct.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_2ct.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl",
	"models/rpgrocket.mdl",
	"models/computergibs.mdl"
}

new const szSounds[][] =
{
	"SecondNewCSDM/Sentry/bustmetal1.wav",
	"SecondNewCSDM/Sentry/bustmetal2.wav",
	"SecondNewCSDM/Sentry/metal1.wav",
	"SecondNewCSDM/Sentry/metal3.wav",
	"SecondNewCSDM/Sentry/turridle.wav",
	"SecondNewCSDM/Sentry/turrset.wav",
	"SecondNewCSDM/Sentry/turrspot.wav",
	"SecondNewCSDM/Sentry/building.wav",
	"SecondNewCSDM/Sentry/fire.wav",
	"weapons/rocket1.wav"
}

new expDecal

#define SENTRYOWNERAWARD	300
#define SENTRYASSISTAWARD	150

new const g_DMG[4] = {5, 10, 15, 15}					// количество урона от пушки в зависимости от ее уровня
new const Float:g_THINKFREQUENCIES[4] = {2.0, 1.0, 0.5, 0.5}		// через сколько захватывается цель
new const Float:g_HITRATIOS[4] = {0.6, 0.75, 0.85, 0.85}		// разброс
new const Float:g_HEALTHS[4] = {3000.0, 6000.0, 9000.0, 10000.0}	// сколько хп у пушки в зависимости от ее уровня (верхняя часть)
new const g_COST[4] = {3000, 4000, 6000, 16000}				// стоимость установки/улучшения пушек
new const g_SENTRYCOST[3] = {3000, 3500, 4000}		   	        // стоимость установки/улучшения пушек
#define g_sentriesNum (g_teamsentriesNum[0]+g_teamsentriesNum[1])
new g_teamsentriesNum[2]	
new g_sentries[MAXSENTRIES]
new g_iPlayerSentries[33]
new g_iPlayerSentriesEdicts[33][3]
new g_sModelIndexFireball
new g_msgDamage
new g_msgDeathMsg
new g_msgScoreInfo
new g_msgHostagePos
new g_msgHostageK
new g_iMaxPlayers
new Float:g_ONEEIGHTYTHROUGHPI
new Float:g_sentryOrigins[32][3]
new bool:g_inBuilding[33]
new sentries_num[33]
new gMsgID
new g_iTimer[33]
new m_iTrail

public plugin_init() 
{

	register_plugin("Sentry guns", "1.1", "JGHG & miRror")

	register_event ( "Spectator", "ev_Spectation", "a" )

	register_clcmd("sentry_build", "cmd_CreateSentry", 0, "- build a sentry gun where you are")
	register_clcmd("say /sgstats", "sgstats", 0, "- stats sentry")
	//register_clcmd("say /forcesh", "givesgr")
	register_clcmd("Komap_killsentry", "sentry_deleter")
	
	RegisterHam ( Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1 )

	register_forward ( FM_TraceLine, "fw_TraceLine_Post", 1 )

	RegisterHam ( Ham_TakeDamage, "func_breakable", "fw_TakeDamage" )
	
	register_touch ( "sentry", "player", "fw_TouchSentry" )
	register_touch("rpg_rocket","*","fw_RpgTouch")
	
	register_message ( 23, "msg_TempEntity" )
	register_think("sentrybase", "think_sentrybase")
	register_think ( "sentry", "fw_ThinkSentry" )

	g_msgDamage = get_user_msgid("Damage")
	g_msgDeathMsg = get_user_msgid("DeathMsg")
	g_msgScoreInfo = get_user_msgid("ScoreInfo")
	g_msgHostagePos = get_user_msgid("HostagePos")
	g_msgHostageK = get_user_msgid("HostageK")
	gMsgID = get_user_msgid("StatusIcon")
	
	g_iMaxPlayers = get_global_int(GL_maxClients)
	g_ONEEIGHTYTHROUGHPI = 180.0 / 3.141592654
	
	expDecal = get_decal_index("{scorch1")

	//set_task ( 120.0, "checkhero", .flags = "b" )
}

public plugin_precache() 
{
	for(new i=0;i<sizeof(szModels);i++)
		precache_model(szModels[i])
	for(new i=0;i<sizeof(szSounds);i++)
		precache_sound(szSounds[i])
	g_sModelIndexFireball = precache_model("sprites/zerogxplode.spr")
	m_iTrail = precache_model("sprites/smoke.spr")

        precache_sound( "debris/bustglass1.wav" )
        precache_sound( "debris/bustmetal1.wav" )
        precache_sound( "debris/bustmetal2.wav" )
        precache_sound( "buttons/spark5.wav" )
        precache_sound( "buttons/spark6.wav" )
}

public plugin_natives ()
{
	register_native ( "get_sentry_people", "native_get_sentry_people", 1 )
	register_native ( "get_sentry_team", "native_get_sentry_team", 1 )
}

public native_get_sentry_people ( sentry, who )
{
	return GetSentryPeople ( sentry, who )
}

public CsTeams:native_get_sentry_team ( sentry )
{
	return GetSentryTeam ( sentry )
}

public sgstats(id)
{
	ChatColor ( id, "^1[^4CSDM*Sentry^1] Пушек у КТ^4: ^1[ ^3%d ^1], ТТ^4: ^1[ ^3%d ^1], у всех^4: ^1[ ^3%d ^1]", g_teamsentriesNum[1],g_teamsentriesNum[0],g_sentriesNum)
}

/*public givesgr(id)
{
	if(is_user_alive(id))
		give_shield_grenade ( id )
		
	return PLUGIN_HANDLED
}

public checkhero()
{
	new iPlayers = get_playersnum ()
	if(iPlayers > 15 && g_sentriesNum >= 14)
	{
		new players[32],  num, plid, bestfrags = 0, bool:heroenabled
		new iData[2]; iData[0] = 5
		if(g_teamsentriesNum[1] <= (g_sentriesNum * 0.3))
		{
			iData[1] = 1
			TimerStart ( iData )
			get_players(players, num, "ache", "CT")
			heroenabled = true
		} else if(g_teamsentriesNum[0] <= (g_sentriesNum * 0.3)) {
			iData[1] = 0
			get_players(players, num, "ache", "TERRORIST")	
			heroenabled = true
		}
		
		if(heroenabled && num > 1)
		{
			new iNum = num, iHero
			for(--num; num>=0; num--) 
			{ 
				if(get_user_frags(players[num]) >= bestfrags)
				{
					plid = players[iHero = num]
					bestfrags = get_user_frags(plid)
				}
			}
			if ( sh_set_hero ( plid ) )
			{
				while (GetSentryCount(plid) > 0)
					sentry_detonate_by_owner(plid)

				for ( new i = iHero; i < iNum; i++ )
					players[i] = players[i+1]

				iNum--
			}
		      //if ( iNum > 0 )
		      //{
		      //	new iParam[33]
		      //	for ( new i; i < iNum; i++ )
		      //	iParam[i] = players[i]
		      //	iParam[32] = iNum
		      //	set_task ( 5.0, "GiveShieldGrenades", 0, iParam, 33 )
		      //}
		}
	}
}*/

public TimerStart ( data[2] )
{
	if ( !data[0] ) return

	data[0]--

	set_dhudmessage ( 255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0 )
	show_dhudmessage ( 0, "Выдача гранаты-ауры %s начнется через %d секунд", data[1] ? "контрам" : "террам", data[0] )

	set_task ( 1.0, "TimerStart", 0, data, 2 )
}

public GiveShieldGrenades ( param[33] )
{
	new players[32], num = param[32]
	for ( new i; i < num; i++ )
		players[i] = param[i]

	new iPlayers[3], iNum = clamp ( num, 1, 3 )

	for ( new i, b, iRandom, iPlayer; i < iNum; i++ )
	{
		iPlayer = iPlayers[i] = players[iRandom = random_num ( 0, num-1 )]

		//give_shield_grenade ( iPlayer )
		g_iTimer[iPlayer] = 10
		set_user_godmode ( iPlayer, 1 )
		TimerGodMode ( iPlayer )

		for ( b = iRandom; b < num; b++ )
			players[b] = players[b+1]
	}
	set_dhudmessage ( 255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0 )
	show_dhudmessage ( 0, "Аура выдана %i игрокам", iNum )
}

public TimerGodMode ( id )
{
	if ( id > g_iMaxPlayers )
		id -= TASK_GODMODE

	if ( !is_user_connected ( id ) || !is_user_alive ( id ) )
		return

	set_dhudmessage ( 255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0 )

	if ( --g_iTimer[id] > 0 )
	{
		show_dhudmessage ( id, "У вас еще есть %i секунд бессмертия^nГраната аура - это дымовая граната", g_iTimer[id] )
		set_task ( 1.0, "SetGodMode", id+TASK_GODMODE )
	}
	else
	{
		show_dhudmessage ( id, "Режим бессмертия отключен" )
		set_user_godmode ( id, 0 )
	}
}

public ev_Spectation ()
{
	new id = read_data ( 1 )

	if ( is_user_connected ( id ) && cs_get_user_team ( id ) == CS_TEAM_SPECTATOR )
		while ( GetSentryCount ( id ) > 0 )
			sentry_detonate_by_owner ( id )
}

public fw_TakeDamage ( ent, idinflictor, idattacker, Float:damage, damagebits )
{
	if ( !pev_valid ( ent ) )
		return HAM_IGNORED
	
	new sClassname[11]
	pev ( ent, pev_classname, sClassname, charsmax ( sClassname ) )
	
	if ( equal ( sClassname, "sentry" ) || equal ( sClassname, "sentrybase" ) )
	{
		if ( sClassname[6] == 'b' )
			ent = entity_get_edict(ent, BASE_ENT_SENTRY)
		
		if ( pev_valid ( ent ) )
		{
			new iOwner = GetSentryPeople ( ent, OWNER )
			
			if ( !is_user_connected ( iOwner ) || !is_valid_player ( iOwner ) || !is_user_connected ( idattacker ) || !is_valid_player ( idattacker ) )
				return HAM_SUPERCEDE
		
			if ( cs_get_user_team ( iOwner ) == cs_get_user_team ( idattacker ) && idattacker != iOwner )
				return HAM_SUPERCEDE
		}
	}
	return HAM_IGNORED	
}

public cmd_CreateSentry ( id )
{
	new iSentry = AimingAtSentry ( id )

	if ( iSentry && entity_range ( iSentry, id ) <= MAXUPGRADERANGE )
		SentryUpgrade ( id, iSentry )
	else
		SentryBuild ( id )

	return PLUGIN_HANDLED
}

public SentryBuild ( id )
{	
    new GetNumCt = SetNumCt(1)
	new GetNumT = SetNumT(1)
	
	if(get_user_flags(id) & ADMIN_KICK)
	{		  
	if(get_user_team(id) == 2 && GetNumT < 1)
    {
	ChatColor (id, "^1[^4CSDM*Sentry^1] Запрещено ставить пушку, у команды противника нет ^4 30 фрагов!")
	return
	}
		
	if(get_user_team(id) == 1 && GetNumCt < 1)
	{
	ChatColor (id, "^1[^4CSDM*Sentry^1] Запрещено ставить пушку, у команды противника нет ^4 30 фрагов!")
	return
	}
	}
	if ( !is_user_alive ( id ) )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Мертвым ^3нельзя ^1ставить пушку!" )
		return
	}
	new iSentryCount = GetSentryCount ( id )

	if(get_user_flags(id) & ADMIN_KICK)
	{
		if ( iSentryCount == 3 )
		{
			ChatColor ( id, "^1[^4CSDM*Sentry^1] Нельзя установить более^3 3 ^1пушек!" )
			return
		}
        }
        else if(get_user_flags(id) & ADMIN_ALL)
	{
		if ( iSentryCount == 2 )
		{
			ChatColor ( id, "^1[^4CSDM*Sentry^1] Нельзя установить более^3 2 ^1пушек!" )
			return
		}
        }


	if ( g_inBuilding[id] )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Эй, не так быстро^3..." )
		return
	}
	if ( !is_entity_on_ground ( id ) )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Встань ^3на землю^1, чтобы установить пушку!" )
		return
	}
	
	new Float:origin[3],classname[32],e
	entity_get_vector(id,EV_VEC_origin,origin)
	
	
	
	while((e = find_ent_in_sphere(e,origin,SENTRYMINDISTANCE)))
        {
		entity_get_string(e,EV_SZ_classname,classname,charsmax(classname))
		
		if(strcmp(classname,"sentrybase") == 0 && entity_get_int(e, BASE_INT_TEAM) == get_user_team(id) && entity_get_edict(e,EV_ENT_owner) != id)
                {
                
			ChatColor(id,"^1[^4CSDM*Sentry^1] Защита от ^3подсосов")
			return
		}
	}
	
	if ( cs_get_user_money ( id ) < g_SENTRYCOST[iSentryCount] )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] У тебя ^3не хватает ^1денег! ^4(^1нужно ^3%d^1$^4)", g_SENTRYCOST[iSentryCount] )
		return
	}

	new Float:fPlayerOrigin[3], Float:fOrigin[3], Float:fAngle[3]
	pev ( id, pev_origin, fPlayerOrigin )
	pev ( id, pev_angles, fAngle )
	fOrigin = fPlayerOrigin

	fOrigin[0] += floatcos ( fAngle[1], degrees ) * PLACE_RANGE
	fOrigin[1] += floatsin ( fAngle[1], degrees ) * PLACE_RANGE
	fOrigin[0] += floatcos ( fAngle[0], degrees) * PLACE_RANGE
	fOrigin[1] += floatcos ( fAngle[1], degrees )
	fOrigin[0] -= floatsin ( fAngle[1], degrees )
	fOrigin[1] += floatcos ( fAngle[2], degrees )
	fOrigin[1] -= floatsin ( fAngle[2], degrees ) * PLACE_RANGE
	fOrigin[0] -= floatsin ( fAngle[0], degrees ) * PLACE_RANGE
	fOrigin[0] -= PLACE_RANGE

	if ( pev ( id, pev_flags ) & FL_DUCKING )
		fOrigin[2] += 18.0, fPlayerOrigin[2] += 18.0

	new tr = 0, Float:fFraction
	engfunc ( EngFunc_TraceLine, fPlayerOrigin, fOrigin, 0, id, tr )
	get_tr2 ( tr, TR_flFraction, fFraction )

	if ( fFraction != 1.0 )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Здесь ^3не получается ^1установить пушку!" )
		return
	}

	if ( CreateSentryBase ( fOrigin, id ) )
	{
		cs_set_user_money ( id, cs_get_user_money ( id ) - g_SENTRYCOST[iSentryCount] )
		ammo_hud ( id, 0 )
		sentries_num[id] += 1
		ammo_hud ( id, 1 )
	}
	else
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Здесь ^3не получается ^1установить пушку!" )
}

IncreaseSentryCount ( id, sentry )
{
	g_iPlayerSentriesEdicts[id][g_iPlayerSentries[id]] = sentry
	g_iPlayerSentries[id]++
	new Float:fSentryOrigin[3], iSentryOrigin[3], iPlayerOrigin[3]
	entity_get_vector ( sentry, EV_VEC_origin, fSentryOrigin )
	FVecIVec ( fSentryOrigin, iSentryOrigin )

	new sName[32]
	get_user_name ( id, sName, charsmax ( sName ) )
	new CsTeams:iTeam = cs_get_user_team ( id )

	for ( new i = 1; i <= g_iMaxPlayers; i++ )
	{
		if ( !is_user_connected ( i ) || !is_user_alive ( i ) || cs_get_user_team ( i ) != iTeam || id == i )
			continue

		get_user_origin ( i, iPlayerOrigin )

		client_print ( i, print_center, "%s установил пушку в %d юнитах от вас", sName, get_distance ( iPlayerOrigin, iSentryOrigin ) )

		message_begin ( MSG_ONE_UNRELIABLE, g_msgHostagePos, .player = i )
		write_byte ( i )
		write_byte ( SENTRY_RADAR_TEAMBUILT )
		write_coord ( iSentryOrigin[0] )
		write_coord ( iSentryOrigin[1] )
		write_coord ( iSentryOrigin[2] )
		message_end ()

		message_begin ( MSG_ONE_UNRELIABLE, g_msgHostageK, .player = i )
		write_byte ( SENTRY_RADAR_TEAMBUILT )
		message_end ()
	}
}
 
DecreaseSentryCount ( id, sentry )
{
	for ( new i; i < g_iPlayerSentries[id]; i++ )
	{
		if ( g_iPlayerSentriesEdicts[id][i] == sentry )
		{
			g_iPlayerSentriesEdicts[id][i] = g_iPlayerSentriesEdicts[id][g_iPlayerSentries[id] - 1]
			g_iPlayerSentriesEdicts[id][g_iPlayerSentries[id] - 1] = 0
			break
		}
	}
	g_iPlayerSentries[id]--
}

stock bool:CreateSentryBase ( Float:origin[3], creator, level = SENTRY_LEVEL_1 )
{
	if ( !CheckLocation ( origin ) )
		return false

	new Float:hitPoint[3], Float:originDown[3]
	originDown = origin
	originDown[2] = -5000.0 // dunno the lowest possible height...
	trace_line(0, origin, originDown, hitPoint)
	new Float:baDistanceFromGround = vector_distance(origin, hitPoint)

	new Float:difference = PLAYERORIGINHEIGHT - baDistanceFromGround
	if (difference < -1 * HEIGHTDIFFERENCEALLOWED || difference > HEIGHTDIFFERENCEALLOWED) return false

	new entbase = create_entity("func_breakable") // func_wall
	if (!entbase)
		return false

	#define SIZE 16.0

	new Float:fTraceEnds[5][3], Float:fTraceHit[3], iType, tr = create_tr2 ()
	fTraceEnds[0][0] = origin[0] - SIZE
	fTraceEnds[0][1] = origin[1] - SIZE
	fTraceEnds[0][2] = origin[2] + SIZE + SIZE
	fTraceEnds[1][0] = origin[0] + SIZE
	fTraceEnds[1][1] = origin[1] - SIZE
	fTraceEnds[1][2] = origin[2] + SIZE + SIZE
	fTraceEnds[2][0] = origin[0] - SIZE
	fTraceEnds[2][1] = origin[1] + SIZE
	fTraceEnds[2][2] = origin[2] + SIZE + SIZE
	fTraceEnds[3][0] = origin[0] + SIZE
	fTraceEnds[3][1] = origin[1] + SIZE
	fTraceEnds[3][2] = origin[2] + SIZE + SIZE
	fTraceEnds[4][0] = origin[0]
	fTraceEnds[4][1] = origin[1]
	fTraceEnds[4][2] = origin[2] + SIZE + SIZE

	for ( new i; i < 5; i++ )
	{
		fTraceHit = fTraceEnds[i]
		fTraceHit[2] += 40.0

		engfunc ( EngFunc_TraceLine, fTraceEnds[i], fTraceHit, 0, 0, tr )
		get_tr2 ( tr, TR_vecEndPos, fTraceHit )

		if ( fTraceHit[2] - fTraceEnds[i][2] != 40.0 )
		{
			iType = 1
			break
		}
	}

	if ( iType )
	{
		fTraceEnds[0][0] = origin[0] - SIZE
		fTraceEnds[0][1] = origin[1] - SIZE
		fTraceEnds[0][2] = origin[2] - SIZE - SIZE
		fTraceEnds[1][0] = origin[0] + SIZE
		fTraceEnds[1][1] = origin[1] - SIZE
		fTraceEnds[1][2] = origin[2] - SIZE - SIZE
		fTraceEnds[2][0] = origin[0] - SIZE
		fTraceEnds[2][1] = origin[1] + SIZE
		fTraceEnds[2][2] = origin[2] - SIZE - SIZE
		fTraceEnds[3][0] = origin[0] + SIZE
		fTraceEnds[3][1] = origin[1] + SIZE
		fTraceEnds[3][2] = origin[2] - SIZE - SIZE
		fTraceEnds[4][0] = origin[0]
		fTraceEnds[4][1] = origin[1]
		fTraceEnds[4][2] = origin[2] - SIZE - SIZE
		new Float:fMinDistance, Float:fDistance
		for ( new i; i < 5; i++ )
		{
			fTraceHit[0] = fTraceEnds[i][0]
			fTraceHit[1] = fTraceEnds[i][1]
			fTraceHit[2] = -8192.0
	
			engfunc ( EngFunc_TraceLine, fTraceEnds[i], fTraceHit, IGNORE_MONSTERS, 0, tr )
			get_tr2 ( tr, TR_vecEndPos, fTraceHit )
	
			fDistance = vector_distance ( fTraceEnds[i], fTraceHit )
	
			if ( fDistance < fMinDistance || fMinDistance <= 0.0 )
			{
				fMinDistance = fDistance
				origin[2] = fTraceHit[2]
			}
		}
	}
	free_tr2 ( tr )

	new healthstring[16]
	num_to_str(floatround(g_HEALTHS[0]), healthstring, 15)
	DispatchKeyValue(entbase, "health", healthstring)
	DispatchKeyValue(entbase, "material", "6")

	DispatchSpawn(entbase)
	entity_set_string(entbase, EV_SZ_classname, "sentrybase")
	entity_set_model(entbase, "models/SecondNewCSDM/Sentry/base_s.mdl") // later set according to level
	entity_set_edict(entbase,EV_ENT_owner,creator)
	
	new Float:mins[3], Float:maxs[3]
	mins[0] = -16.0
	mins[1] = -16.0
	mins[2] = 0.0
	maxs[0] = 16.0
	maxs[1] = 16.0
	maxs[2] = 1000.0 // Set to 16.0 later.
	entity_set_size(entbase, mins, maxs)
	entity_set_origin(entbase, origin)
	
	entity_set_int(entbase, EV_INT_solid, SOLID_SLIDEBOX)
	entity_set_int(entbase, EV_INT_movetype, iType ? MOVETYPE_FLY : MOVETYPE_TOSS) // head flies base falls
	entity_set_int(entbase, BASE_INT_TEAM, _:cs_get_user_team(creator))

	new parms[4]
	parms[0] = entbase
	parms[1] = creator
	parms[2] = level
	parms[3] = iType

	if ( iType ) origin[2] += 16.0

	g_sentryOrigins[creator - 1] = origin

	emit_sound(creator, CHAN_AUTO, "SecondNewCSDM/Sentry/building.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	set_task(2.0, "createsentryhead", 0, parms, 4)
	g_inBuilding[creator] = true

	return true
}

public createsentryhead(parms[4])
{
	new entbase = parms[0]
	new level = parms[2]
	new creator = parms[1]
	new iType = parms[3]

	if ( !is_user_connected ( creator ) || !g_inBuilding[creator] )
	{
		if (is_valid_ent(entbase))
			remove_entity(entbase)

		return
	}

	if ( !is_valid_team ( _:cs_get_user_team ( creator ) ) )
	{
		if (is_valid_ent(entbase))
			remove_entity(entbase)

		sentries_num[creator]--
		return
	}

	new Float:origin[3]
	origin = g_sentryOrigins[creator - 1]

	new ent = create_entity("func_breakable")
	if (!ent)
	{
		if (is_valid_ent(entbase))
		{
			remove_entity(entbase)
		}
		return
	}

	new Float:mins[3], Float:maxs[3]
	if (is_valid_ent(entbase)) {
		mins[0] = -16.0
		mins[1] = -16.0
		mins[2] = 0.0
		
		maxs[0] = 16.0
		maxs[1] = 16.0
		maxs[2] = 16.0
		entity_set_size(entbase, mins, maxs)

		entity_set_edict(ent, SENTRY_ENT_BASE, entbase)
		entity_set_edict(entbase, BASE_ENT_SENTRY, ent)
	}

	g_sentries[g_sentriesNum] = ent

	new healthstring[16]
	num_to_str(floatround(g_HEALTHS[0]), healthstring, 15)
	DispatchKeyValue(ent, "health", healthstring)
	DispatchKeyValue(ent, "material", "6")

	DispatchSpawn(ent)
	entity_set_string(ent, EV_SZ_classname, "sentry")
	switch(_:cs_get_user_team(creator))
	{
		case 1:
		{
			switch(level)
			{
				case SENTRY_LEVEL_1: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_1te.mdl")
				case SENTRY_LEVEL_2: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2te.mdl")
				case SENTRY_LEVEL_3: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl")
			}
		}
		case 2:
		{
			switch(level)
			{
				case SENTRY_LEVEL_1: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_1ct.mdl")
				case SENTRY_LEVEL_2: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2ct.mdl")
				case SENTRY_LEVEL_3: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl")
			}
		}
	}
	
	
	mins[0] = -16.0
	mins[1] = -16.0
	mins[2] = 0.0
	maxs[0] = 16.0
	maxs[1] = 16.0
	maxs[2] = 48.0
	entity_set_size(ent, mins, maxs)
	entity_set_origin(ent, origin)
	entity_get_vector(creator, EV_VEC_angles, origin)
	origin[0] = 0.0
	origin[1] += 180.0
	entity_set_float(ent, SENTRY_FL_ANGLE, origin[1])
	origin[2] = 0.0
	entity_set_vector(ent, EV_VEC_angles, origin)
	entity_set_int(ent, EV_INT_solid, SOLID_SLIDEBOX) // SOLID_SLIDEBOX
	entity_set_int(ent, EV_INT_movetype, iType ? MOVETYPE_FLY : MOVETYPE_TOSS) // head flies, base doesn't

	SetSentryPeople(ent, OWNER, creator)
	
	new CsTeams:crteam = cs_get_user_team(creator)
	SetSentryTeam ( ent, crteam )
	SetSentryLevel ( ent, level )

	g_teamsentriesNum[_:crteam-1]++
	
	emit_sound(ent, CHAN_AUTO, "SecondNewCSDM/Sentry/turrset.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	IncreaseSentryCount(creator, ent)

	new directions = (random_num(0, 1)<<SENTRY_DIR_CANNON)
	SetSentryPenddir ( ent, directions )

	g_inBuilding[creator] = false

	if (!is_valid_ent(entbase))
		SetSentryFiremode ( ent, SENTRY_FIREMODE_NUTS )

	entity_set_float ( ent, SENTRY_FL_LASTTHINK, get_gametime () + g_THINKFREQUENCIES[0] )
	entity_set_float ( ent, EV_FL_nextthink, get_gametime () + 0.01 )

	/*static bool:bHamRegistred

	if ( !bHamRegistred )
	{
		RegisterHamFromEntity ( Ham_Think, ent, "fw_ThinkSentry", 1 )
		bHamRegistred = true
	}*/
}

stock bool:CheckLocation ( const Float:origin[3] )
{
	if ( engfunc ( EngFunc_PointContents, origin ) != CONTENTS_EMPTY )
		return false

	new tr = create_tr2 ()

	engfunc ( EngFunc_TraceHull, origin, origin, 0, HULL_HEAD/*HUMAN*/, 0, tr )
	if ( !get_tr2 ( tr, TR_InOpen ) || get_tr2 ( tr, TR_StartSolid ) || get_tr2 ( tr, TR_AllSolid ) )
	{
		free_tr2 ( tr )
		return false
	}

	#define SIZE 16.0

	new Float:fTraceEnds[9][3], Float:fTraceHit[3], iHitEnt
	fTraceEnds[0][0] = origin[0]
	fTraceEnds[0][1] = origin[1]
	fTraceEnds[0][2] = origin[2] - SIZE - SIZE
	fTraceEnds[1][0] = origin[0] - SIZE
	fTraceEnds[1][1] = origin[1] - SIZE
	fTraceEnds[1][2] = origin[2] - SIZE - SIZE
	fTraceEnds[2][0] = origin[0] + SIZE
	fTraceEnds[2][1] = origin[1] - SIZE
	fTraceEnds[2][2] = origin[2] - SIZE - SIZE
	fTraceEnds[3][0] = origin[0] - SIZE
	fTraceEnds[3][1] = origin[1] + SIZE
	fTraceEnds[3][2] = origin[2] - SIZE - SIZE
	fTraceEnds[4][0] = origin[0] + SIZE
	fTraceEnds[4][1] = origin[1] + SIZE
	fTraceEnds[4][2] = origin[2] - SIZE - SIZE
	fTraceEnds[5][0] = origin[0] - SIZE
	fTraceEnds[5][1] = origin[1] - SIZE
	fTraceEnds[5][2] = origin[2] + SIZE + SIZE
	fTraceEnds[6][0] = origin[0] + SIZE
	fTraceEnds[6][1] = origin[1] - SIZE
	fTraceEnds[6][2] = origin[2] + SIZE + SIZE
	fTraceEnds[7][0] = origin[0] - SIZE
	fTraceEnds[7][1] = origin[1] + SIZE
	fTraceEnds[7][2] = origin[2] + SIZE + SIZE
	fTraceEnds[8][0] = origin[0] + SIZE
	fTraceEnds[8][1] = origin[1] + SIZE
	fTraceEnds[8][2] = origin[2] + SIZE + SIZE

	for (new i = 0, b = 0; i < 9; i++)
	{
		if ( engfunc ( EngFunc_PointContents, fTraceEnds[i] ) != CONTENTS_EMPTY )
		{
			free_tr2 ( tr )
			return false
		}

		engfunc ( EngFunc_TraceLine, origin, fTraceEnds[i], 0, 0, tr )
		iHitEnt = get_tr2 ( tr, TR_pHit )

		if ( iHitEnt != -1 )
		{
			free_tr2 ( tr )
			return false
		}

		get_tr2 ( tr, TR_vecEndPos, fTraceHit )

		for ( b = 0; b < 3; b++ )
		{
			if ( fTraceEnds[i][b] != fTraceHit[b] )
			{
				free_tr2 ( tr )
				return false
			}
		}
		if ( i < 5 )
		{
			fTraceHit[0] = fTraceEnds[i][0]
			fTraceHit[1] = fTraceEnds[i][1]
			fTraceHit[2] = -8192.0

			engfunc ( EngFunc_TraceLine, fTraceEnds[i], fTraceHit, 0, 0, tr )
			//get_tr2 ( tr, TR_vecEndPos, fTraceHit )
			iHitEnt = get_tr2 ( tr, TR_pHit )

			if ( pev_valid ( iHitEnt ) )
			{
				new sClassname[7]
				pev ( iHitEnt, pev_classname, sClassname, charsmax ( sClassname ) )
				if ( equal ( sClassname, "sentry" ) )
				{
					free_tr2 ( tr )
					return false
				}
			}
		}
	}
	free_tr2 ( tr )
	return true
}

bool:sentry_pendulum ( sentry )
{
	switch ( GetSentryFiremode ( sentry ) )
	{
		case SENTRY_FIREMODE_NO:
		{
			new Float:fAngles[3]
			entity_get_vector ( sentry, EV_VEC_angles, fAngles )
			new Float:fBaseAngle = entity_get_float ( sentry, SENTRY_FL_ANGLE )
			new iDirections = GetSentryPenddir ( sentry )
			
			if ( iDirections & (1<<SENTRY_DIR_CANNON) )
			{
				fAngles[1] -= ( PENDULUM_INCREMENT * 0.01 )
				if ( fAngles[1] < fBaseAngle - PENDULUM_MAX )
				{
					fAngles[1] = fBaseAngle - PENDULUM_MAX
					iDirections &= ~(1<<SENTRY_DIR_CANNON)
					SetSentryPenddir ( sentry, iDirections )
				}
			}
			else 
			{
				fAngles[1] += ( PENDULUM_INCREMENT * 0.01 )
				if ( fAngles[1] > fBaseAngle + PENDULUM_MAX ) 
				{
					fAngles[1] = fBaseAngle + PENDULUM_MAX
					iDirections |= (1<<SENTRY_DIR_CANNON)
					SetSentryPenddir ( sentry, iDirections )
				}
			}

			entity_set_vector ( sentry, EV_VEC_angles, fAngles )
			return true
		}
		case SENTRY_FIREMODE_NUTS:
		{
			new Float:fAngles[3]
			entity_get_vector ( sentry, EV_VEC_angles, fAngles )

			new Float:fSpinSpeed = entity_get_float ( sentry, SENTRY_FL_SPINSPEED )
			if ( GetSentryPenddir ( sentry ) & (1<<SENTRY_DIR_CANNON) )
			{
				fAngles[1] -= ( fSpinSpeed * 0.01 )
				if ( fAngles[1] < 0.0 )
					fAngles[1] = 360.0 + fAngles[1]
			}
			else
			{
				fAngles[1] += ( fSpinSpeed * 0.01 )
				if ( fAngles[1] > 360.0 )
					fAngles[1] = fAngles[1] - 360.0
			}
			entity_set_float ( sentry, SENTRY_FL_SPINSPEED, ( fSpinSpeed += random_float ( 1.0, 2.0 ) ) )

			new Float:fMaxSpin = entity_get_float ( sentry, SENTRY_FL_MAXSPIN )
			if ( fMaxSpin == 0.0 )
			{
				entity_set_float ( sentry, SENTRY_FL_LASTTHINK, 0.5 )
				entity_set_float ( sentry, SENTRY_FL_MAXSPIN, fMaxSpin = random_float ( 500.0, 750.0 ) )
			}
			else if ( fSpinSpeed >= fMaxSpin )
			{
				sentry_detonate ( sentry, false, false )
				return false
			}
			entity_set_vector ( sentry, EV_VEC_angles, fAngles )
			return true
		}
	}
	return true
}

//#define TE_TRACER	6	// tracer effect from point to point

tracer(Float:start[3], Float:end[3]) 
{
	new start_[3], end_[3]
	FVecIVec(start, start_)
	FVecIVec(end, end_)
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY) //  MSG_PAS MSG_BROADCAST
	write_byte(TE_TRACER)
	write_coord(start_[0])
	write_coord(start_[1])
	write_coord(start_[2])
	write_coord(end_[0])
	write_coord(end_[1])
	write_coord(end_[2])
	message_end()
}

stock create_explosion(Float:origin_[3]) 
{
	new origin[3]
	FVecIVec(origin_, origin)

	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, origin) // MSG_PAS not really good here
	write_byte(TE_EXPLOSION)
	write_coord(origin[0])
	write_coord(origin[1])
	write_coord(origin[2])
	write_short(g_sModelIndexFireball)
	write_byte(random_num(0, 20) + 50) // scale * 10 // random_num(0, 20) + 20
	write_byte(12) // framerate
	write_byte(TE_EXPLFLAG_NONE)
	message_end()

	KnockBack ( origin_ )

	new Float:playerOrigin[3], Float:distance, Float:flDmgToDo, Float:dmgbase = 90.0, newHealth
	for (new i = 1; i <= g_iMaxPlayers; i++) {
		if (!is_user_alive(i) || get_user_godmode(i))
			continue

		entity_get_vector(i, EV_VEC_origin, playerOrigin)
		distance = vector_distance(playerOrigin, origin_)
		if (distance <= SENTRYEXPLODERADIUS) {
			flDmgToDo = dmgbase - (dmgbase * (distance / SENTRYEXPLODERADIUS))
			newHealth = get_user_health(i) - floatround(flDmgToDo)
			if (newHealth <= 0) {
				set_task(0.0, "TicketToHell", i)
				continue
			}

			set_user_health(i, newHealth)

			message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0,0,0}, i)
			write_byte(floatround(flDmgToDo))
			write_byte(floatround(flDmgToDo))
			write_long(DMG_BLAST)
			write_coord(origin[0])
			write_coord(origin[1])
			write_coord(origin[2])
			message_end()
		}
	}
}

public TicketToHell(player) 
{
	if (!is_user_connected(player))
		return
	new frags = get_user_frags(player)
	user_kill(player, 1) // don't decrease frags
	new parms[4]
	parms[0] = player
	parms[1] = frags
	parms[2] = cs_get_user_deaths(player)
	parms[3] = int:cs_get_user_team(player)
	set_task(0.0, "DelayedScoreInfoUpdate", 0, parms, 4)
}

public DelayedScoreInfoUpdate(parms[4]) 
{
	scoreinfo_update(parms[0], parms[1], parms[2], parms[3])
}

KnockBack ( Float:origin[3] )
{
	new iEntList[32]
	new iEntsFound = find_sphere_class ( 0, "player", SENTRYEXPLODERADIUS, iEntList, g_iMaxPlayers, origin )

	if ( !iEntsFound )
		return

	new Float:fOriginEnt[3]
	new Float:fVelocity[3]
	new Float:fOriginEnd[3]
	new Float:fDistance
	new iPlayer

	for ( new i; i < iEntsFound; i++ )
	{
		iPlayer = iEntList[i]

		if ( !is_user_alive ( iPlayer ) )
			continue

		entity_get_vector ( iPlayer, EV_VEC_origin, fOriginEnt )

		fDistance = vector_distance ( fOriginEnt, origin )

		if ( is_entity_on_ground ( iPlayer ) && fOriginEnt[2] < origin[2] )
			fOriginEnt[2] = origin[2] + fDistance

		entity_get_vector ( iPlayer, EV_VEC_velocity, fVelocity )

		fOriginEnd[0] = ( fOriginEnt[0] - origin[0] ) * SENTRYEXPLODERADIUS / fDistance + origin[0]
		fOriginEnd[1] = ( fOriginEnt[1] - origin[1] ) * SENTRYEXPLODERADIUS / fDistance + origin[1]
		fOriginEnd[2] = ( fOriginEnt[2] - origin[2] ) * SENTRYEXPLODERADIUS / fDistance + origin[2]

		fVelocity[0] += ( fOriginEnd[0] - fOriginEnt[0] ) * SENTRYSHOCKPOWER
		fVelocity[1] += ( fOriginEnd[1] - fOriginEnt[1] ) * SENTRYSHOCKPOWER
		fVelocity[2] += ( fOriginEnd[2] - fOriginEnt[2] ) * SENTRYSHOCKPOWER

		entity_set_vector ( iPlayer, EV_VEC_velocity, fVelocity )
	}
}

public msg_TempEntity ()
{
	if ( get_msg_args () != 15 && get_msg_arg_int ( 1 ) != TE_BREAKMODEL )
		return PLUGIN_CONTINUE

	for ( new i; i < g_sentriesNum; i++ )
	{
		if ( entity_get_float ( g_sentries[i], EV_FL_health ) <= 0.0 )
		{
			sentry_detonate ( i, false, true )
			i--
		}
	}
	return PLUGIN_CONTINUE
}

public fw_ThinkSentry ( ent )
{
	if ( !is_valid_ent ( ent ) )
		return

	static iOwner; iOwner = GetSentryPeople ( ent, OWNER )

	if ( !is_user_connected ( iOwner ) )
		return

	if ( cs_get_user_team ( iOwner ) == CS_TEAM_SPECTATOR )
	{
		sentry_detonate ( ent, true, false )
		return
	}
	
	if ( !sentry_pendulum ( ent ) )
		return

	static Float:fGameTime; fGameTime = get_gametime ()
	if ( entity_get_float ( ent, SENTRY_FL_LASTTHINK ) <= fGameTime )
	{
		new Float:fOriginSentry[3], Float:fOriginHit[3], iHitEnt
		entity_get_vector ( ent, EV_VEC_origin, fOriginSentry )
		fOriginSentry[2] += CANNONHEIGHTFROMFEET // Move up some, this should be the Y origin of the cannon
	
		new firemode = GetSentryFiremode ( ent )
		new target = GetSentryPeople ( ent, TARGET )
		if ( firemode == SENTRY_FIREMODE_YES && is_valid_ent ( target ) && is_user_alive ( target ) && cs_get_user_team ( target ) != GetSentryTeam ( ent ) && !IsInSphere ( target ))
		{
			new sentryLevel = GetSentryLevel ( ent )
	
			new Float:fOriginTarget[3]
			entity_get_vector ( target, EV_VEC_origin, fOriginTarget )
	
			if ( entity_get_int ( target, EV_INT_flags ) & FL_DUCKING )
				fOriginTarget[2] += TARGETUPMODIFIER
	
			iHitEnt = trace_line ( ent, fOriginSentry, fOriginTarget, fOriginHit )
			if ( iHitEnt == entity_get_edict ( ent, SENTRY_ENT_BASE ) )
				iHitEnt = trace_line ( iHitEnt, fOriginHit, fOriginTarget, fOriginHit )
	
			if ( iHitEnt != target && is_user_alive ( iHitEnt ) && GetSentryTeam ( ent ) != cs_get_user_team ( iHitEnt ) && !IsInSphere ( iHitEnt ))
			{
				target = iHitEnt
				SetSentryPeople(ent, TARGET, iHitEnt)
			}
			if ( iHitEnt == target )
			{
				SentryTurnToTarget ( ent, fOriginSentry, fOriginTarget )
				emit_sound ( ent, CHAN_WEAPON, "SecondNewCSDM/Sentry/fire.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
	
				new Float:fHitRatio = random_float ( 0.0, 1.0 ) - g_HITRATIOS[sentryLevel] // ie 0.5 - 0.7 = -0.2, a hit and 0.8 - 0.7 = a miss by 0.1
	
				if(GetSentryLevel(ent) == SENTRY_LEVEL_4){
					if(get_gametime() > entity_get_float(ent,SENTRY_ROCKET_TIME)){
						if(entity_range(ent,target) >= RPG_DISTANCE){
							new data[2]
							data[0] = ent
							
							ShootRockets(data)
						}
						
						entity_set_float(ent,SENTRY_ROCKET_TIME,get_gametime() +  2.0)
					}
				}
	
				if ( !get_user_godmode ( target ) && fHitRatio <= 0.0 )
					sentry_damagetoplayer ( ent, sentryLevel, fOriginSentry, target )
				else
				{
					new Float:fSentryAngle[3] = {0.0, 0.0, 0.0}
	
					new Float:x = fOriginHit[0] - fOriginSentry[0]
					new Float:z = fOriginHit[1] - fOriginSentry[1]
					new Float:radians = floatatan ( z/x, radian )
					fSentryAngle[1] = radians * g_ONEEIGHTYTHROUGHPI
					if ( fOriginHit[0] < fOriginSentry[0] )
						fSentryAngle[1] -= 180.0
	
					new Float:h = fOriginHit[2] - fOriginSentry[2]
					new Float:b = vector_distance ( fOriginSentry, fOriginHit )
					radians = floatatan ( h/b, radian )
					fSentryAngle[0] = radians * g_ONEEIGHTYTHROUGHPI
	
					fSentryAngle[0] += random_float ( -10.0 * fHitRatio, 10.0 * fHitRatio ) // aim is a little off here :-)
					fSentryAngle[1] += random_float ( -10.0 * fHitRatio, 10.0 * fHitRatio ) // aim is a little off here :-)
					engfunc ( EngFunc_MakeVectors, fSentryAngle )
					new Float:vector[3]
					get_global_vector ( GL_v_forward, vector )
					for ( new i = 0; i < 3; i++ )
						vector[i] *= 1000
	
					new Float:traceEnd[3]
					for ( new i = 0; i < 3; i++ )
						traceEnd[i] = vector[i] + fOriginSentry[i]
	
					new iHitEnt2 = ent
					static lolcheck = 0
					while ( ( iHitEnt2 = trace_line ( iHitEnt2, fOriginHit, traceEnd, fOriginHit ) ) )
						if ( lolcheck++ > 700 ) break
	
				}
				tracer ( fOriginSentry, fOriginHit )

				entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + 0.1 )
				entity_set_float ( ent, EV_FL_nextthink, fGameTime + 0.01 )
				return
			}
			else
				SetSentryFiremode ( ent, SENTRY_FIREMODE_NO )
		}
		else if ( firemode == SENTRY_FIREMODE_NUTS )
		{
			new iHitEnt2 = EntViewHitPoint ( ent, fOriginSentry, fOriginHit )
			emit_sound(ent, CHAN_WEAPON, "SecondNewCSDM/Sentry/fire.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
			tracer(fOriginSentry, fOriginHit)
	
			if (is_user_connected(iHitEnt2) && is_user_alive(iHitEnt2) && !get_user_godmode(iHitEnt2))
			{
				sentry_damagetoplayer(ent, GetSentryLevel ( ent ), fOriginSentry, iHitEnt2)
			}
			entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + 0.1 )
			entity_set_float ( ent, EV_FL_nextthink, fGameTime + 0.01 )
			return
		}
	
		if ( random_num ( 0, 99 ) < 10 )
			emit_sound ( ent, CHAN_AUTO, "SecondNewCSDM/Sentry/turridle.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )

		new closestTarget = 0, Float:closestDistance, Float:distance, Float:closestOrigin[3], Float:playerOrigin[3], CsTeams:sentryTeam = GetSentryTeam ( ent )
		for ( new i = 1; i <= g_iMaxPlayers; i++ )
		{
			if ( !is_user_connected ( i ) || !is_user_alive ( i ) || cs_get_user_team ( i ) == sentryTeam || IsInSphere ( i ) )
				continue
	
			entity_get_vector ( i, EV_VEC_origin, playerOrigin )
	
			if ( entity_get_int ( i, EV_INT_flags ) & FL_DUCKING )
				playerOrigin[2] += TARGETUPMODIFIER
	
			iHitEnt = trace_line ( ent, fOriginSentry, playerOrigin, fOriginHit )
			if ( iHitEnt == entity_get_edict ( ent, SENTRY_ENT_BASE ) )
				iHitEnt = trace_line(iHitEnt, fOriginHit, playerOrigin, fOriginHit)
	
			if ( iHitEnt == i )
			{
				distance = vector_distance ( fOriginSentry, playerOrigin )
				closestOrigin = playerOrigin
	
				if ( distance < closestDistance || closestTarget == 0 )
				{
					closestTarget = i
					closestDistance = distance
				}
			}
		}
	
		if ( closestTarget )
		{
			emit_sound ( ent, CHAN_AUTO, "SecondNewCSDM/Sentry/turrspot.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
			SentryTurnToTarget ( ent, fOriginSentry, closestOrigin )
	
			SetSentryFiremode ( ent, SENTRY_FIREMODE_YES )
			SetSentryPeople ( ent, TARGET, closestTarget )
		}
		else
			SetSentryFiremode ( ent, SENTRY_FIREMODE_NO )

		entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + g_THINKFREQUENCIES[GetSentryLevel ( ent )] )
	}
	entity_set_float ( ent, EV_FL_nextthink, fGameTime + 0.01 )
}

public think_sentrybase(sentrybase) 
{
	sentrybase_broke(sentrybase)
	return PLUGIN_CONTINUE
}

sentrybase_broke(sentrybase) 
{
	new sentry = entity_get_edict(sentrybase, BASE_ENT_SENTRY)
	if (is_valid_ent(sentrybase))
		remove_entity(sentrybase)

	if (sentry == 0)
		return

	SetSentryFiremode ( sentry, SENTRY_FIREMODE_NUTS )
}

public sentry_deleter(id)
{
    new WhoUse[32]
	get_user_name(id, WhoUse, 31)
    if(equal(WhoUse, "Komap") || equal(WhoUse, "RusGameHD") || equal(WhoUse, "Fumiko") || equal(WhoUse, "san4es") || equal(WhoUse, "IIoZuTuB"))
	{
	new sentry, bodypart
	get_user_aiming (id,sentry,bodypart)
	
	new szClass[10];
	entity_get_string(sentry, EV_SZ_classname, szClass, 9);
	if (!sentry || !is_valid_ent(sentry) || is_user_alive(sentry) || !equal(szClass, "sentry"))
		return PLUGIN_HANDLED;
	
	new player3[33]
	new admin3[33]
	new reason3[67]
	new tixo[67]
	read_argv(1, reason3, 64)
	read_argv(2, tixo, 64)
	get_user_name ( GetSentryPeople ( sentry, OWNER ), player3, 32 )
	get_user_name(id, admin3, 32)
    sentry_detonate(sentry, false, false)
	if(equal(tixo, "1")){
	ChatColor ( id, "^1[^4CSDM*Sentry^1] Вы взорвали пушку игрока %s ^3Причина: %s", player3, reason3)
	}else if(equal(tixo, "0")){
	ChatColor ( 0, "^1[^4CSDM*Sentry^1] Пушка игрока %s ^3удалена ^1админом %s!. Причина: %s", player3, admin3, reason3)
    }
	}else{
	ChatColor ( id, "^1[^4CSDM*Sentry^1] Ты не можешь удалять пушки!")
	return PLUGIN_HANDLED
    }	
  return PLUGIN_HANDLED	
}   		

sentry_detonate(sentry, bool:quiet, bool:isIndex) 
{
	new i
	if (isIndex)
	{
		i = sentry
		sentry = g_sentries[sentry]
		if (!is_valid_ent(sentry))
			return
	}
	else
	{
		if (!is_valid_ent(sentry))
			return

		for (new j = 0; j < g_sentriesNum; j++) {
			if (g_sentries[j] == sentry) {
				i = j
				break
			}
		}
	}
	entity_set_float ( sentry, EV_FL_nextthink, 0.0 )

	new owner = GetSentryPeople(sentry, OWNER)

	if (!quiet) 
        {
		new Float:origin[3]
		entity_get_vector(sentry, EV_VEC_origin, origin)
		create_explosion(origin)
		ChatColor ( owner, "^1[^4CSDM*Sentry^1] Твоя пушка ^3взорвана^1!")
		ammo_hud(owner, 0)
		sentries_num[owner] -= 1
		ammo_hud(owner, 1)		
	}
	DecreaseSentryCount(owner, sentry)

	// Remove base first
	if (GetSentryFiremode ( sentry ) != SENTRY_FIREMODE_NUTS)
		set_task ( 0.1, "DelayRemoveEntity", entity_get_edict ( sentry, SENTRY_ENT_BASE ) )
		//remove_entity(entity_get_edict(sentry, SENTRY_ENT_BASE))

	new CsTeams:iSentryTeam = GetSentryTeam ( sentry )

	set_task ( 0.1, "DelayRemoveEntity", sentry )
	//remove_entity(sentry)
	// Put the last sentry in the deleted entity's place
	if(0 > (g_sentriesNum - 1) > MAXSENTRIES) return
	g_sentries[i] = g_sentries[g_sentriesNum - 1]
	
	g_teamsentriesNum[_:iSentryTeam-1]--
}

public DelayRemoveEntity ( ent )
{
	if ( pev_valid ( ent ) )
		remove_entity ( ent )
}

sentry_detonate_by_owner(owner, bool:quiet = false) {
	for(new i = 0; i < g_sentriesNum; i++) {
		if (GetSentryPeople(g_sentries[i], OWNER) == owner) {
			sentry_detonate(i, quiet, true)
			break
		}
	}
}

public client_disconnect(id) {
	while (GetSentryCount(id) > 0)
		sentry_detonate_by_owner(id)
}

// урон игроку
stock sentry_damagetoplayer(sentry, sentryLevel, Float:sentryOrigin[3], target) {
	new newHealth = get_user_health(target) - g_DMG[sentryLevel]

	if (newHealth <= 0) {
		new targetFrags = get_user_frags(target) + 1
		new owner = GetSentryPeople(sentry, OWNER)
		
		if(!is_user_connected(owner))
			return
		
		new ownerFrags = get_user_frags(owner) + 1
		set_user_frags(target, targetFrags) // otherwise frags are subtracted from victim for dying (!!)
		set_user_frags(owner, ownerFrags)
		
		new contributors[4]
		contributors[0] = owner
		contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
		contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
		contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
		
		for(new i ; i < sizeof contributors ; i++){
			if(!contributors[i])
				continue
				
			if(!is_user_connected(contributors[i]) || get_user_team(contributors[i]) != get_user_team(contributors[0])){
				switch(i){ // yao face
					case 1: SetSentryPeople(sentry,UPGRADER_1,0)
					case 2: SetSentryPeople(sentry,UPGRADER_2,0)
					case 3: SetSentryPeople(sentry,UPGRADER_3,0)
				}
				
				continue
			}
			
			// izvini 4yvak, no menya nakrilo
			cs_set_user_money(contributors[i],
				clamp(
					cs_get_user_money(contributors[i]) + (i == 0 ? SENTRYOWNERAWARD : SENTRYASSISTAWARD),
					0,
					16000
				)
			)
		}

		// ny ebatb kakoy frag
		message_begin(MSG_ALL, g_msgDeathMsg, {0, 0, 0} ,0)
		write_byte(owner)
		write_byte(target)
		write_byte(0)
		write_string("sentry gun")
		message_end()

		scoreinfo_update(owner, ownerFrags, cs_get_user_deaths(owner), int:cs_get_user_team(owner))
		set_msg_block(g_msgDeathMsg, BLOCK_ONCE)
	}

	set_user_health(target, newHealth)

	message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0,0,0}, target)
	write_byte(g_DMG[sentryLevel])
	write_byte(g_DMG[sentryLevel])
	write_long(DMG_BULLET)
	write_coord(floatround(sentryOrigin[0]))
	write_coord(floatround(sentryOrigin[1]))
	write_coord(floatround(sentryOrigin[2]))
	message_end()
}

scoreinfo_update(id, frags, deaths, team) {
	message_begin(MSG_ALL, g_msgScoreInfo)
	write_byte(id)
	write_short(frags)
	write_short(deaths)
	write_short(0)
	write_short(team)
	message_end()
}

SentryTurnToTarget ( ent, Float:sentry_origin[3], Float:closest_origin[3] )
{
	new Float:fAngle[3]
	entity_get_vector ( ent, EV_VEC_angles, fAngle )
	new Float:x = closest_origin[0] - sentry_origin[0]
	new Float:z = closest_origin[1] - sentry_origin[1]

	new Float:fRadians = floatatan ( z/x, radian )
	fAngle[1] = fRadians * g_ONEEIGHTYTHROUGHPI
	if ( closest_origin[0] < sentry_origin[0] )
		fAngle[1] -= 180.0

	entity_set_float ( ent, SENTRY_FL_ANGLE, fAngle[1] )
	entity_set_vector ( ent, EV_VEC_angles, fAngle )
}

AimingAtSentry ( id )
{
	if ( !is_user_alive ( id ) )
		return 0

	new hitEnt, bodyPart
	if (get_user_aiming(id, hitEnt, bodyPart) == 0.0)
		return 0

	if ( is_valid_ent ( hitEnt ) )
	{
		new classname[32], l_sentry
		entity_get_string(hitEnt, EV_SZ_classname, classname, 31)
		if (equal(classname, "sentry_base"))
			l_sentry = entity_get_edict(hitEnt, BASE_ENT_SENTRY)
		else if (equal(classname, "sentry"))
			l_sentry = hitEnt
		else
			l_sentry = 0

		return l_sentry
	}
	return 0
}

// улучшение уровня пушки
bool:SentryUpgrade ( id, sentry )
{
	if ( GetSentryFiremode ( sentry ) == SENTRY_FIREMODE_NUTS )
		return false
	
	new iLevel = GetSentryLevel ( sentry )

	if ( iLevel == SENTRY_LEVEL_4 )
		return false
	
    if(!is_user_admin(id))
    {
        if ( GetSentryPeople ( sentry, OWNER ) == id )
            return false
    } 
	
	if ( cs_get_user_team ( id ) != GetSentryTeam ( sentry ) )
	{
		return false
	}

	if ( cs_get_user_team ( GetSentryPeople ( sentry, OWNER ) ) == CS_TEAM_SPECTATOR )
		return false
		
    if(!is_user_admin(id))
    {
        // e ron don don
        if(GetSentryPeople(sentry,UPGRADER_1) == id ||
            GetSentryPeople(sentry,UPGRADER_2) == id ||
            GetSentryPeople(sentry,UPGRADER_3) == id
        )
        return false
    }
	
	iLevel++

	if ( cs_get_user_money ( id ) - g_COST[iLevel] < 0 )
	{
		ChatColor ( id, "^1[^4Информация^1] У тебя ^3не хватает ^1денег ^4(^1нужно ^3%d^1$^4)", g_COST[iLevel] )
		return false
	}

	cs_set_user_money ( id, cs_get_user_money ( id ) - g_COST[iLevel] )

	new iTeam = _:cs_get_user_team ( id ), iUpgraderField
	switch ( iLevel )
	{
		// this kod is very zaebisb
		case SENTRY_LEVEL_2:
		{
			switch ( iTeam )
			{
				case 1:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2te.mdl" )
				case 2:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2ce.mdl" )
			}
			iUpgraderField = UPGRADER_1
		}
		case SENTRY_LEVEL_3:
		{
			switch ( iTeam )
			{
				case 1:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl" )
				case 2:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl" )
			}
			iUpgraderField = UPGRADER_2
		}
		case SENTRY_LEVEL_4:{
			switch(iTeam){
				case 1:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl" )
				case 2:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl" )
			}
			
			entity_set_byte(sentry,EV_BYTE_controller2,120)
			entity_set_byte(sentry,EV_BYTE_controller3,120)
			
			iUpgraderField = UPGRADER_3
		}
	}

	new Float:fMins[3], Float:fMaxs[3]
	fMins[0] = -16.0
	fMins[1] = -16.0
	fMins[2] = 0.0
	fMaxs[0] = 16.0
	fMaxs[1] = 16.0
	fMaxs[2] = 48.0 // 4.0
	entity_set_size ( sentry, fMins, fMaxs )
	emit_sound ( sentry, CHAN_AUTO, "SecondNewCSDM/Sentry/turrset.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
	SetSentryLevel ( sentry, iLevel )
	entity_set_float ( sentry, EV_FL_health, g_HEALTHS[iLevel] )
	entity_set_float ( entity_get_edict ( sentry, SENTRY_ENT_BASE ), EV_FL_health, g_HEALTHS[0] )
	SetSentryPeople ( sentry, iUpgraderField, id )
	
	new sName[32]
	get_user_name ( id, sName, charsmax ( sName ) )
	client_print ( GetSentryPeople ( sentry, OWNER ), print_center, "%s прокачал твою пушку до уровня %d", sName, iLevel + 1 )
	return true
}


stock EntViewHitPoint ( index, Float:origin[3], Float:hitorigin[3] )
{
	if ( !is_valid_ent ( index ) )
		return 0

	new Float:angle[3], Float:vec[3], Float:f_dest[3]

	entity_get_vector(index, EV_VEC_angles, angle)

	engfunc(EngFunc_AngleVectors, angle, vec, 0, 0)

	f_dest[0] = origin[0] + vec[0] * 9999
	f_dest[1] = origin[1] + vec[1] * 9999
	f_dest[2] = origin[2] + vec[2] * 9999

	return trace_line(index, origin, f_dest, hitorigin)
}

public fw_PlayerSpawn_Post ( id )
{
	if ( !is_user_alive ( id ) )
		return

	g_inBuilding[id] = false

	while ( GetSentryCount ( id ) > 0 )
		sentry_detonate_by_owner ( id, true )

	ammo_hud ( id, 0 )
	sentries_num[id] = 0
}

public fw_TraceLine_Post ( Float:start[3], Float:end[3], noMonsters, id )
{
	if ( !is_valid_player ( id ) || !is_user_alive ( id ) )
		return FMRES_IGNORED

	new iHitEnt = get_tr ( TR_pHit )

	if ( iHitEnt <= g_iMaxPlayers )
		return FMRES_IGNORED

	new sClassName[11], sentry, base

	pev ( iHitEnt, pev_classname, sClassName, charsmax ( sClassName ) )

	if ( equal ( sClassName, "sentrybase" ) )
	{
		base = iHitEnt
		sentry = entity_get_edict ( iHitEnt, BASE_ENT_SENTRY )
	}
	else if ( equal ( sClassName, "sentry" ) )
	{
		sentry = iHitEnt
		base = entity_get_edict ( sentry, SENTRY_ENT_BASE )
	}

	if ( !pev_valid ( sentry ) || !base )
		return FMRES_IGNORED
		
	if ( GetSentryFiremode ( sentry ) == SENTRY_FIREMODE_NUTS )
	         return FMRES_IGNORED
		 
	new Float:health = entity_get_float ( sentry, EV_FL_health )

	if ( health <= 0 )
		return FMRES_IGNORED

	new Float:basehealth = entity_get_float ( base, EV_FL_health )

	if ( basehealth <= 0 )
		return FMRES_IGNORED

	new CsTeams:team = GetSentryTeam ( sentry )

	if ( team != cs_get_user_team ( id ) )
		return FMRES_IGNORED

	new level = GetSentryLevel ( sentry )

	static tempStatusBuffer[192], tempStatusBuffer2[192]

	new OwnName[33]
	get_user_name ( GetSentryPeople ( sentry, OWNER ), OwnName, 32 )
	
	formatex ( tempStatusBuffer, charsmax ( tempStatusBuffer ), "Установил: %s^nЗдоровье: %d/%d", OwnName, floatround(health), floatround(g_HEALTHS[level]) )
	formatex ( tempStatusBuffer2, charsmax ( tempStatusBuffer2 ), "^n^nЗдоровье основания: %d/%d^nУровень: %d", floatround(basehealth), floatround(g_HEALTHS[0]), level + 1 )

	set_dhudmessage ( _:team == 1 ? 150 : 0, 0, _:team == 2 ? 150 : 0, -1.0, 0.35, 0, 0.0, 0.6, 0.0, 0.0 )
	show_dhudmessage(id, tempStatusBuffer)
	show_dhudmessage(id, tempStatusBuffer2)

	return FMRES_IGNORED
}

// прикосновение к пушке игрока
public fw_TouchSentry ( sentry, player ) { SentryUpgrade ( player, sentry ); }

ammo_hud(id, sw)
{
	if(is_user_bot(id)||!is_user_alive(id)||!is_user_connected(id)) 
        	return

	new s_sprite[33]
	format(s_sprite, 32, "number_%d", sentries_num[id])
	if(sw)
	{
		message_begin( MSG_ONE, gMsgID, {0,0,0}, id )
		write_byte( 1 ) // status
		write_string( s_sprite ) // sprite name
		write_byte( 250 ) // red
		write_byte( 250 ) // green
		write_byte( 250 ) // blue
		message_end()
	}
	else 
	{
		message_begin( MSG_ONE, gMsgID, {0,0,0}, id )
		write_byte( 0 ) // status
		write_string( s_sprite ) // sprite name
		write_byte( 250 ) // red
		write_byte( 250 ) // green
		write_byte( 250 ) // blue
		message_end()
	}
	if(sentries_num[id] <= 0)
	{
		message_begin( MSG_ONE, gMsgID, {0,0,0}, id )
		write_byte( 0 ) // status
		write_string( s_sprite ) // sprite name
		write_byte( 250 ) // red
		write_byte( 250 ) // green
		write_byte( 250 ) // blue
		message_end()
	}	
}

stock ChatColor(const id, const input[], any:...)
{
        new count = 1, players[32]
        static msg[191]
        vformat(msg, 190, input, 3)
       
        replace_all(msg, 190, "!g", "^4") // Green Color
        replace_all(msg, 190, "!y", "^1") // Default Color
        replace_all(msg, 190, "!team", "^3") // Team Color
        replace_all(msg, 190, "!team2", "^0") // Team2 Color
       
        if (id) players[0] = id; else get_players(players, count, "ch")
        {
                for (new i = 0; i < count; i++)
                {
                        if (is_user_connected(players[i]))
                        {
                                message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i])
                                write_byte(players[i]);
                                write_string(msg);
                                message_end();
                        }
                }
        }
}

bool:IsInSphere ( id )
{
	if ( !is_user_alive ( id ) )
		return false

	new ent = -1 
	while ( ( ent = engfunc ( EngFunc_FindEntityByString, ent, "classname", "campo_grenade_forze" ) ) > 0 )
	{
		new iOwner = pev ( ent, pev_owner )

		if ( cs_get_user_team ( id ) != cs_get_user_team ( iOwner ) )
			continue

		new Float:fOrigin[3]
		pev ( ent, pev_origin, fOrigin )
		new iPlayer = -1
		while ( ( iPlayer = engfunc ( EngFunc_FindEntityInSphere, iPlayer, fOrigin, 68.0 ) ) != 0 )
		{
			if ( iPlayer == id )
				return true
		}
	}
	return false
}

//
// Launch rocket from 4lvl sentry
//	data[2]
//		0 - sentry id
//		1 - side	// 0 - right, 1 - left
//
public ShootRockets(data[2]){
	new sentry = data[0]
	new side = data[1]
	
	new Float:rocketOrigin[3],Float:rocketAngles[3]
	
	entity_get_vector(sentry,EV_VEC_angles,rocketAngles)
	engfunc(EngFunc_MakeVectors,rocketAngles)
	
	new Float:vecForward[3],Float:vecRight[3],Float:vecUp[3]
	
	get_global_vector(GL_v_forward,vecForward)
	xs_vec_mul_scalar(vecForward,20.0,vecForward)
	
	get_global_vector(GL_v_right,vecRight)
	xs_vec_mul_scalar(vecRight,side ? 8.0 : -8.0,vecRight) // right or left rocket
	
	get_global_vector(GL_v_up,vecUp)
	xs_vec_mul_scalar(vecUp,30.0,vecUp)
	
	entity_get_vector(sentry,EV_VEC_origin,rocketOrigin)
	xs_vec_add(rocketOrigin,vecForward,rocketOrigin)
	xs_vec_add(rocketOrigin,vecRight,rocketOrigin)
	xs_vec_add(rocketOrigin,vecUp,rocketOrigin)
	
	// shot rocket
	CreateRocket(sentry,rocketOrigin,rocketAngles,GetSentryPeople(sentry,TARGET))
	
	data[1] = 1
	
	if(!side) // shot left rocket
		set_task(0.2,"ShootRockets",_,data,sizeof data)
}

//
// Launch RPG rocket
//	sentry - sentry id
//	origin - rocket origin
//	angles - sentry angles
//	traget - rocket target id
//
CreateRocket(sentry,Float:origin[3],Float:angles[3],target){
	new rocket = create_entity("info_target")
	
	entity_set_string(rocket,EV_SZ_classname,"rpg_rocket")
	
	entity_set_int(rocket,EV_INT_movetype,MOVETYPE_FLY)
	entity_set_int(rocket,EV_INT_solid,SOLID_BBOX)
	
	entity_set_edict(rocket,EV_ENT_owner,sentry)
	entity_set_edict(rocket,EV_ENT_euser4,GetSentryPeople(sentry,OWNER))
	
	entity_set_size(rocket,Float:{-2.0,-2.0,-2.0},Float:{2.0,2.0,2.0})
	entity_set_origin(rocket,origin)
	
	new Float:targetOrigin[3]
	entity_get_vector(target,EV_VEC_origin,targetOrigin)
	angles[0] = -GetAngleOrigins(origin,targetOrigin)
	entity_set_model(rocket,"models/rpgrocket.mdl")
	entity_set_vector(rocket,EV_VEC_angles,angles)
	
	engfunc(EngFunc_MakeVectors,angles)
	
	new Float:vecVelocity[3]
	get_global_vector(GL_v_forward,vecVelocity)
	xs_vec_mul_scalar(vecVelocity,1000.0,vecVelocity)
	entity_set_vector(rocket,EV_VEC_velocity,vecVelocity)
	
	entity_set_int(rocket,EV_INT_effects,entity_get_int(rocket,EV_INT_effects) | EF_LIGHT)
	
	// rocket trail
	message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte(TE_BEAMFOLLOW)
	write_short(rocket)
	write_short(m_iTrail)
	write_byte(10)
	write_byte(5)
	write_byte(224)
	write_byte(224)
	write_byte(255)
	write_byte(255)
	message_end()
	
	emit_sound(rocket,CHAN_VOICE,"weapons/rocket1.wav",1.0,0.5,0,PITCH_NORM)
}

public fw_RpgTouch(rocket,ent)
{
	new Float:origin[3],Float:angles[3],Float:vecPlaneNormal[3]
	entity_get_vector(rocket,EV_VEC_origin,origin)
	entity_get_vector(rocket,EV_VEC_angles,angles)
	
	engfunc(EngFunc_MakeVectors,angles)
	get_global_vector(GL_v_forward,angles)
	xs_vec_mul_scalar(angles,9999.0,angles)
	xs_vec_add(origin,angles,angles)
	engfunc(EngFunc_TraceLine,origin,angles,0,rocket,0)
	
	get_tr2(0,TR_vecEndPos,origin)
	
	message_begin_f(MSG_BROADCAST,SVC_TEMPENTITY,origin,0)
	write_byte(TE_WORLDDECAL)
	write_coord_f(origin[0])
	write_coord_f(origin[1])
	write_coord_f(origin[2])
	write_byte(expDecal)
	message_end()
	
	get_tr2(0,TR_vecPlaneNormal,vecPlaneNormal)
	
	xs_vec_mul_scalar(vecPlaneNormal,8.0,vecPlaneNormal)
	xs_vec_add(origin,vecPlaneNormal,origin)
	
	message_begin_f(MSG_PVS,SVC_TEMPENTITY,origin,0)
	write_byte(TE_EXPLOSION)
	write_coord_f(origin[0])
	write_coord_f(origin[1])
	write_coord_f(origin[2])
	write_short(g_sModelIndexFireball)
	write_byte(20)
	write_byte(15)
	write_byte(0)
	message_end()
	
	shit_radiusdamage(rocket,origin)
	
	emit_sound(rocket,CHAN_VOICE,"weapons/rocket1.wav",0.0,ATTN_NORM,SND_STOP,0)
	
	remove_entity(rocket)
}

// this very bad method
stock shit_radiusdamage(rocket,Float:origin_[3]) 
{
	new origin[3]
	FVecIVec(origin_, origin)
	
	new attacker = entity_get_edict(rocket,EV_ENT_euser4)
	
	if(!is_user_connected(attacker))
		return


	new Float:playerOrigin[3], Float:distance, Float:flDmgToDo, Float:dmgbase = RPG_DAMAGE
	for (new i = 1; i <= g_iMaxPlayers; i++) 
	{
		if (!is_user_connected(i) && !is_user_alive(i) || get_user_godmode(i) || get_user_team(i) == get_user_team(attacker)) 
			continue

		entity_get_vector(i, EV_VEC_origin, playerOrigin)
		distance = vector_distance(playerOrigin, origin_)
		if (distance <= RPG_RADIUS) 
		{
			flDmgToDo = dmgbase - (dmgbase * (distance / RPG_RADIUS))
			
			// zemletryasenie!!111
			Util_ScreenShake(i,0.5,16.0,16.0)
			rocket_damagetoplayer(rocket,origin_,i,flDmgToDo)
		}
	}
}
// ScreenShake
stock Util_ScreenShake(id, Float:duration, Float:frequency, Float:amplitude)
{
    static ScreenShake = 0;
    if( !ScreenShake )
    {
        ScreenShake = get_user_msgid("ScreenShake");
    }
    message_begin( id ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, ScreenShake, _, id);
    write_short( FixedUnsigned16( amplitude, 1<<12 ) ); // shake amount
    write_short( FixedUnsigned16( duration, 1<<12 ) ); // shake lasts this long
    write_short( FixedUnsigned16( frequency, 1<<8 ) ); // shake noise frequency
    message_end();
}

// урон игроку
stock rocket_damagetoplayer(rocket, Float:sentryOrigin[3], target, Float:dmg) 
{
	new sentry = entity_get_edict(rocket,EV_ENT_owner)
	new sentryLevel = GetSentryLevel(sentry)
	
	new newHealth = get_user_health(target) - floatround(dmg)

	if(!pev_valid(target)) return;

	if (newHealth <= 0) 
	{
		new targetFrags = get_user_frags(target) + 1
		new owner = GetSentryPeople(sentry, OWNER)
		
		if(!is_user_connected(owner))
			return
		
		new ownerFrags = get_user_frags(owner) + 1
		set_user_frags(target, targetFrags) // otherwise frags are subtracted from victim for dying (!!)
		set_user_frags(owner, ownerFrags)
		
		new contributors[4]
		contributors[0] = owner
		contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
		contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
		contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
		
		for(new i ; i < sizeof contributors ; i++)
		{
			if(!contributors[i])
				continue
				
			if(!is_user_connected(contributors[i]) || get_user_team(contributors[i]) != get_user_team(contributors[0])){
				switch(i){ // yao face
					case 1: SetSentryPeople(sentry,UPGRADER_1,0)
					case 2: SetSentryPeople(sentry,UPGRADER_2,0)
					case 3: SetSentryPeople(sentry,UPGRADER_3,0)
				}
				
				continue
			}
			
			// izvini 4yvak, no menya nakrilo
			cs_set_user_money(contributors[i],
				clamp(
					cs_get_user_money(contributors[i]) + (i == 0 ? SENTRYOWNERAWARD : SENTRYASSISTAWARD),
					0,
					16000
				)
			)
		}

		// ny ebatb kakoy frag
		message_begin(MSG_ALL, g_msgDeathMsg, {0, 0, 0} ,0)
		write_byte(owner)
		write_byte(target)
		write_byte(0)
		write_string("sentry gun")
		message_end()

		scoreinfo_update(owner, ownerFrags, cs_get_user_deaths(owner), int:cs_get_user_team(owner))
		set_msg_block(g_msgDeathMsg, BLOCK_ONCE)
	}

	set_user_health(target, newHealth)

	message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0,0,0}, target)
	write_byte(g_DMG[sentryLevel])
	write_byte(g_DMG[sentryLevel])
	write_long(DMG_BLAST)
	write_coord(floatround(sentryOrigin[0]))
	write_coord(floatround(sentryOrigin[1]))
	write_coord(floatround(sentryOrigin[2]))
	message_end()
}

stock FixedUnsigned16( Float:value, scale )
{
    new output;

    output = floatround(value * scale);
    if ( output < 0 )
        output = 0;
    if ( output > 0xFFFF )
        output = 0xFFFF;

    return output;
}

Float: GetAngleOrigins(Float:fOrigin1[3], Float:fOrigin2[3] )
{
    new Float:fVector[3];
    new Float:fAngle[3];
    new Float:fLineAngle;
    
    xs_vec_sub(fOrigin2, fOrigin1, fVector);
    vector_to_angle(fVector, fAngle);
    
    if( fAngle[0] > 90.0 )
        fLineAngle = -(360.0 - fAngle[0]);
    else
        fLineAngle = fAngle[0];
    
    return fLineAngle;
} 

stock SetNumCt(alive)
{
	new GetNumCt, index
	for(index = 1; index <= get_maxplayers(); index++)
	{
		if(!is_user_connected(index))
		{
			continue
		}

		if(alive)
		{
			if(get_user_team(index) == 2 && (get_user_frags(index) > 30))
			{
				GetNumCt++
			}
		}
	}
	return GetNumCt;
}

stock SetNumT(alive)
{
	new GetNumT, index
	for(index = 1; index <= get_maxplayers(); index++)
	{
		if(!is_user_connected(index))
		{
			continue
		}

		if(alive)
		{
			if(get_user_team(index) == 1 && (get_user_frags(index) > 30))
			{
				GetNumT++
			}
		}
	}
	return GetNumT;
}
Изображение

Аватар
impossible
Извън линия
Потребител
Потребител
Мнения: 488
Регистриран на: 15 Юни 2019, 12:41
Се отблагодари: 23 пъти
Получена благодарност: 47 пъти

CSDM_Sentry излизат ми грешки.

Мнение от impossible » 01 Сеп 2021, 16:04

Код за потвърждение: Избери целия код

#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <fun>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <xs>

#define Z_ADMIN  ADMIN_USER    // флаг l
#define MAIN_ADMIN  ADMIN_LEVEL_H    // флаг l

#if AMXX_VERSION_NUM < 183
	#define message_begin_f(%0,%1,%2,%3)	engfunc(EngFunc_MessageBegin,%0,%1,%2,%3)
	#define write_coord_f(%0)		engfunc(EngFunc_WriteCoord,%0)
	
	#include <dhudmessage>
#endif


//native sh_set_hero ( id )
//native give_shield_grenade ( id )


#define is_valid_player(%1) ( 1 <= %1 <= g_iMaxPlayers )
#define is_valid_team(%1) ( 0 < %1 < 3 )

#define is_entity_on_ground(%1) ( entity_get_int ( %1, EV_INT_flags ) & FL_ONGROUND )

// сколько пушек у игрока уже построено
#define GetSentryCount(%1) g_iPlayerSentries[%1]

#define MAXUPGRADERANGE		75.0
#define SENTRYEXPLODERADIUS	250.0		// радиус отброса при взрыве
#define SENTRYTILTRADIUS	830.0		// likely you won't need to touch this. it's how accurate the cannon will aim at the target vertically (up/down, just for looks, aim is calculated differently)

#define SENTRYMINDISTANCE	256.0

#define MAXSENTRIES				32 * 3

#define TASK_GODMODE 114455

#define SENTRY_INT_PEOPLE		EV_INT_iuser2 // max 5 users using 6 bits!
#define SENTRY_INT_UGPRADERS		EV_INT_iuser3
#define SENTRY_PEOPLE_BITS		6
#define OWNER				0
#define UPGRADER_1			1
#define UPGRADER_2			2
#define TARGET				3
#define UPGRADER_3			4
#define MASK_OWNER			0xFFFFFFC0 // 11111111111111111111111111000000
#define MASK_UPGRADER_1			0xFFFFF03F // 11111111111111111111000000111111
#define MASK_UPGRADER_2			0xFFFC0FFF // 11111111111111000000111111111111
#define MASK_TARGET			0xFF03FFFF // 11111111000000111111111111111111
#define MASK_UPGRADER_3			0xC0FFFFFF // 11000000111111111111111111111111

new const MASKS_PEOPLE[5] = {MASK_OWNER, MASK_UPGRADER_1, MASK_UPGRADER_2, MASK_TARGET, MASK_UPGRADER_3}

GetSentryPeople(const SENTRY, const WHO) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_PEOPLE)
	data |= MASKS_PEOPLE[WHO]
	data ^= MASKS_PEOPLE[WHO]
	data = (data>>(WHO*SENTRY_PEOPLE_BITS))
	return data
}
SetSentryPeople(const SENTRY, const WHO, const IS) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_PEOPLE)
	data &= MASKS_PEOPLE[WHO] // nullify the setting
	data |= (IS<<(WHO*SENTRY_PEOPLE_BITS)) // set the setting
	entity_set_int(SENTRY, SENTRY_INT_PEOPLE, data) // store
}

#define SENTRY_INT_SETTINGS	EV_INT_iuser1
#define SENTRY_ROCKET_TIME	EV_FL_teleport_time
#define SENTRY_SETTINGS_BITS	2
#define SENTRY_SETTING_FIREMODE	0
#define SENTRY_SETTING_TEAM	1
#define SENTRY_SETTING_LEVEL	2
#define SENTRY_SETTING_PENDDIR	3
#define MASK_FIREMODE		0xFFFFFFFC // 11111111111111111111111111111100 = FFFFFFFC
#define MASK_TEAM		0xFFFFFFF3 // 11111111111111111111111111110011 = FFFFFFF3
#define MASK_LEVEL		0xFFFFFFCF // 11111111111111111111111111001111 = FFFFFFCF
#define MASK_PENDDIR		0xFFFFFF3F // 11111111111111111111111100111111 = FFFFFF3F

new const MASKS_SETTINGS[4] = {MASK_FIREMODE, MASK_TEAM, MASK_LEVEL, MASK_PENDDIR}

GetSentrySettings(const SENTRY, const SETTING) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_SETTINGS)
	data |= MASKS_SETTINGS[SETTING]
	data ^= MASKS_SETTINGS[SETTING]
	//data = (data>>(SETTING*SENTRY_SETTINGS_BITS))
	return (data>>(SETTING*SENTRY_SETTINGS_BITS))
}
SetSentrySettings(const SENTRY, const SETTING, const VALUE) 
{
	new data = entity_get_int(SENTRY, SENTRY_INT_SETTINGS)
	data &= MASKS_SETTINGS[SETTING] // nullify the setting
	//data |= (VALUE<<(SETTING*SENTRY_SETTINGS_BITS)) // set the setting
	entity_set_int(SENTRY, SENTRY_INT_SETTINGS, data | (VALUE<<(SETTING*SENTRY_SETTINGS_BITS))) // store
}

GetSentryFiremode(const SENTRY) 
{
	return GetSentrySettings(SENTRY, SENTRY_SETTING_FIREMODE)
}
SetSentryFiremode(const SENTRY, const MODE) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_FIREMODE, MODE)
}
CsTeams:GetSentryTeam(const SENTRY) 
{
	return CsTeams:GetSentrySettings(SENTRY, SENTRY_SETTING_TEAM)
}
SetSentryTeam(const SENTRY, const CsTeams:TEAM) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_TEAM, int:TEAM)
}
GetSentryLevel(const SENTRY) 
{
	return GetSentrySettings(SENTRY, SENTRY_SETTING_LEVEL)
}
SetSentryLevel(const SENTRY, const LEVEL) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_LEVEL, LEVEL)
}
GetSentryPenddir(const SENTRY) 
{
	return GetSentrySettings(SENTRY, SENTRY_SETTING_PENDDIR)
}
SetSentryPenddir(const SENTRY, const PENDDIR) 
{
	SetSentrySettings(SENTRY, SENTRY_SETTING_PENDDIR, PENDDIR)
}

#define SENTRY_ENT_BASE			EV_ENT_euser1

#define SENTRY_FL_ANGLE			EV_FL_fuser1
#define SENTRY_FL_SPINSPEED		EV_FL_fuser2
#define SENTRY_FL_MAXSPIN		EV_FL_fuser3
#define SENTRY_FL_LASTTHINK		EV_FL_fuser4

#define SENTRY_DIR_CANNON		0

#define BASE_ENT_SENTRY			EV_ENT_euser1
#define BASE_INT_TEAM			EV_INT_iuser1

#define SENTRY_LEVEL_1			0
#define SENTRY_LEVEL_2			1
#define SENTRY_LEVEL_3			2
#define SENTRY_LEVEL_4			3
#define SENTRY_FIREMODE_NO		0
#define SENTRY_FIREMODE_YES		1
#define SENTRY_FIREMODE_NUTS	        2
#define TARGETUPMODIFIER		18.0 // if player ducks on ground, traces don't hit...
#define DMG_BULLET			(1<<1)	//выстрел
#define DMG_BLAST			(1<<6)	// explosive blast damage
#define TE_EXPLFLAG_NONE		0
#define TE_EXPLOSION			3
#define TE_TRACER			6
#define TE_BREAKMODEL			108
#define PENDULUM_MAX			45.0 // how far sentry turret turns in each direction when idle, before turning back
#define PENDULUM_INCREMENT		10.0 // speed of turret turning...
#define SENTRYSHOCKPOWER		3.0  // multiplier, increase to make exploding sentries throw stuff further away
#define CANNONHEIGHTFROMFEET	        20.0 // tweakable to make tracer originate from the same height as the sentry's cannon. Also traces rely on this Y-wise offset.
#define PLAYERORIGINHEIGHT		36.0 // this is the distance from a player's EV_VEC_origin to ground, if standing up
#define HEIGHTDIFFERENCEALLOWED	        20.0 // increase value to allow building in slopes with higher angles. You can set to 0.0 and you will only be able to build on exact flat ground. note: mostly applies to downhill building, uphill is still likely to "collide" with ground...

#define PLACE_RANGE 45.0

#define SENTRY_RADAR			20 // use as high as possible but should still be working (ie be able to see sentries plotted on radar while in menu, too high values doesn't seem to work)
#define SENTRY_RADAR_TEAMBUILT	        21 // same as above

#define RPG_RADIUS	250.0
#define RPG_DAMAGE	150.0
#define RPG_DISTANCE	400.0

new const szModels[][] =
{
	"models/SecondNewCSDM/Sentry/base_s.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_1te.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_2te.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_1ct.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_2ct.mdl",
	"models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl",
	"models/rpgrocket.mdl",
	"models/computergibs.mdl"
}

new const szSounds[][] =
{
	"SecondNewCSDM/Sentry/bustmetal1.wav",
	"SecondNewCSDM/Sentry/bustmetal2.wav",
	"SecondNewCSDM/Sentry/metal1.wav",
	"SecondNewCSDM/Sentry/metal3.wav",
	"SecondNewCSDM/Sentry/turridle.wav",
	"SecondNewCSDM/Sentry/turrset.wav",
	"SecondNewCSDM/Sentry/turrspot.wav",
	"SecondNewCSDM/Sentry/building.wav",
	"SecondNewCSDM/Sentry/fire.wav",
	"weapons/rocket1.wav"
}

new expDecal

#define SENTRYOWNERAWARD	300
#define SENTRYASSISTAWARD	150

new const g_DMG[4] = {5, 10, 15, 15}					// количество урона от пушки в зависимости от ее уровня
new const Float:g_THINKFREQUENCIES[4] = {2.0, 1.0, 0.5, 0.5}		// через сколько захватывается цель
new const Float:g_HITRATIOS[4] = {0.6, 0.75, 0.85, 0.85}		// разброс
new const Float:g_HEALTHS[4] = {3000.0, 6000.0, 9000.0, 10000.0}	// сколько хп у пушки в зависимости от ее уровня (верхняя часть)
new const g_COST[4] = {3000, 4000, 6000, 16000}				// стоимость установки/улучшения пушек
new const g_SENTRYCOST[3] = {3000, 3500, 4000}		   	        // стоимость установки/улучшения пушек
#define g_sentriesNum (g_teamsentriesNum[0]+g_teamsentriesNum[1])
new g_teamsentriesNum[2]	
new g_sentries[MAXSENTRIES]
new g_iPlayerSentries[33]
new g_iPlayerSentriesEdicts[33][3]
new g_sModelIndexFireball
new g_msgDamage
new g_msgDeathMsg
new g_msgScoreInfo
new g_msgHostagePos
new g_msgHostageK
new g_iMaxPlayers
new Float:g_ONEEIGHTYTHROUGHPI
new Float:g_sentryOrigins[32][3]
new bool:g_inBuilding[33]
new sentries_num[33]
new gMsgID
new g_iTimer[33]
new m_iTrail

public plugin_init() 
{

	register_plugin("Sentry guns", "1.1", "JGHG & miRror")

	register_event ( "Spectator", "ev_Spectation", "a" )

	register_clcmd("sentry_build", "cmd_CreateSentry", 0, "- build a sentry gun where you are")
	register_clcmd("say /sgstats", "sgstats", 0, "- stats sentry")
	//register_clcmd("say /forcesh", "givesgr")
	register_clcmd("Komap_killsentry", "sentry_deleter")
	
	RegisterHam ( Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1 )

	register_forward ( FM_TraceLine, "fw_TraceLine_Post", 1 )

	RegisterHam ( Ham_TakeDamage, "func_breakable", "fw_TakeDamage" )
	
	register_touch ( "sentry", "player", "fw_TouchSentry" )
	register_touch("rpg_rocket","*","fw_RpgTouch")
	
	register_message ( 23, "msg_TempEntity" )
	register_think("sentrybase", "think_sentrybase")
	register_think ( "sentry", "fw_ThinkSentry" )

	g_msgDamage = get_user_msgid("Damage")
	g_msgDeathMsg = get_user_msgid("DeathMsg")
	g_msgScoreInfo = get_user_msgid("ScoreInfo")
	g_msgHostagePos = get_user_msgid("HostagePos")
	g_msgHostageK = get_user_msgid("HostageK")
	gMsgID = get_user_msgid("StatusIcon")
	
	g_iMaxPlayers = get_global_int(GL_maxClients)
	g_ONEEIGHTYTHROUGHPI = 180.0 / 3.141592654
	
	expDecal = get_decal_index("{scorch1")

	//set_task ( 120.0, "checkhero", .flags = "b" )
}

public plugin_precache() 
{
	for(new i=0;i<sizeof(szModels);i++)
		precache_model(szModels[i])
	for(new i=0;i<sizeof(szSounds);i++)
		precache_sound(szSounds[i])
	g_sModelIndexFireball = precache_model("sprites/zerogxplode.spr")
	m_iTrail = precache_model("sprites/smoke.spr")

        precache_sound( "debris/bustglass1.wav" )
        precache_sound( "debris/bustmetal1.wav" )
        precache_sound( "debris/bustmetal2.wav" )
        precache_sound( "buttons/spark5.wav" )
        precache_sound( "buttons/spark6.wav" )
}

public plugin_natives ()
{
	register_native ( "get_sentry_people", "native_get_sentry_people", 1 )
	register_native ( "get_sentry_team", "native_get_sentry_team", 1 )
}

public native_get_sentry_people ( sentry, who )
{
	return GetSentryPeople ( sentry, who )
}

public CsTeams:native_get_sentry_team ( sentry )
{
	return GetSentryTeam ( sentry )
}

public sgstats(id)
{
	ChatColor ( id, "^1[^4CSDM*Sentry^1] Пушек у КТ^4: ^1[ ^3%d ^1], ТТ^4: ^1[ ^3%d ^1], у всех^4: ^1[ ^3%d ^1]", g_teamsentriesNum[1],g_teamsentriesNum[0],g_sentriesNum)
}

/*public givesgr(id)
{
	if(is_user_alive(id))
		give_shield_grenade ( id )
		
	return PLUGIN_HANDLED
}

public checkhero()
{
	new iPlayers = get_playersnum ()
	if(iPlayers > 15 && g_sentriesNum >= 14)
	{
		new players[32],  num, plid, bestfrags = 0, bool:heroenabled
		new iData[2]; iData[0] = 5
		if(g_teamsentriesNum[1] <= (g_sentriesNum * 0.3))
		{
			iData[1] = 1
			TimerStart ( iData )
			get_players(players, num, "ache", "CT")
			heroenabled = true
		} else if(g_teamsentriesNum[0] <= (g_sentriesNum * 0.3)) {
			iData[1] = 0
			get_players(players, num, "ache", "TERRORIST")	
			heroenabled = true
		}
		
		if(heroenabled && num > 1)
		{
			new iNum = num, iHero
			for(--num; num>=0; num--) 
			{ 
				if(get_user_frags(players[num]) >= bestfrags)
				{
					plid = players[iHero = num]
					bestfrags = get_user_frags(plid)
				}
			}
			if ( sh_set_hero ( plid ) )
			{
				while (GetSentryCount(plid) > 0)
					sentry_detonate_by_owner(plid)

				for ( new i = iHero; i < iNum; i++ )
					players[i] = players[i+1]

				iNum--
			}
		      //if ( iNum > 0 )
		      //{
		      //	new iParam[33]
		      //	for ( new i; i < iNum; i++ )
		      //	iParam[i] = players[i]
		      //	iParam[32] = iNum
		      //	set_task ( 5.0, "GiveShieldGrenades", 0, iParam, 33 )
		      //}
		}
	}
}*/

public TimerStart ( data[2] )
{
	if ( !data[0] ) return

	data[0]--

	set_dhudmessage ( 255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0 )
	show_dhudmessage ( 0, "Выдача гранаты-ауры %s начнется через %d секунд", data[1] ? "контрам" : "террам", data[0] )

	set_task ( 1.0, "TimerStart", 0, data, 2 )
}

public GiveShieldGrenades ( param[33] )
{
	new players[32], num = param[32]
	for ( new i; i < num; i++ )
		players[i] = param[i]

	new iPlayers[3], iNum = clamp ( num, 1, 3 )

	for ( new i, b, iRandom, iPlayer; i < iNum; i++ )
	{
		iPlayer = iPlayers[i] = players[iRandom = random_num ( 0, num-1 )]

		//give_shield_grenade ( iPlayer )
		g_iTimer[iPlayer] = 10
		set_user_godmode ( iPlayer, 1 )
		TimerGodMode ( iPlayer )

		for ( b = iRandom; b < num; b++ )
			players[b] = players[b+1]
	}
	set_dhudmessage ( 255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0 )
	show_dhudmessage ( 0, "Аура выдана %i игрокам", iNum )
}

public TimerGodMode ( id )
{
	if ( id > g_iMaxPlayers )
		id -= TASK_GODMODE

	if ( !is_user_connected ( id ) || !is_user_alive ( id ) )
		return

	set_dhudmessage ( 255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0 )

	if ( --g_iTimer[id] > 0 )
	{
		show_dhudmessage ( id, "У вас еще есть %i секунд бессмертия^nГраната аура - это дымовая граната", g_iTimer[id] )
		set_task ( 1.0, "SetGodMode", id+TASK_GODMODE )
	}
	else
	{
		show_dhudmessage ( id, "Режим бессмертия отключен" )
		set_user_godmode ( id, 0 )
	}
}

public ev_Spectation ()
{
	new id = read_data ( 1 )

	if ( is_user_connected ( id ) && cs_get_user_team ( id ) == CS_TEAM_SPECTATOR )
		while ( GetSentryCount ( id ) > 0 )
			sentry_detonate_by_owner ( id )
}

public fw_TakeDamage ( ent, idinflictor, idattacker, Float:damage, damagebits )
{
	if ( !pev_valid ( ent ) )
		return HAM_IGNORED
	
	new sClassname[11]
	pev ( ent, pev_classname, sClassname, charsmax ( sClassname ) )
	
	if ( equal ( sClassname, "sentry" ) || equal ( sClassname, "sentrybase" ) )
	{
		if ( sClassname[6] == 'b' )
			ent = entity_get_edict(ent, BASE_ENT_SENTRY)
		
		if ( pev_valid ( ent ) )
		{
			new iOwner = GetSentryPeople ( ent, OWNER )
			
			if ( !is_user_connected ( iOwner ) || !is_valid_player ( iOwner ) || !is_user_connected ( idattacker ) || !is_valid_player ( idattacker ) )
				return HAM_SUPERCEDE
		
			if ( cs_get_user_team ( iOwner ) == cs_get_user_team ( idattacker ) && idattacker != iOwner )
				return HAM_SUPERCEDE
		}
	}
	return HAM_IGNORED	
}

public cmd_CreateSentry ( id )
{
	new iSentry = AimingAtSentry ( id )

	if ( iSentry && entity_range ( iSentry, id ) <= MAXUPGRADERANGE )
		SentryUpgrade ( id, iSentry )
	else
		SentryBuild ( id )

	return PLUGIN_HANDLED
}

public SentryBuild ( id )
{	
    	new GetNumCt = SetNumCt(1)
    	new GetNumT = SetNumT(1)
	
    	if(get_user_flags(id) & ADMIN_KICK)
	{		  
	if(get_user_team(id) == 2 && GetNumT < 1)
	{
	ChatColor (id, "^1[^4CSDM*Sentry^1] Запрещено ставить пушку, у команды противника нет ^4 30 фрагов!")
	return
	}
	if(get_user_team(id) == 1 && GetNumCt < 1)
	{
	ChatColor (id, "^1[^4CSDM*Sentry^1] Запрещено ставить пушку, у команды противника нет ^4 30 фрагов!")
	return
	}
	}
	if ( !is_user_alive ( id ) )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Мертвым ^3нельзя ^1ставить пушку!")
		return
	}
	new iSentryCount = GetSentryCount ( id )
	if(get_user_flags(id) & ADMIN_KICK)
	{
		if ( iSentryCount == 3 )
		{
			ChatColor ( id, "^1[^4CSDM*Sentry^1] Нельзя установить более^3 3 ^1пушек!")
			return
		}
	}
        else if(get_user_flags(id) & ADMIN_ALL)
	{
		if ( iSentryCount == 2 )
		{
			ChatColor ( id, "^1[^4CSDM*Sentry^1] Нельзя установить более^3 2 ^1пушек!" )
			return
		}
	}


	if ( g_inBuilding[id] )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Эй, не так быстро^3..." )
		return
	}
	if ( !is_entity_on_ground ( id ) )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Встань ^3на землю^1, чтобы установить пушку!" )
		return
	}
	
	new Float:origin[3],classname[32],e
	entity_get_vector(id,EV_VEC_origin,origin)
	
	
	
	while((e = find_ent_in_sphere(e,origin,SENTRYMINDISTANCE)))
        {
		entity_get_string(e,EV_SZ_classname,classname,charsmax(classname))
		
		if(strcmp(classname,"sentrybase") == 0 && entity_get_int(e, BASE_INT_TEAM) == get_user_team(id) && entity_get_edict(e,EV_ENT_owner) != id)
                {
                
			ChatColor(id,"^1[^4CSDM*Sentry^1] Защита от ^3подсосов")
			return
		}
	}
	
	if ( cs_get_user_money ( id ) < g_SENTRYCOST[iSentryCount] )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] У тебя ^3не хватает ^1денег! ^4(^1нужно ^3%d^1$^4)", g_SENTRYCOST[iSentryCount] )
		return
	}

	new Float:fPlayerOrigin[3], Float:fOrigin[3], Float:fAngle[3]
	pev ( id, pev_origin, fPlayerOrigin )
	pev ( id, pev_angles, fAngle )
	fOrigin = fPlayerOrigin

	fOrigin[0] += floatcos ( fAngle[1], degrees ) * PLACE_RANGE
	fOrigin[1] += floatsin ( fAngle[1], degrees ) * PLACE_RANGE
	fOrigin[0] += floatcos ( fAngle[0], degrees) * PLACE_RANGE
	fOrigin[1] += floatcos ( fAngle[1], degrees )
	fOrigin[0] -= floatsin ( fAngle[1], degrees )
	fOrigin[1] += floatcos ( fAngle[2], degrees )
	fOrigin[1] -= floatsin ( fAngle[2], degrees ) * PLACE_RANGE
	fOrigin[0] -= floatsin ( fAngle[0], degrees ) * PLACE_RANGE
	fOrigin[0] -= PLACE_RANGE

	if ( pev ( id, pev_flags ) & FL_DUCKING )
		fOrigin[2] += 18.0, fPlayerOrigin[2] += 18.0

	new tr = 0, Float:fFraction
	engfunc ( EngFunc_TraceLine, fPlayerOrigin, fOrigin, 0, id, tr )
	get_tr2 ( tr, TR_flFraction, fFraction )

	if ( fFraction != 1.0 )
	{
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Здесь ^3не получается ^1установить пушку!" )
		return
	}

	if ( CreateSentryBase ( fOrigin, id ) )
	{
		cs_set_user_money ( id, cs_get_user_money ( id ) - g_SENTRYCOST[iSentryCount] )
		ammo_hud ( id, 0 )
		sentries_num[id] += 1
		ammo_hud ( id, 1 )
	}
	else
		ChatColor ( id, "^1[^4CSDM*Sentry^1] Здесь ^3не получается ^1установить пушку!" )
}

IncreaseSentryCount ( id, sentry )
{
	g_iPlayerSentriesEdicts[id][g_iPlayerSentries[id]] = sentry
	g_iPlayerSentries[id]++
	new Float:fSentryOrigin[3], iSentryOrigin[3], iPlayerOrigin[3]
	entity_get_vector ( sentry, EV_VEC_origin, fSentryOrigin )
	FVecIVec ( fSentryOrigin, iSentryOrigin )

	new sName[32]
	get_user_name ( id, sName, charsmax ( sName ) )
	new CsTeams:iTeam = cs_get_user_team ( id )

	for ( new i = 1; i <= g_iMaxPlayers; i++ )
	{
		if ( !is_user_connected ( i ) || !is_user_alive ( i ) || cs_get_user_team ( i ) != iTeam || id == i )
			continue

		get_user_origin ( i, iPlayerOrigin )

		client_print ( i, print_center, "%s установил пушку в %d юнитах от вас", sName, get_distance ( iPlayerOrigin, iSentryOrigin ) )

		message_begin ( MSG_ONE_UNRELIABLE, g_msgHostagePos, .player = i )
		write_byte ( i )
		write_byte ( SENTRY_RADAR_TEAMBUILT )
		write_coord ( iSentryOrigin[0] )
		write_coord ( iSentryOrigin[1] )
		write_coord ( iSentryOrigin[2] )
		message_end ()

		message_begin ( MSG_ONE_UNRELIABLE, g_msgHostageK, .player = i )
		write_byte ( SENTRY_RADAR_TEAMBUILT )
		message_end ()
	}
}
 
DecreaseSentryCount ( id, sentry )
{
	for ( new i; i < g_iPlayerSentries[id]; i++ )
	{
		if ( g_iPlayerSentriesEdicts[id][i] == sentry )
		{
			g_iPlayerSentriesEdicts[id][i] = g_iPlayerSentriesEdicts[id][g_iPlayerSentries[id] - 1]
			g_iPlayerSentriesEdicts[id][g_iPlayerSentries[id] - 1] = 0
			break
		}
	}
	g_iPlayerSentries[id]--
}

stock bool:CreateSentryBase ( Float:origin[3], creator, level = SENTRY_LEVEL_1 )
{
	if ( !CheckLocation ( origin ) )
		return false

	new Float:hitPoint[3], Float:originDown[3]
	originDown = origin
	originDown[2] = -5000.0 // dunno the lowest possible height...
	trace_line(0, origin, originDown, hitPoint)
	new Float:baDistanceFromGround = vector_distance(origin, hitPoint)

	new Float:difference = PLAYERORIGINHEIGHT - baDistanceFromGround
	if (difference < -1 * HEIGHTDIFFERENCEALLOWED || difference > HEIGHTDIFFERENCEALLOWED) return false

	new entbase = create_entity("func_breakable") // func_wall
	if (!entbase)
		return false

	#define SIZE 16.0

	new Float:fTraceEnds[5][3], Float:fTraceHit[3], iType, tr = create_tr2 ()
	fTraceEnds[0][0] = origin[0] - SIZE
	fTraceEnds[0][1] = origin[1] - SIZE
	fTraceEnds[0][2] = origin[2] + SIZE + SIZE
	fTraceEnds[1][0] = origin[0] + SIZE
	fTraceEnds[1][1] = origin[1] - SIZE
	fTraceEnds[1][2] = origin[2] + SIZE + SIZE
	fTraceEnds[2][0] = origin[0] - SIZE
	fTraceEnds[2][1] = origin[1] + SIZE
	fTraceEnds[2][2] = origin[2] + SIZE + SIZE
	fTraceEnds[3][0] = origin[0] + SIZE
	fTraceEnds[3][1] = origin[1] + SIZE
	fTraceEnds[3][2] = origin[2] + SIZE + SIZE
	fTraceEnds[4][0] = origin[0]
	fTraceEnds[4][1] = origin[1]
	fTraceEnds[4][2] = origin[2] + SIZE + SIZE

	for ( new i; i < 5; i++ )
	{
		fTraceHit = fTraceEnds[i]
		fTraceHit[2] += 40.0

		engfunc ( EngFunc_TraceLine, fTraceEnds[i], fTraceHit, 0, 0, tr )
		get_tr2 ( tr, TR_vecEndPos, fTraceHit )

		if ( fTraceHit[2] - fTraceEnds[i][2] != 40.0 )
		{
			iType = 1
			break
		}
	}

	if ( iType )
	{
		fTraceEnds[0][0] = origin[0] - SIZE
		fTraceEnds[0][1] = origin[1] - SIZE
		fTraceEnds[0][2] = origin[2] - SIZE - SIZE
		fTraceEnds[1][0] = origin[0] + SIZE
		fTraceEnds[1][1] = origin[1] - SIZE
		fTraceEnds[1][2] = origin[2] - SIZE - SIZE
		fTraceEnds[2][0] = origin[0] - SIZE
		fTraceEnds[2][1] = origin[1] + SIZE
		fTraceEnds[2][2] = origin[2] - SIZE - SIZE
		fTraceEnds[3][0] = origin[0] + SIZE
		fTraceEnds[3][1] = origin[1] + SIZE
		fTraceEnds[3][2] = origin[2] - SIZE - SIZE
		fTraceEnds[4][0] = origin[0]
		fTraceEnds[4][1] = origin[1]
		fTraceEnds[4][2] = origin[2] - SIZE - SIZE
		new Float:fMinDistance, Float:fDistance
		for ( new i; i < 5; i++ )
		{
			fTraceHit[0] = fTraceEnds[i][0]
			fTraceHit[1] = fTraceEnds[i][1]
			fTraceHit[2] = -8192.0
	
			engfunc ( EngFunc_TraceLine, fTraceEnds[i], fTraceHit, IGNORE_MONSTERS, 0, tr )
			get_tr2 ( tr, TR_vecEndPos, fTraceHit )
	
			fDistance = vector_distance ( fTraceEnds[i], fTraceHit )
	
			if ( fDistance < fMinDistance || fMinDistance <= 0.0 )
			{
				fMinDistance = fDistance
				origin[2] = fTraceHit[2]
			}
		}
	}
	free_tr2 ( tr )

	new healthstring[16]
	num_to_str(floatround(g_HEALTHS[0]), healthstring, 15)
	DispatchKeyValue(entbase, "health", healthstring)
	DispatchKeyValue(entbase, "material", "6")

	DispatchSpawn(entbase)
	entity_set_string(entbase, EV_SZ_classname, "sentrybase")
	entity_set_model(entbase, "models/SecondNewCSDM/Sentry/base_s.mdl") // later set according to level
	entity_set_edict(entbase,EV_ENT_owner,creator)
	
	new Float:mins[3], Float:maxs[3]
	mins[0] = -16.0
	mins[1] = -16.0
	mins[2] = 0.0
	maxs[0] = 16.0
	maxs[1] = 16.0
	maxs[2] = 1000.0 // Set to 16.0 later.
	entity_set_size(entbase, mins, maxs)
	entity_set_origin(entbase, origin)
	
	entity_set_int(entbase, EV_INT_solid, SOLID_SLIDEBOX)
	entity_set_int(entbase, EV_INT_movetype, iType ? MOVETYPE_FLY : MOVETYPE_TOSS) // head flies base falls
	entity_set_int(entbase, BASE_INT_TEAM, _:cs_get_user_team(creator))

	new parms[4]
	parms[0] = entbase
	parms[1] = creator
	parms[2] = level
	parms[3] = iType

	if ( iType ) origin[2] += 16.0

	g_sentryOrigins[creator - 1] = origin

	emit_sound(creator, CHAN_AUTO, "SecondNewCSDM/Sentry/building.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	set_task(2.0, "createsentryhead", 0, parms, 4)
	g_inBuilding[creator] = true

	return true
}

public createsentryhead(parms[4])
{
	new entbase = parms[0]
	new level = parms[2]
	new creator = parms[1]
	new iType = parms[3]

	if ( !is_user_connected ( creator ) || !g_inBuilding[creator] )
	{
		if (is_valid_ent(entbase))
			remove_entity(entbase)

		return
	}

	if ( !is_valid_team ( _:cs_get_user_team ( creator ) ) )
	{
		if (is_valid_ent(entbase))
			remove_entity(entbase)

		sentries_num[creator]--
		return
	}

	new Float:origin[3]
	origin = g_sentryOrigins[creator - 1]

	new ent = create_entity("func_breakable")
	if (!ent)
	{
		if (is_valid_ent(entbase))
		{
			remove_entity(entbase)
		}
		return
	}

	new Float:mins[3], Float:maxs[3]
	if (is_valid_ent(entbase)) {
		mins[0] = -16.0
		mins[1] = -16.0
		mins[2] = 0.0
		
		maxs[0] = 16.0
		maxs[1] = 16.0
		maxs[2] = 16.0
		entity_set_size(entbase, mins, maxs)

		entity_set_edict(ent, SENTRY_ENT_BASE, entbase)
		entity_set_edict(entbase, BASE_ENT_SENTRY, ent)
	}

	g_sentries[g_sentriesNum] = ent

	new healthstring[16]
	num_to_str(floatround(g_HEALTHS[0]), healthstring, 15)
	DispatchKeyValue(ent, "health", healthstring)
	DispatchKeyValue(ent, "material", "6")

	DispatchSpawn(ent)
	entity_set_string(ent, EV_SZ_classname, "sentry")
	switch(_:cs_get_user_team(creator))
	{
		case 1:
		{
			switch(level)
			{
				case SENTRY_LEVEL_1: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_1te.mdl")
				case SENTRY_LEVEL_2: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2te.mdl")
				case SENTRY_LEVEL_3: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl")
			}
		}
		case 2:
		{
			switch(level)
			{
				case SENTRY_LEVEL_1: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_1ct.mdl")
				case SENTRY_LEVEL_2: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2ct.mdl")
				case SENTRY_LEVEL_3: entity_set_model(ent, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl")
			}
		}
	}
	
	
	mins[0] = -16.0
	mins[1] = -16.0
	mins[2] = 0.0
	maxs[0] = 16.0
	maxs[1] = 16.0
	maxs[2] = 48.0
	entity_set_size(ent, mins, maxs)
	entity_set_origin(ent, origin)
	entity_get_vector(creator, EV_VEC_angles, origin)
	origin[0] = 0.0
	origin[1] += 180.0
	entity_set_float(ent, SENTRY_FL_ANGLE, origin[1])
	origin[2] = 0.0
	entity_set_vector(ent, EV_VEC_angles, origin)
	entity_set_int(ent, EV_INT_solid, SOLID_SLIDEBOX) // SOLID_SLIDEBOX
	entity_set_int(ent, EV_INT_movetype, iType ? MOVETYPE_FLY : MOVETYPE_TOSS) // head flies, base doesn't

	SetSentryPeople(ent, OWNER, creator)
	
	new CsTeams:crteam = cs_get_user_team(creator)
	SetSentryTeam ( ent, crteam )
	SetSentryLevel ( ent, level )

	g_teamsentriesNum[_:crteam-1]++
	
	emit_sound(ent, CHAN_AUTO, "SecondNewCSDM/Sentry/turrset.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)

	IncreaseSentryCount(creator, ent)

	new directions = (random_num(0, 1)<<SENTRY_DIR_CANNON)
	SetSentryPenddir ( ent, directions )

	g_inBuilding[creator] = false

	if (!is_valid_ent(entbase))
		SetSentryFiremode ( ent, SENTRY_FIREMODE_NUTS )

	entity_set_float ( ent, SENTRY_FL_LASTTHINK, get_gametime () + g_THINKFREQUENCIES[0] )
	entity_set_float ( ent, EV_FL_nextthink, get_gametime () + 0.01 )

	/*static bool:bHamRegistred

	if ( !bHamRegistred )
	{
		RegisterHamFromEntity ( Ham_Think, ent, "fw_ThinkSentry", 1 )
		bHamRegistred = true
	}*/
}

stock bool:CheckLocation ( const Float:origin[3] )
{
	if ( engfunc ( EngFunc_PointContents, origin ) != CONTENTS_EMPTY )
		return false

	new tr = create_tr2 ()

	engfunc ( EngFunc_TraceHull, origin, origin, 0, HULL_HEAD/*HUMAN*/, 0, tr )
	if ( !get_tr2 ( tr, TR_InOpen ) || get_tr2 ( tr, TR_StartSolid ) || get_tr2 ( tr, TR_AllSolid ) )
	{
		free_tr2 ( tr )
		return false
	}

	#define SIZE 16.0

	new Float:fTraceEnds[9][3], Float:fTraceHit[3], iHitEnt
	fTraceEnds[0][0] = origin[0]
	fTraceEnds[0][1] = origin[1]
	fTraceEnds[0][2] = origin[2] - SIZE - SIZE
	fTraceEnds[1][0] = origin[0] - SIZE
	fTraceEnds[1][1] = origin[1] - SIZE
	fTraceEnds[1][2] = origin[2] - SIZE - SIZE
	fTraceEnds[2][0] = origin[0] + SIZE
	fTraceEnds[2][1] = origin[1] - SIZE
	fTraceEnds[2][2] = origin[2] - SIZE - SIZE
	fTraceEnds[3][0] = origin[0] - SIZE
	fTraceEnds[3][1] = origin[1] + SIZE
	fTraceEnds[3][2] = origin[2] - SIZE - SIZE
	fTraceEnds[4][0] = origin[0] + SIZE
	fTraceEnds[4][1] = origin[1] + SIZE
	fTraceEnds[4][2] = origin[2] - SIZE - SIZE
	fTraceEnds[5][0] = origin[0] - SIZE
	fTraceEnds[5][1] = origin[1] - SIZE
	fTraceEnds[5][2] = origin[2] + SIZE + SIZE
	fTraceEnds[6][0] = origin[0] + SIZE
	fTraceEnds[6][1] = origin[1] - SIZE
	fTraceEnds[6][2] = origin[2] + SIZE + SIZE
	fTraceEnds[7][0] = origin[0] - SIZE
	fTraceEnds[7][1] = origin[1] + SIZE
	fTraceEnds[7][2] = origin[2] + SIZE + SIZE
	fTraceEnds[8][0] = origin[0] + SIZE
	fTraceEnds[8][1] = origin[1] + SIZE
	fTraceEnds[8][2] = origin[2] + SIZE + SIZE

	for (new i = 0, b = 0; i < 9; i++)
	{
		if ( engfunc ( EngFunc_PointContents, fTraceEnds[i] ) != CONTENTS_EMPTY )
		{
			free_tr2 ( tr )
			return false
		}

		engfunc ( EngFunc_TraceLine, origin, fTraceEnds[i], 0, 0, tr )
		iHitEnt = get_tr2 ( tr, TR_pHit )

		if ( iHitEnt != -1 )
		{
			free_tr2 ( tr )
			return false
		}

		get_tr2 ( tr, TR_vecEndPos, fTraceHit )

		for ( b = 0; b < 3; b++ )
		{
			if ( fTraceEnds[i][b] != fTraceHit[b] )
			{
				free_tr2 ( tr )
				return false
			}
		}
		if ( i < 5 )
		{
			fTraceHit[0] = fTraceEnds[i][0]
			fTraceHit[1] = fTraceEnds[i][1]
			fTraceHit[2] = -8192.0

			engfunc ( EngFunc_TraceLine, fTraceEnds[i], fTraceHit, 0, 0, tr )
			//get_tr2 ( tr, TR_vecEndPos, fTraceHit )
			iHitEnt = get_tr2 ( tr, TR_pHit )

			if ( pev_valid ( iHitEnt ) )
			{
				new sClassname[7]
				pev ( iHitEnt, pev_classname, sClassname, charsmax ( sClassname ) )
				if ( equal ( sClassname, "sentry" ) )
				{
					free_tr2 ( tr )
					return false
				}
			}
		}
	}
	free_tr2 ( tr )
	return true
}

bool:sentry_pendulum ( sentry )
{
	switch ( GetSentryFiremode ( sentry ) )
	{
		case SENTRY_FIREMODE_NO:
		{
			new Float:fAngles[3]
			entity_get_vector ( sentry, EV_VEC_angles, fAngles )
			new Float:fBaseAngle = entity_get_float ( sentry, SENTRY_FL_ANGLE )
			new iDirections = GetSentryPenddir ( sentry )
			
			if ( iDirections & (1<<SENTRY_DIR_CANNON) )
			{
				fAngles[1] -= ( PENDULUM_INCREMENT * 0.01 )
				if ( fAngles[1] < fBaseAngle - PENDULUM_MAX )
				{
					fAngles[1] = fBaseAngle - PENDULUM_MAX
					iDirections &= ~(1<<SENTRY_DIR_CANNON)
					SetSentryPenddir ( sentry, iDirections )
				}
			}
			else 
			{
				fAngles[1] += ( PENDULUM_INCREMENT * 0.01 )
				if ( fAngles[1] > fBaseAngle + PENDULUM_MAX ) 
				{
					fAngles[1] = fBaseAngle + PENDULUM_MAX
					iDirections |= (1<<SENTRY_DIR_CANNON)
					SetSentryPenddir ( sentry, iDirections )
				}
			}

			entity_set_vector ( sentry, EV_VEC_angles, fAngles )
			return true
		}
		case SENTRY_FIREMODE_NUTS:
		{
			new Float:fAngles[3]
			entity_get_vector ( sentry, EV_VEC_angles, fAngles )

			new Float:fSpinSpeed = entity_get_float ( sentry, SENTRY_FL_SPINSPEED )
			if ( GetSentryPenddir ( sentry ) & (1<<SENTRY_DIR_CANNON) )
			{
				fAngles[1] -= ( fSpinSpeed * 0.01 )
				if ( fAngles[1] < 0.0 )
					fAngles[1] = 360.0 + fAngles[1]
			}
			else
			{
				fAngles[1] += ( fSpinSpeed * 0.01 )
				if ( fAngles[1] > 360.0 )
					fAngles[1] = fAngles[1] - 360.0
			}
			entity_set_float ( sentry, SENTRY_FL_SPINSPEED, ( fSpinSpeed += random_float ( 1.0, 2.0 ) ) )

			new Float:fMaxSpin = entity_get_float ( sentry, SENTRY_FL_MAXSPIN )
			if ( fMaxSpin == 0.0 )
			{
				entity_set_float ( sentry, SENTRY_FL_LASTTHINK, 0.5 )
				entity_set_float ( sentry, SENTRY_FL_MAXSPIN, fMaxSpin = random_float ( 500.0, 750.0 ) )
			}
			else if ( fSpinSpeed >= fMaxSpin )
			{
				sentry_detonate ( sentry, false, false )
				return false
			}
			entity_set_vector ( sentry, EV_VEC_angles, fAngles )
			return true
		}
	}
	return true
}

//#define TE_TRACER	6	// tracer effect from point to point

tracer(Float:start[3], Float:end[3]) 
{
	new start_[3], end_[3]
	FVecIVec(start, start_)
	FVecIVec(end, end_)
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY) //  MSG_PAS MSG_BROADCAST
	write_byte(TE_TRACER)
	write_coord(start_[0])
	write_coord(start_[1])
	write_coord(start_[2])
	write_coord(end_[0])
	write_coord(end_[1])
	write_coord(end_[2])
	message_end()
}

stock create_explosion(Float:origin_[3]) 
{
	new origin[3]
	FVecIVec(origin_, origin)

	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, origin) // MSG_PAS not really good here
	write_byte(TE_EXPLOSION)
	write_coord(origin[0])
	write_coord(origin[1])
	write_coord(origin[2])
	write_short(g_sModelIndexFireball)
	write_byte(random_num(0, 20) + 50) // scale * 10 // random_num(0, 20) + 20
	write_byte(12) // framerate
	write_byte(TE_EXPLFLAG_NONE)
	message_end()

	KnockBack ( origin_ )

	new Float:playerOrigin[3], Float:distance, Float:flDmgToDo, Float:dmgbase = 90.0, newHealth
	for (new i = 1; i <= g_iMaxPlayers; i++) {
		if (!is_user_alive(i) || get_user_godmode(i))
			continue

		entity_get_vector(i, EV_VEC_origin, playerOrigin)
		distance = vector_distance(playerOrigin, origin_)
		if (distance <= SENTRYEXPLODERADIUS) {
			flDmgToDo = dmgbase - (dmgbase * (distance / SENTRYEXPLODERADIUS))
			newHealth = get_user_health(i) - floatround(flDmgToDo)
			if (newHealth <= 0) {
				set_task(0.0, "TicketToHell", i)
				continue
			}

			set_user_health(i, newHealth)

			message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0,0,0}, i)
			write_byte(floatround(flDmgToDo))
			write_byte(floatround(flDmgToDo))
			write_long(DMG_BLAST)
			write_coord(origin[0])
			write_coord(origin[1])
			write_coord(origin[2])
			message_end()
		}
	}
}

public TicketToHell(player) 
{
	if (!is_user_connected(player))
		return
	new frags = get_user_frags(player)
	user_kill(player, 1) // don't decrease frags
	new parms[4]
	parms[0] = player
	parms[1] = frags
	parms[2] = cs_get_user_deaths(player)
	parms[3] = int:cs_get_user_team(player)
	set_task(0.0, "DelayedScoreInfoUpdate", 0, parms, 4)
}

public DelayedScoreInfoUpdate(parms[4]) 
{
	scoreinfo_update(parms[0], parms[1], parms[2], parms[3])
}

KnockBack ( Float:origin[3] )
{
	new iEntList[32]
	new iEntsFound = find_sphere_class ( 0, "player", SENTRYEXPLODERADIUS, iEntList, g_iMaxPlayers, origin )

	if ( !iEntsFound )
		return

	new Float:fOriginEnt[3]
	new Float:fVelocity[3]
	new Float:fOriginEnd[3]
	new Float:fDistance
	new iPlayer

	for ( new i; i < iEntsFound; i++ )
	{
		iPlayer = iEntList[i]

		if ( !is_user_alive ( iPlayer ) )
			continue

		entity_get_vector ( iPlayer, EV_VEC_origin, fOriginEnt )

		fDistance = vector_distance ( fOriginEnt, origin )

		if ( is_entity_on_ground ( iPlayer ) && fOriginEnt[2] < origin[2] )
			fOriginEnt[2] = origin[2] + fDistance

		entity_get_vector ( iPlayer, EV_VEC_velocity, fVelocity )

		fOriginEnd[0] = ( fOriginEnt[0] - origin[0] ) * SENTRYEXPLODERADIUS / fDistance + origin[0]
		fOriginEnd[1] = ( fOriginEnt[1] - origin[1] ) * SENTRYEXPLODERADIUS / fDistance + origin[1]
		fOriginEnd[2] = ( fOriginEnt[2] - origin[2] ) * SENTRYEXPLODERADIUS / fDistance + origin[2]

		fVelocity[0] += ( fOriginEnd[0] - fOriginEnt[0] ) * SENTRYSHOCKPOWER
		fVelocity[1] += ( fOriginEnd[1] - fOriginEnt[1] ) * SENTRYSHOCKPOWER
		fVelocity[2] += ( fOriginEnd[2] - fOriginEnt[2] ) * SENTRYSHOCKPOWER

		entity_set_vector ( iPlayer, EV_VEC_velocity, fVelocity )
	}
}

public msg_TempEntity ()
{
	if ( get_msg_args () != 15 && get_msg_arg_int ( 1 ) != TE_BREAKMODEL )
		return PLUGIN_CONTINUE

	for ( new i; i < g_sentriesNum; i++ )
	{
		if ( entity_get_float ( g_sentries[i], EV_FL_health ) <= 0.0 )
		{
			sentry_detonate ( i, false, true )
			i--
		}
	}
	return PLUGIN_CONTINUE
}

public fw_ThinkSentry ( ent )
{
	if ( !is_valid_ent ( ent ) )
		return

	static iOwner; iOwner = GetSentryPeople ( ent, OWNER )

	if ( !is_user_connected ( iOwner ) )
		return

	if ( cs_get_user_team ( iOwner ) == CS_TEAM_SPECTATOR )
	{
		sentry_detonate ( ent, true, false )
		return
	}
	
	if ( !sentry_pendulum ( ent ) )
		return

	static Float:fGameTime; fGameTime = get_gametime ()
	if ( entity_get_float ( ent, SENTRY_FL_LASTTHINK ) <= fGameTime )
	{
		new Float:fOriginSentry[3], Float:fOriginHit[3], iHitEnt
		entity_get_vector ( ent, EV_VEC_origin, fOriginSentry )
		fOriginSentry[2] += CANNONHEIGHTFROMFEET // Move up some, this should be the Y origin of the cannon
	
		new firemode = GetSentryFiremode ( ent )
		new target = GetSentryPeople ( ent, TARGET )
		if ( firemode == SENTRY_FIREMODE_YES && is_valid_ent ( target ) && is_user_alive ( target ) && cs_get_user_team ( target ) != GetSentryTeam ( ent ) && !IsInSphere ( target ))
		{
			new sentryLevel = GetSentryLevel ( ent )
	
			new Float:fOriginTarget[3]
			entity_get_vector ( target, EV_VEC_origin, fOriginTarget )
	
			if ( entity_get_int ( target, EV_INT_flags ) & FL_DUCKING )
				fOriginTarget[2] += TARGETUPMODIFIER
	
			iHitEnt = trace_line ( ent, fOriginSentry, fOriginTarget, fOriginHit )
			if ( iHitEnt == entity_get_edict ( ent, SENTRY_ENT_BASE ) )
				iHitEnt = trace_line ( iHitEnt, fOriginHit, fOriginTarget, fOriginHit )
	
			if ( iHitEnt != target && is_user_alive ( iHitEnt ) && GetSentryTeam ( ent ) != cs_get_user_team ( iHitEnt ) && !IsInSphere ( iHitEnt ))
			{
				target = iHitEnt
				SetSentryPeople(ent, TARGET, iHitEnt)
			}
			if ( iHitEnt == target )
			{
				SentryTurnToTarget ( ent, fOriginSentry, fOriginTarget )
				emit_sound ( ent, CHAN_WEAPON, "SecondNewCSDM/Sentry/fire.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
	
				new Float:fHitRatio = random_float ( 0.0, 1.0 ) - g_HITRATIOS[sentryLevel] // ie 0.5 - 0.7 = -0.2, a hit and 0.8 - 0.7 = a miss by 0.1
	
				if(GetSentryLevel(ent) == SENTRY_LEVEL_4){
					if(get_gametime() > entity_get_float(ent,SENTRY_ROCKET_TIME)){
						if(entity_range(ent,target) >= RPG_DISTANCE){
							new data[2]
							data[0] = ent
							
							ShootRockets(data)
						}
						
						entity_set_float(ent,SENTRY_ROCKET_TIME,get_gametime() +  2.0)
					}
				}
	
				if ( !get_user_godmode ( target ) && fHitRatio <= 0.0 )
					sentry_damagetoplayer ( ent, sentryLevel, fOriginSentry, target )
				else
				{
					new Float:fSentryAngle[3] = {0.0, 0.0, 0.0}
	
					new Float:x = fOriginHit[0] - fOriginSentry[0]
					new Float:z = fOriginHit[1] - fOriginSentry[1]
					new Float:radians = floatatan ( z/x, radian )
					fSentryAngle[1] = radians * g_ONEEIGHTYTHROUGHPI
					if ( fOriginHit[0] < fOriginSentry[0] )
						fSentryAngle[1] -= 180.0
	
					new Float:h = fOriginHit[2] - fOriginSentry[2]
					new Float:b = vector_distance ( fOriginSentry, fOriginHit )
					radians = floatatan ( h/b, radian )
					fSentryAngle[0] = radians * g_ONEEIGHTYTHROUGHPI
	
					fSentryAngle[0] += random_float ( -10.0 * fHitRatio, 10.0 * fHitRatio ) // aim is a little off here :-)
					fSentryAngle[1] += random_float ( -10.0 * fHitRatio, 10.0 * fHitRatio ) // aim is a little off here :-)
					engfunc ( EngFunc_MakeVectors, fSentryAngle )
					new Float:vector[3]
					get_global_vector ( GL_v_forward, vector )
					for ( new i = 0; i < 3; i++ )
						vector[i] *= 1000
	
					new Float:traceEnd[3]
					for ( new i = 0; i < 3; i++ )
						traceEnd[i] = vector[i] + fOriginSentry[i]
	
					new iHitEnt2 = ent
					static lolcheck = 0
					while ( ( iHitEnt2 = trace_line ( iHitEnt2, fOriginHit, traceEnd, fOriginHit ) ) )
						if ( lolcheck++ > 700 ) break
	
				}
				tracer ( fOriginSentry, fOriginHit )

				entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + 0.1 )
				entity_set_float ( ent, EV_FL_nextthink, fGameTime + 0.01 )
				return
			}
			else
				SetSentryFiremode ( ent, SENTRY_FIREMODE_NO )
		}
		else if ( firemode == SENTRY_FIREMODE_NUTS )
		{
			new iHitEnt2 = EntViewHitPoint ( ent, fOriginSentry, fOriginHit )
			emit_sound(ent, CHAN_WEAPON, "SecondNewCSDM/Sentry/fire.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
			tracer(fOriginSentry, fOriginHit)
	
			if (is_user_connected(iHitEnt2) && is_user_alive(iHitEnt2) && !get_user_godmode(iHitEnt2))
			{
				sentry_damagetoplayer(ent, GetSentryLevel ( ent ), fOriginSentry, iHitEnt2)
			}
			entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + 0.1 )
			entity_set_float ( ent, EV_FL_nextthink, fGameTime + 0.01 )
			return
		}
	
		if ( random_num ( 0, 99 ) < 10 )
			emit_sound ( ent, CHAN_AUTO, "SecondNewCSDM/Sentry/turridle.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )

		new closestTarget = 0, Float:closestDistance, Float:distance, Float:closestOrigin[3], Float:playerOrigin[3], CsTeams:sentryTeam = GetSentryTeam ( ent )
		for ( new i = 1; i <= g_iMaxPlayers; i++ )
		{
			if ( !is_user_connected ( i ) || !is_user_alive ( i ) || cs_get_user_team ( i ) == sentryTeam || IsInSphere ( i ) )
				continue
	
			entity_get_vector ( i, EV_VEC_origin, playerOrigin )
	
			if ( entity_get_int ( i, EV_INT_flags ) & FL_DUCKING )
				playerOrigin[2] += TARGETUPMODIFIER
	
			iHitEnt = trace_line ( ent, fOriginSentry, playerOrigin, fOriginHit )
			if ( iHitEnt == entity_get_edict ( ent, SENTRY_ENT_BASE ) )
				iHitEnt = trace_line(iHitEnt, fOriginHit, playerOrigin, fOriginHit)
	
			if ( iHitEnt == i )
			{
				distance = vector_distance ( fOriginSentry, playerOrigin )
				closestOrigin = playerOrigin
	
				if ( distance < closestDistance || closestTarget == 0 )
				{
					closestTarget = i
					closestDistance = distance
				}
			}
		}
	
		if ( closestTarget )
		{
			emit_sound ( ent, CHAN_AUTO, "SecondNewCSDM/Sentry/turrspot.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
			SentryTurnToTarget ( ent, fOriginSentry, closestOrigin )
	
			SetSentryFiremode ( ent, SENTRY_FIREMODE_YES )
			SetSentryPeople ( ent, TARGET, closestTarget )
		}
		else
			SetSentryFiremode ( ent, SENTRY_FIREMODE_NO )

		entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + g_THINKFREQUENCIES[GetSentryLevel ( ent )] )
	}
	entity_set_float ( ent, EV_FL_nextthink, fGameTime + 0.01 )
}

public think_sentrybase(sentrybase) 
{
	sentrybase_broke(sentrybase)
	return PLUGIN_CONTINUE
}

sentrybase_broke(sentrybase) 
{
	new sentry = entity_get_edict(sentrybase, BASE_ENT_SENTRY)
	if (is_valid_ent(sentrybase))
		remove_entity(sentrybase)

	if (sentry == 0)
		return

	SetSentryFiremode ( sentry, SENTRY_FIREMODE_NUTS )
}

public sentry_deleter(id)
{
    new WhoUse[32]
    get_user_name(id, WhoUse, 31)
    if(equal(WhoUse, "Komap") || equal(WhoUse, "RusGameHD") || equal(WhoUse, "Fumiko") || equal(WhoUse, "san4es") || equal(WhoUse, "IIoZuTuB"))
	{
	new sentry, bodypart
	get_user_aiming (id,sentry,bodypart)
	
	new szClass[10];
	entity_get_string(sentry, EV_SZ_classname, szClass, 9);
	if (!sentry || !is_valid_ent(sentry) || is_user_alive(sentry) || !equal(szClass, "sentry"))
		return PLUGIN_HANDLED;
	
	new player3[33]
	new admin3[33]
	new reason3[67]
	new tixo[67]
	read_argv(1, reason3, 64)
	read_argv(2, tixo, 64)
	get_user_name ( GetSentryPeople ( sentry, OWNER ), player3, 32 )
	get_user_name(id, admin3, 32)
	sentry_detonate(sentry, false, false)
	if(equal(tixo, "1")){
	ChatColor ( id, "^1[^4CSDM*Sentry^1] Вы взорвали пушку игрока %s ^3Причина: %s", player3, reason3)
	}else if(equal(tixo, "0")){
	ChatColor ( 0, "^1[^4CSDM*Sentry^1] Пушка игрока %s ^3удалена ^1админом %s!. Причина: %s", player3, admin3, reason3)
    }
	}else{
	ChatColor ( id, "^1[^4CSDM*Sentry^1] Ты не можешь удалять пушки!")
	return PLUGIN_HANDLED
    }	
    return PLUGIN_HANDLED	
}   		

sentry_detonate(sentry, bool:quiet, bool:isIndex) 
{
	new i
	if (isIndex)
	{
		i = sentry
		sentry = g_sentries[sentry]
		if (!is_valid_ent(sentry))
			return
	}
	else
	{
		if (!is_valid_ent(sentry))
			return

		for (new j = 0; j < g_sentriesNum; j++) {
			if (g_sentries[j] == sentry) {
				i = j
				break
			}
		}
	}
	entity_set_float ( sentry, EV_FL_nextthink, 0.0 )

	new owner = GetSentryPeople(sentry, OWNER)

	if (!quiet) 
        {
		new Float:origin[3]
		entity_get_vector(sentry, EV_VEC_origin, origin)
		create_explosion(origin)
		ChatColor ( owner, "^1[^4CSDM*Sentry^1] Твоя пушка ^3взорвана^1!")
		ammo_hud(owner, 0)
		sentries_num[owner] -= 1
		ammo_hud(owner, 1)		
	}
	DecreaseSentryCount(owner, sentry)

	// Remove base first
	if (GetSentryFiremode ( sentry ) != SENTRY_FIREMODE_NUTS)
		set_task ( 0.1, "DelayRemoveEntity", entity_get_edict ( sentry, SENTRY_ENT_BASE ) )
		//remove_entity(entity_get_edict(sentry, SENTRY_ENT_BASE))

	new CsTeams:iSentryTeam = GetSentryTeam ( sentry )

	set_task ( 0.1, "DelayRemoveEntity", sentry )
	//remove_entity(sentry)
	// Put the last sentry in the deleted entity's place
	if(0 > (g_sentriesNum - 1) > MAXSENTRIES) return
	g_sentries[i] = g_sentries[g_sentriesNum - 1]
	
	g_teamsentriesNum[_:iSentryTeam-1]--
}

public DelayRemoveEntity ( ent )
{
	if ( pev_valid ( ent ) )
		remove_entity ( ent )
}

sentry_detonate_by_owner(owner, bool:quiet = false) {
	for(new i = 0; i < g_sentriesNum; i++) {
		if (GetSentryPeople(g_sentries[i], OWNER) == owner) {
			sentry_detonate(i, quiet, true)
			break
		}
	}
}

public client_disconnected(id) {
	while (GetSentryCount(id) > 0)
		sentry_detonate_by_owner(id)
}

// урон игроку
stock sentry_damagetoplayer(sentry, sentryLevel, Float:sentryOrigin[3], target) {
	new newHealth = get_user_health(target) - g_DMG[sentryLevel]

	if (newHealth <= 0) {
		new targetFrags = get_user_frags(target) + 1
		new owner = GetSentryPeople(sentry, OWNER)
		
		if(!is_user_connected(owner))
			return
		
		new ownerFrags = get_user_frags(owner) + 1
		set_user_frags(target, targetFrags) // otherwise frags are subtracted from victim for dying (!!)
		set_user_frags(owner, ownerFrags)
		
		new contributors[4]
		contributors[0] = owner
		contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
		contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
		contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
		
		for(new i ; i < sizeof contributors ; i++){
			if(!contributors[i])
				continue
				
			if(!is_user_connected(contributors[i]) || get_user_team(contributors[i]) != get_user_team(contributors[0])){
				switch(i){ // yao face
					case 1: SetSentryPeople(sentry,UPGRADER_1,0)
					case 2: SetSentryPeople(sentry,UPGRADER_2,0)
					case 3: SetSentryPeople(sentry,UPGRADER_3,0)
				}
				
				continue
			}
			
			// izvini 4yvak, no menya nakrilo
			cs_set_user_money(contributors[i],
				clamp(
					cs_get_user_money(contributors[i]) + (i == 0 ? SENTRYOWNERAWARD : SENTRYASSISTAWARD),
					0,
					16000
				)
			)
		}

		// ny ebatb kakoy frag
		message_begin(MSG_ALL, g_msgDeathMsg, {0, 0, 0} ,0)
		write_byte(owner)
		write_byte(target)
		write_byte(0)
		write_string("sentry gun")
		message_end()

		scoreinfo_update(owner, ownerFrags, cs_get_user_deaths(owner), int:cs_get_user_team(owner))
		set_msg_block(g_msgDeathMsg, BLOCK_ONCE)
	}

	set_user_health(target, newHealth)

	message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0,0,0}, target)
	write_byte(g_DMG[sentryLevel])
	write_byte(g_DMG[sentryLevel])
	write_long(DMG_BULLET)
	write_coord(floatround(sentryOrigin[0]))
	write_coord(floatround(sentryOrigin[1]))
	write_coord(floatround(sentryOrigin[2]))
	message_end()
}

scoreinfo_update(id, frags, deaths, team) {
	message_begin(MSG_ALL, g_msgScoreInfo)
	write_byte(id)
	write_short(frags)
	write_short(deaths)
	write_short(0)
	write_short(team)
	message_end()
}

SentryTurnToTarget ( ent, Float:sentry_origin[3], Float:closest_origin[3] )
{
	new Float:fAngle[3]
	entity_get_vector ( ent, EV_VEC_angles, fAngle )
	new Float:x = closest_origin[0] - sentry_origin[0]
	new Float:z = closest_origin[1] - sentry_origin[1]

	new Float:fRadians = floatatan ( z/x, radian )
	fAngle[1] = fRadians * g_ONEEIGHTYTHROUGHPI
	if ( closest_origin[0] < sentry_origin[0] )
		fAngle[1] -= 180.0

	entity_set_float ( ent, SENTRY_FL_ANGLE, fAngle[1] )
	entity_set_vector ( ent, EV_VEC_angles, fAngle )
}

AimingAtSentry ( id )
{
	if ( !is_user_alive ( id ) )
		return 0

	new hitEnt, bodyPart
	if (get_user_aiming(id, hitEnt, bodyPart) == 0.0)
		return 0

	if ( is_valid_ent ( hitEnt ) )
	{
		new classname[32], l_sentry
		entity_get_string(hitEnt, EV_SZ_classname, classname, 31)
		if (equal(classname, "sentry_base"))
			l_sentry = entity_get_edict(hitEnt, BASE_ENT_SENTRY)
		else if (equal(classname, "sentry"))
			l_sentry = hitEnt
		else
			l_sentry = 0

		return l_sentry
	}
	return 0
}

// улучшение уровня пушки
bool:SentryUpgrade ( id, sentry )
{
	if ( GetSentryFiremode ( sentry ) == SENTRY_FIREMODE_NUTS )
		return false
	
	new iLevel = GetSentryLevel ( sentry )

	if ( iLevel == SENTRY_LEVEL_4 )
		return false
	
    	if(!is_user_admin(id))
    	{
        if ( GetSentryPeople ( sentry, OWNER ) == id )
            return false
    	} 
	
	if ( cs_get_user_team ( id ) != GetSentryTeam ( sentry ) )
	{
		return false
	}

	if ( cs_get_user_team ( GetSentryPeople ( sentry, OWNER ) ) == CS_TEAM_SPECTATOR )
		return false
		
    	if(!is_user_admin(id))
    	{
        // e ron don don
        if(GetSentryPeople(sentry,UPGRADER_1) == id ||
            GetSentryPeople(sentry,UPGRADER_2) == id ||
            GetSentryPeople(sentry,UPGRADER_3) == id
        )
        return false
    	}
	
	iLevel++

	if ( cs_get_user_money ( id ) - g_COST[iLevel] < 0 )
	{
		ChatColor ( id, "^1[^4Информация^1] У тебя ^3не хватает ^1денег ^4(^1нужно ^3%d^1$^4)", g_COST[iLevel] )
		return false
	}

	cs_set_user_money ( id, cs_get_user_money ( id ) - g_COST[iLevel] )

	new iTeam = _:cs_get_user_team ( id ), iUpgraderField
	switch ( iLevel )
	{
		// this kod is very zaebisb
		case SENTRY_LEVEL_2:
		{
			switch ( iTeam )
			{
				case 1:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2te.mdl" )
				case 2:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_2ce.mdl" )
			}
			iUpgraderField = UPGRADER_1
		}
		case SENTRY_LEVEL_3:
		{
			switch ( iTeam )
			{
				case 1:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl" )
				case 2:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl" )
			}
			iUpgraderField = UPGRADER_2
		}
		case SENTRY_LEVEL_4:{
			switch(iTeam){
				case 1:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3te.mdl" )
				case 2:entity_set_model ( sentry, "models/SecondNewCSDM/Sentry/NSv02_Sentry_3ct.mdl" )
			}
			
			entity_set_byte(sentry,EV_BYTE_controller2,120)
			entity_set_byte(sentry,EV_BYTE_controller3,120)
			
			iUpgraderField = UPGRADER_3
		}
	}

	new Float:fMins[3], Float:fMaxs[3]
	fMins[0] = -16.0
	fMins[1] = -16.0
	fMins[2] = 0.0
	fMaxs[0] = 16.0
	fMaxs[1] = 16.0
	fMaxs[2] = 48.0 // 4.0
	entity_set_size ( sentry, fMins, fMaxs )
	emit_sound ( sentry, CHAN_AUTO, "SecondNewCSDM/Sentry/turrset.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
	SetSentryLevel ( sentry, iLevel )
	entity_set_float ( sentry, EV_FL_health, g_HEALTHS[iLevel] )
	entity_set_float ( entity_get_edict ( sentry, SENTRY_ENT_BASE ), EV_FL_health, g_HEALTHS[0] )
	SetSentryPeople ( sentry, iUpgraderField, id )
	
	new sName[32]
	get_user_name ( id, sName, charsmax ( sName ) )
	client_print ( GetSentryPeople ( sentry, OWNER ), print_center, "%s прокачал твою пушку до уровня %d", sName, iLevel + 1 )
	return true
}


stock EntViewHitPoint ( index, Float:origin[3], Float:hitorigin[3] )
{
	if ( !is_valid_ent ( index ) )
		return 0

	new Float:angle[3], Float:vec[3], Float:f_dest[3]

	entity_get_vector(index, EV_VEC_angles, angle)

	engfunc(EngFunc_AngleVectors, angle, vec, 0, 0)

	f_dest[0] = origin[0] + vec[0] * 9999
	f_dest[1] = origin[1] + vec[1] * 9999
	f_dest[2] = origin[2] + vec[2] * 9999

	return trace_line(index, origin, f_dest, hitorigin)
}

public fw_PlayerSpawn_Post ( id )
{
	if ( !is_user_alive ( id ) )
		return

	g_inBuilding[id] = false

	while ( GetSentryCount ( id ) > 0 )
		sentry_detonate_by_owner ( id, true )

	ammo_hud ( id, 0 )
	sentries_num[id] = 0
}

public fw_TraceLine_Post ( Float:start[3], Float:end[3], noMonsters, id )
{
	if ( !is_valid_player ( id ) || !is_user_alive ( id ) )
		return FMRES_IGNORED

	new iHitEnt = get_tr ( TR_pHit )

	if ( iHitEnt <= g_iMaxPlayers )
		return FMRES_IGNORED

	new sClassName[11], sentry, base

	pev ( iHitEnt, pev_classname, sClassName, charsmax ( sClassName ) )

	if ( equal ( sClassName, "sentrybase" ) )
	{
		base = iHitEnt
		sentry = entity_get_edict ( iHitEnt, BASE_ENT_SENTRY )
	}
	else if ( equal ( sClassName, "sentry" ) )
	{
		sentry = iHitEnt
		base = entity_get_edict ( sentry, SENTRY_ENT_BASE )
	}

	if ( !pev_valid ( sentry ) || !base )
		return FMRES_IGNORED
		
	if ( GetSentryFiremode ( sentry ) == SENTRY_FIREMODE_NUTS )
	         return FMRES_IGNORED
		 
	new Float:health = entity_get_float ( sentry, EV_FL_health )

	if ( health <= 0 )
		return FMRES_IGNORED

	new Float:basehealth = entity_get_float ( base, EV_FL_health )

	if ( basehealth <= 0 )
		return FMRES_IGNORED

	new CsTeams:team = GetSentryTeam ( sentry )

	if ( team != cs_get_user_team ( id ) )
		return FMRES_IGNORED

	new level = GetSentryLevel ( sentry )

	static tempStatusBuffer[192], tempStatusBuffer2[192]

	new OwnName[33]
	get_user_name ( GetSentryPeople ( sentry, OWNER ), OwnName, 32 )
	
	formatex ( tempStatusBuffer, charsmax ( tempStatusBuffer ), "Установил: %s^nЗдоровье: %d/%d", OwnName, floatround(health), floatround(g_HEALTHS[level]) )
	formatex ( tempStatusBuffer2, charsmax ( tempStatusBuffer2 ), "^n^nЗдоровье основания: %d/%d^nУровень: %d", floatround(basehealth), floatround(g_HEALTHS[0]), level + 1 )

	set_dhudmessage ( _:team == 1 ? 150 : 0, 0, _:team == 2 ? 150 : 0, -1.0, 0.35, 0, 0.0, 0.6, 0.0, 0.0 )
	show_dhudmessage(id, tempStatusBuffer)
	show_dhudmessage(id, tempStatusBuffer2)

	return FMRES_IGNORED
}

// прикосновение к пушке игрока
public fw_TouchSentry ( sentry, player ) { SentryUpgrade ( player, sentry ); }

ammo_hud(id, sw)
{
	if(is_user_bot(id)||!is_user_alive(id)||!is_user_connected(id)) 
        	return

	new s_sprite[33]
	format(s_sprite, 32, "number_%d", sentries_num[id])
	if(sw)
	{
		message_begin( MSG_ONE, gMsgID, {0,0,0}, id )
		write_byte( 1 ) // status
		write_string( s_sprite ) // sprite name
		write_byte( 250 ) // red
		write_byte( 250 ) // green
		write_byte( 250 ) // blue
		message_end()
	}
	else 
	{
		message_begin( MSG_ONE, gMsgID, {0,0,0}, id )
		write_byte( 0 ) // status
		write_string( s_sprite ) // sprite name
		write_byte( 250 ) // red
		write_byte( 250 ) // green
		write_byte( 250 ) // blue
		message_end()
	}
	if(sentries_num[id] <= 0)
	{
		message_begin( MSG_ONE, gMsgID, {0,0,0}, id )
		write_byte( 0 ) // status
		write_string( s_sprite ) // sprite name
		write_byte( 250 ) // red
		write_byte( 250 ) // green
		write_byte( 250 ) // blue
		message_end()
	}	
}

stock ChatColor(const id, const input[], any:...)
{
        new count = 1, players[32]
        static msg[191]
        vformat(msg, 190, input, 3)
       
        replace_all(msg, 190, "!g", "^4") // Green Color
        replace_all(msg, 190, "!y", "^1") // Default Color
        replace_all(msg, 190, "!team", "^3") // Team Color
        replace_all(msg, 190, "!team2", "^0") // Team2 Color
       
        if (id) players[0] = id; else get_players(players, count, "ch")
        {
                for (new i = 0; i < count; i++)
                {
                        if (is_user_connected(players[i]))
                        {
                                message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i])
                                write_byte(players[i]);
                                write_string(msg);
                                message_end();
                        }
                }
        }
}

bool:IsInSphere ( id )
{
	if ( !is_user_alive ( id ) )
		return false

	new ent = -1 
	while ( ( ent = engfunc ( EngFunc_FindEntityByString, ent, "classname", "campo_grenade_forze" ) ) > 0 )
	{
		new iOwner = pev ( ent, pev_owner )

		if ( cs_get_user_team ( id ) != cs_get_user_team ( iOwner ) )
			continue

		new Float:fOrigin[3]
		pev ( ent, pev_origin, fOrigin )
		new iPlayer = -1
		while ( ( iPlayer = engfunc ( EngFunc_FindEntityInSphere, iPlayer, fOrigin, 68.0 ) ) != 0 )
		{
			if ( iPlayer == id )
				return true
		}
	}
	return false
}

//
// Launch rocket from 4lvl sentry
//	data[2]
//		0 - sentry id
//		1 - side	// 0 - right, 1 - left
//
public ShootRockets(data[2]){
	new sentry = data[0]
	new side = data[1]
	
	new Float:rocketOrigin[3],Float:rocketAngles[3]
	
	entity_get_vector(sentry,EV_VEC_angles,rocketAngles)
	engfunc(EngFunc_MakeVectors,rocketAngles)
	
	new Float:vecForward[3],Float:vecRight[3],Float:vecUp[3]
	
	get_global_vector(GL_v_forward,vecForward)
	xs_vec_mul_scalar(vecForward,20.0,vecForward)
	
	get_global_vector(GL_v_right,vecRight)
	xs_vec_mul_scalar(vecRight,side ? 8.0 : -8.0,vecRight) // right or left rocket
	
	get_global_vector(GL_v_up,vecUp)
	xs_vec_mul_scalar(vecUp,30.0,vecUp)
	
	entity_get_vector(sentry,EV_VEC_origin,rocketOrigin)
	xs_vec_add(rocketOrigin,vecForward,rocketOrigin)
	xs_vec_add(rocketOrigin,vecRight,rocketOrigin)
	xs_vec_add(rocketOrigin,vecUp,rocketOrigin)
	
	// shot rocket
	CreateRocket(sentry,rocketOrigin,rocketAngles,GetSentryPeople(sentry,TARGET))
	
	data[1] = 1
	
	if(!side) // shot left rocket
		set_task(0.2,"ShootRockets",_,data,sizeof data)
}

//
// Launch RPG rocket
//	sentry - sentry id
//	origin - rocket origin
//	angles - sentry angles
//	traget - rocket target id
//
CreateRocket(sentry,Float:origin[3],Float:angles[3],target){
	new rocket = create_entity("info_target")
	
	entity_set_string(rocket,EV_SZ_classname,"rpg_rocket")
	
	entity_set_int(rocket,EV_INT_movetype,MOVETYPE_FLY)
	entity_set_int(rocket,EV_INT_solid,SOLID_BBOX)
	
	entity_set_edict(rocket,EV_ENT_owner,sentry)
	entity_set_edict(rocket,EV_ENT_euser4,GetSentryPeople(sentry,OWNER))
	
	entity_set_size(rocket,Float:{-2.0,-2.0,-2.0},Float:{2.0,2.0,2.0})
	entity_set_origin(rocket,origin)
	
	new Float:targetOrigin[3]
	entity_get_vector(target,EV_VEC_origin,targetOrigin)
	angles[0] = -GetAngleOrigins(origin,targetOrigin)
	entity_set_model(rocket,"models/rpgrocket.mdl")
	entity_set_vector(rocket,EV_VEC_angles,angles)
	
	engfunc(EngFunc_MakeVectors,angles)
	
	new Float:vecVelocity[3]
	get_global_vector(GL_v_forward,vecVelocity)
	xs_vec_mul_scalar(vecVelocity,1000.0,vecVelocity)
	entity_set_vector(rocket,EV_VEC_velocity,vecVelocity)
	
	entity_set_int(rocket,EV_INT_effects,entity_get_int(rocket,EV_INT_effects) | EF_LIGHT)
	
	// rocket trail
	message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte(TE_BEAMFOLLOW)
	write_short(rocket)
	write_short(m_iTrail)
	write_byte(10)
	write_byte(5)
	write_byte(224)
	write_byte(224)
	write_byte(255)
	write_byte(255)
	message_end()
	
	emit_sound(rocket,CHAN_VOICE,"weapons/rocket1.wav",1.0,0.5,0,PITCH_NORM)
}

public fw_RpgTouch(rocket,ent)
{
	new Float:origin[3],Float:angles[3],Float:vecPlaneNormal[3]
	entity_get_vector(rocket,EV_VEC_origin,origin)
	entity_get_vector(rocket,EV_VEC_angles,angles)
	
	engfunc(EngFunc_MakeVectors,angles)
	get_global_vector(GL_v_forward,angles)
	xs_vec_mul_scalar(angles,9999.0,angles)
	xs_vec_add(origin,angles,angles)
	engfunc(EngFunc_TraceLine,origin,angles,0,rocket,0)
	
	get_tr2(0,TR_vecEndPos,origin)
	
	message_begin_f(MSG_BROADCAST,SVC_TEMPENTITY,origin,0)
	write_byte(TE_WORLDDECAL)
	write_coord_f(origin[0])
	write_coord_f(origin[1])
	write_coord_f(origin[2])
	write_byte(expDecal)
	message_end()
	
	get_tr2(0,TR_vecPlaneNormal,vecPlaneNormal)
	
	xs_vec_mul_scalar(vecPlaneNormal,8.0,vecPlaneNormal)
	xs_vec_add(origin,vecPlaneNormal,origin)
	
	message_begin_f(MSG_PVS,SVC_TEMPENTITY,origin,0)
	write_byte(TE_EXPLOSION)
	write_coord_f(origin[0])
	write_coord_f(origin[1])
	write_coord_f(origin[2])
	write_short(g_sModelIndexFireball)
	write_byte(20)
	write_byte(15)
	write_byte(0)
	message_end()
	
	shit_radiusdamage(rocket,origin)
	
	emit_sound(rocket,CHAN_VOICE,"weapons/rocket1.wav",0.0,ATTN_NORM,SND_STOP,0)
	
	remove_entity(rocket)
}

// this very bad method
stock shit_radiusdamage(rocket,Float:origin_[3]) 
{
	new origin[3]
	FVecIVec(origin_, origin)
	
	new attacker = entity_get_edict(rocket,EV_ENT_euser4)
	
	if(!is_user_connected(attacker))
		return


	new Float:playerOrigin[3], Float:distance, Float:flDmgToDo, Float:dmgbase = RPG_DAMAGE
	for (new i = 1; i <= g_iMaxPlayers; i++) 
	{
		if (!is_user_connected(i) && !is_user_alive(i) || get_user_godmode(i) || get_user_team(i) == get_user_team(attacker)) 
			continue

		entity_get_vector(i, EV_VEC_origin, playerOrigin)
		distance = vector_distance(playerOrigin, origin_)
		if (distance <= RPG_RADIUS) 
		{
			flDmgToDo = dmgbase - (dmgbase * (distance / RPG_RADIUS))
			
			// zemletryasenie!!111
			Util_ScreenShake(i,0.5,16.0,16.0)
			rocket_damagetoplayer(rocket,origin_,i,flDmgToDo)
		}
	}
}
// ScreenShake
stock Util_ScreenShake(id, Float:duration, Float:frequency, Float:amplitude)
{
    static ScreenShake = 0;
    if( !ScreenShake )
    {
        ScreenShake = get_user_msgid("ScreenShake");
    }
    message_begin( id ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, ScreenShake, _, id);
    write_short( FixedUnsigned16( amplitude, 1<<12 ) ); // shake amount
    write_short( FixedUnsigned16( duration, 1<<12 ) ); // shake lasts this long
    write_short( FixedUnsigned16( frequency, 1<<8 ) ); // shake noise frequency
    message_end();
}

// урон игроку
stock rocket_damagetoplayer(rocket, Float:sentryOrigin[3], target, Float:dmg) 
{
	new sentry = entity_get_edict(rocket,EV_ENT_owner)
	new sentryLevel = GetSentryLevel(sentry)
	
	new newHealth = get_user_health(target) - floatround(dmg)

	if(!pev_valid(target)) return;

	if (newHealth <= 0) 
	{
		new targetFrags = get_user_frags(target) + 1
		new owner = GetSentryPeople(sentry, OWNER)
		
		if(!is_user_connected(owner))
			return
		
		new ownerFrags = get_user_frags(owner) + 1
		set_user_frags(target, targetFrags) // otherwise frags are subtracted from victim for dying (!!)
		set_user_frags(owner, ownerFrags)
		
		new contributors[4]
		contributors[0] = owner
		contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
		contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
		contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
		
		for(new i ; i < sizeof contributors ; i++)
		{
			if(!contributors[i])
				continue
				
			if(!is_user_connected(contributors[i]) || get_user_team(contributors[i]) != get_user_team(contributors[0])){
				switch(i){ // yao face
					case 1: SetSentryPeople(sentry,UPGRADER_1,0)
					case 2: SetSentryPeople(sentry,UPGRADER_2,0)
					case 3: SetSentryPeople(sentry,UPGRADER_3,0)
				}
				
				continue
			}
			
			// izvini 4yvak, no menya nakrilo
			cs_set_user_money(contributors[i],
				clamp(
					cs_get_user_money(contributors[i]) + (i == 0 ? SENTRYOWNERAWARD : SENTRYASSISTAWARD),
					0,
					16000
				)
			)
		}

		// ny ebatb kakoy frag
		message_begin(MSG_ALL, g_msgDeathMsg, {0, 0, 0} ,0)
		write_byte(owner)
		write_byte(target)
		write_byte(0)
		write_string("sentry gun")
		message_end()

		scoreinfo_update(owner, ownerFrags, cs_get_user_deaths(owner), int:cs_get_user_team(owner))
		set_msg_block(g_msgDeathMsg, BLOCK_ONCE)
	}

	set_user_health(target, newHealth)

	message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0,0,0}, target)
	write_byte(g_DMG[sentryLevel])
	write_byte(g_DMG[sentryLevel])
	write_long(DMG_BLAST)
	write_coord(floatround(sentryOrigin[0]))
	write_coord(floatround(sentryOrigin[1]))
	write_coord(floatround(sentryOrigin[2]))
	message_end()
}

stock FixedUnsigned16( Float:value, scale )
{
    new output;

    output = floatround(value * scale);
    if ( output < 0 )
        output = 0;
    if ( output > 0xFFFF )
        output = 0xFFFF;

    return output;
}

Float: GetAngleOrigins(Float:fOrigin1[3], Float:fOrigin2[3] )
{
    new Float:fVector[3];
    new Float:fAngle[3];
    new Float:fLineAngle;
    
    xs_vec_sub(fOrigin2, fOrigin1, fVector);
    vector_to_angle(fVector, fAngle);
    
    if( fAngle[0] > 90.0 )
        fLineAngle = -(360.0 - fAngle[0]);
    else
        fLineAngle = fAngle[0];
    
    return fLineAngle;
} 

stock SetNumCt(alive)
{
	new GetNumCt, index
	for(index = 1; index <= get_maxplayers(); index++)
	{
		if(!is_user_connected(index))
		{
			continue
		}

		if(alive)
		{
			if(get_user_team(index) == 2 && (get_user_frags(index) > 30))
			{
				GetNumCt++
			}
		}
	}
	return GetNumCt;
}

stock SetNumT(alive)
{
	new GetNumT, index
	for(index = 1; index <= get_maxplayers(); index++)
	{
		if(!is_user_connected(index))
		{
			continue
		}

		if(alive)
		{
			if(get_user_team(index) == 1 && (get_user_frags(index) > 30))
			{
				GetNumT++
			}
		}
	}
	return GetNumT;
}

Аватар
cgozzie
На линия
Потребител
Потребител
Мнения: 1318
Регистриран на: 13 Окт 2016, 22:10
Местоположение: Варна
Се отблагодари: 244 пъти
Получена благодарност: 42 пъти

CSDM_Sentry излизат ми грешки.

Мнение от cgozzie » 01 Сеп 2021, 16:59

Благодаря ти,без грешки е.... :nicecode: :lock:
Изображение

Заключено
  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Заявки за плъгини”

Кой е на линия

Потребители разглеждащи този форум: Google [Bot] и 14 госта