Удаляю я значит функции героя, нативы и так далее.
Стояла привязка через натив к герою и я просто ее удалил.
Ибо 4 лвл с ракетами стрелял бы только по герою и по игрокам с невидимостью.
Так вот ракеты работают, но виснет звук выстрела ракет, то бишь он раздается всем и бесконечно.
В чем может быть причина этого?
Стояла привязка через натив к герою и я просто ее удалил.
Ибо 4 лвл с ракетами стрелял бы только по герою и по игрокам с невидимостью.
Так вот ракеты работают, но виснет звук выстрела ракет, то бишь он раздается всем и бесконечно.
В чем может быть причина этого?
Код:
/*
#include <amxmodx>
#include <engine>
#include <fun>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#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 sh_get_hero ()
#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 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 1000
#define TASK_GODMODE 114455
#define SENTRY_INT_TARGET EV_INT_iuser3
#define SENTRY_TARGET_BITS 6
#define TARGET 0
#define MASK_TARGET 0xFFFFFFC0 // 11111111111111111111111111000000
new const MASKS_TARGET[1] = {MASK_TARGET}
GetSentryTarget(const SENTRY, const WHO) {
new data = entity_get_int(SENTRY, SENTRY_INT_TARGET)
data |= MASKS_TARGET[WHO]
data ^= MASKS_TARGET[WHO]
data = (data>>(WHO*SENTRY_TARGET_BITS))
return data
}
SetSentryTarget(const SENTRY, const WHO, const IS) {
new data = entity_get_int(SENTRY, SENTRY_INT_TARGET)
data &= MASKS_TARGET[WHO] // nullify the setting
data |= (IS<<(WHO*SENTRY_TARGET_BITS)) // set the setting
entity_set_int(SENTRY, SENTRY_INT_TARGET, data) // store
}
#define SENTRY_INT_PEOPLE EV_INT_iuser2 // max 5 users using 6 bits!
#define SENTRY_PEOPLE_BITS 6
#define OWNER 0
#define UPGRADER_1 1
#define UPGRADER_2 2
#define UPGRADER_3 3
#define UPGRADER_4 4
#define MASK_OWNER 0xFFFFFFC0 // 11111111111111111111111111000000
#define MASK_UPGRADER_1 0xFFFFF03F // 11111111111111111111000000111111
#define MASK_UPGRADER_2 0xFFFC0FFF // 11111111111111000000111111111111
#define MASK_UPGRADER_3 0xFF03FFFF // 11111111000000111111111111111111
#define MASK_UPGRADER_4 0xC0FFFFFF // 11000000111111111111111111111111
new const MASKS_PEOPLE[5] = {MASK_OWNER, MASK_UPGRADER_1, MASK_UPGRADER_2, MASK_UPGRADER_3, MASK_UPGRADER_4}
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 3
#define SENTRY_SETTING_FIREMODE 0
#define SENTRY_SETTING_TEAM 1
#define SENTRY_SETTING_LEVEL 2
#define SENTRY_SETTING_PENDDIR 3
#define MASK_FIREMODE 0xFFFFFFF8 // 11111111111111111111111111111000 = FFFFFFFC
#define MASK_TEAM 0xFFFFFFC7 // 11111111111111111111111111000111 = FFFFFFF3
#define MASK_LEVEL 0xFFFFFE3F // 11111111111111111111111000111111 = FFFFFFCF
#define MASK_PENDDIR 0xFFFFF1FF // 11111111111111111111000111111111 = 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_LEVEL_5 4
#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/error_csdm/sentry/base.mdl",
"models/error_csdm/sentry/te_1.mdl",
"models/error_csdm/sentry/te_2.mdl",
"models/error_csdm/sentry/te_3.mdl",
"models/error_csdm/sentry/ct_1.mdl",
"models/error_csdm/sentry/ct_2.mdl",
"models/error_csdm/sentry/ct_3.mdl",
"models/error_csdm/sentry/rpgrocket.mdl",
"models/computergibs.mdl"
}
new const szSounds[][] =
{
"debris/bustmetal1.wav",
"debris/bustmetal2.wav",
"debris/metal1.wav",
"debris/metal3.wav",
"error_csdm/sentry/turridle.wav",
"error_csdm/sentry/turrset.wav",
"error_csdm/sentry/turrspot.wav",
"error_csdm/sentry/building.wav",
"error_csdm/sentry/fire.wav",
"weapons/rocket1.wav",
"weapons/tok.wav"
}
new expDecal
#define SENTRYOWNERAWARD 300
#define SENTRYASSISTAWARD 150
#define g_DMG 30 // количество урона от пушки в зависимости от ее уровня
#define g_THINKFREQUENCIES 0.7 // через сколько захватывается цель
#define g_HITRATIOS 0.7 // разброс
new const g_SENTRYCOST[5] = {3500, 4000, 7000, 8000, 9000} // стоимость установки
new const g_SENTRYCOST_VIP[5] = {200,300,400,700,800} // стоимость установки
new const g_COST_VIP[5] = {300, 100, 150, 850, 1000} // стоимость улучшения пушек VIP
new const Float:g_HEALTHS[5] = {3500.0, 4500.0, 5500.0, 6500.0, 7500.0} // сколько хп у пушки в зависимости от ее уровня (верхняя часть)
new const g_COST[5] = {3500, 1500, 2500, 10000, 12000} // стоимость улучшения пушек
#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][5]
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
new g_Sprt_Tok
enum _:menuStatus {
CURRENT_SENTRYID
}
new g_MenuStatus[33][menuStatus]
#define SentryClassName "sentry"
#define SentryBaseClassName "sentrybase"
new attach_viewmod[33]
new g_FlagVip
new g_Nagrada
new g_Count_sentry_vip, g_Count_sentry
public plugin_init() {
register_plugin("Sentry Guns", "1.2", "pro100web")
register_event ( "Spectator", "ev_Spectation", "a" )
register_clcmd("sentry_build", "cmd_CreateSentry", 0, "- build a sentry gun where you are")
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 ( SentryClassName, "player", "fw_TouchSentry" )
register_touch("rpg_rocket","*","fw_RpgTouch")
register_message ( 23, "msg_TempEntity" )
register_think("sentrybase", "think_sentrybase")
register_think ( SentryClassName, "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")
register_clcmd("sentry_menu", "sentry_menu")
register_clcmd("say /off", "offview")
- set_task ( 120.0, "checkhero", .flags = "b" )
set_task(0.2,"informer",_,_,_,"b");
g_FlagVip = register_cvar("er_sentry_flag_vip", "t") // Флаг для vip игрока.
g_Count_sentry_vip = register_cvar("er_sentry_max_vip", "2") // Сколько пушек может поставить VIP игрок с флагом выше (er_sentry_flag_vip)
g_Count_sentry = register_cvar("er_sentry_max", "1") // Сколько пушек может поставить простой игрок
g_Nagrada = register_cvar("er_sentry_nagrada", "2000") // Награда за разрушение пушки
}
public offview(id)
{
attach_view(id,id)
attach_viewmod[id] = 0
}
public sentry_menu(id)
{
new szItem[128];
new szItem1[128];
new msentry_item = menu_create("\wНастройка пушек!", "cl_men")
//format(szItem1, 127, "\wМодель пушки: \y%s", SzModelSentry[modelSentryVID[id]])
//menu_additem( msentry_item, szItem1, "1", 0)
//format(szItem1, 127, "\wСкин пушки: \y%s", SzSkinsSentry[skinSentryVID[id]])
//menu_additem( msentry_item, szItem1, "2", 0)
if(sentries_num[id] > 0){
static ent = -1
while ((ent = find_ent_by_class(ent, SentryClassName)))
{
if( GetSentryPeople(ent,OWNER) != id) continue;
if(is_valid_ent(ent))
{
format(szItem, 127, "%d", ent)
new sClassName[11]
pev ( ent, pev_classname, sClassName, charsmax ( sClassName ) )
if ( equal ( sClassName, SentryClassName ) )
{
new Float:health = entity_get_float ( ent, EV_FL_health )
new level = GetSentryLevel ( ent )
format(szItem1, 127, "\wID %d | LVL %d HP %i", ent, level+1, floatround(health))
menu_additem( msentry_item, szItem1, szItem, 0)
}
}
}
}
menu_setprop(msentry_item, MPROP_EXIT, MEXIT_ALL)
menu_setprop(msentry_item, MPROP_EXITNAME, "\yВыход")
menu_display(id, msentry_item, 0)
return PLUGIN_HANDLED
}
public cl_men(id, menu, item) {
new s_Data[6], s_Name[64], i_Access, i_Callback
menu_item_getinfo(menu, item, i_Access, s_Data, charsmax(s_Data), s_Name, charsmax(s_Name), i_Callback)
new i_Key = str_to_num(s_Data)
menu_destroy(menu)
switch(i_Key){
case 0: return 0
/* case 1: {
switch(modelSentryVID[id]){
case 0: modelSentryVID[id] = 1
case 1: modelSentryVID[id] = 2
case 2: modelSentryVID[id] = 0
}
ChatColor ( id, "^4Вы успешно выбрали модель")
sentry_menu(id)
}
case 2: {
switch(skinSentryVID[id]){
case 0: skinSentryVID[id] = 1
case 1: skinSentryVID[id] = 2
case 2: skinSentryVID[id] = 0
}
ChatColor ( id, "^4Вы успешно выбрали скин")
sentry_menu(id)
} */
default: {
if ( !is_valid_ent ( i_Key ) ) return 0
g_MenuStatus[id][CURRENT_SENTRYID] = i_Key
sentry_menu_func(id)
}
}
return 1
}
public sentry_menu_func(id)
{
if(sentries_num[id] == 0){
ChatColor ( id, "^4У тебя нет пушек, что ты хотел этим добится?")
return HAM_IGNORED
}
new szItem1[128];
new ent = g_MenuStatus[id][CURRENT_SENTRYID];
if(ent==0) return PLUGIN_HANDLED
if(is_valid_ent(ent))
{
new sClassName[11]
pev ( ent, pev_classname, sClassName, charsmax ( sClassName ) )
if ( equal ( sClassName, SentryClassName ) )
{
new msentry_item = menu_create("\yВыберите пушку!", "cl_menr");
new Float:health = entity_get_float ( ent, EV_FL_health )
new level = GetSentryLevel ( ent )
menu_additem( msentry_item, "\wУничтожить", "1")
format(szItem1, 127, "\wСмотреть от лица пушки", "3")
menu_additem( msentry_item, szItem1, "3", 0)
menu_addblank( msentry_item, 0)
menu_addblank( msentry_item, 0)
menu_addblank( msentry_item, 0)
format(szItem1, 127, "\wID \r%d", ent)
menu_addtext( msentry_item, szItem1)
format(szItem1, 127, "Уровень \r%d", level+1)
menu_addtext( msentry_item, szItem1)
format(szItem1, 127, "\w[HP \y%d\w]", floatround(health))
menu_addtext( msentry_item, szItem1)
menu_setprop(msentry_item, MPROP_EXIT, MEXIT_ALL)
menu_setprop(msentry_item, MPROP_EXITNAME, "\yВыход")
menu_display(id, msentry_item, 0)
}
}
return PLUGIN_HANDLED
}
public cl_menr(id, menu, item) {
new s_Data[6], s_Name[64], i_Access, i_Callback
menu_item_getinfo(menu, item, i_Access, s_Data, charsmax(s_Data), s_Name, charsmax(s_Name), i_Callback)
new i_Key = str_to_num(s_Data)
menu_destroy(menu)
switch(i_Key){
case 0: return 1;
case 1:{
if ( !is_valid_ent ( g_MenuStatus[id][CURRENT_SENTRYID] ) ) return 0
ChatColor(id,"Пушка: %d уничтожена",g_MenuStatus[id][CURRENT_SENTRYID])
sentry_detonate ( g_MenuStatus[id][CURRENT_SENTRYID], false, false )
}
/* case 2:{
if ( !is_valid_ent ( g_MenuStatus[id][CURRENT_SENTRYID] ) ) return 0
if(cs_get_user_money(id)<9000){
ChatColor(id,"У вас недостаточно средств. Пушка: %d",g_MenuStatus[id][CURRENT_SENTRYID])
return 0
}
if(SentryPatrWhit[g_MenuStatus[id][CURRENT_SENTRYID]]+3000<8000){
ChatColor(id,"Пушка: %d Закуплены патроны ",g_MenuStatus[id][CURRENT_SENTRYID])
SentryPatrWhit[g_MenuStatus[id][CURRENT_SENTRYID]]+=3000
} else {
ChatColor(id,"В пушке не может быть более 8000 патронов. Пушка: %d",g_MenuStatus[id][CURRENT_SENTRYID])
}
} */
case 3: {
attach_viewEx(id, g_MenuStatus[id][CURRENT_SENTRYID])
set_task ( 15.0, "DelayRemoveAttachView", id-9250)
}
}
g_MenuStatus[id][CURRENT_SENTRYID] = 0
return 1
}
public DelayRemoveAttachView(idoff){
new id = idoff+9250
attach_viewEx(id,id)
}
stock attach_viewEx(id,target){
attach_view(id,target)
if(id == target) attach_viewmod[id] = 0, remove_task(id-100)
else attach_viewmod[id] = target, set_task ( 1.0, "set_taskdhudmessagebg", id-100, .flags = "b" )
}
public set_taskdhudmessagebg(idoff){
new id = idoff+100
if(!attach_viewmod[id]) remove_task(idoff)
new Float:health = entity_get_float ( attach_viewmod[id], EV_FL_health )
set_dhudmessage ( 255, 255, 255, 0.0, 0.75, 0, 0.0, 0.99, 0.0, 0.0 )
static tempStatusBuffer[192]
new level = GetSentryLevel ( attach_viewmod[id] )
new OwnName[33]
get_user_name ( GetSentryPeople ( attach_viewmod[id], OWNER ), OwnName, 32 )
formatex ( tempStatusBuffer, charsmax ( tempStatusBuffer ), "Установил: %s^nЗдоровье: %d/%d^nsay /off", OwnName, floatround(health), floatround(g_HEALTHS[level]))
show_dhudmessage(id, tempStatusBuffer)
}
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")
g_Sprt_Tok = precache_model("sprites/tok.spr")
}
public plugin_natives ()
{
register_native ( "get_sentry_people", "native_get_sentry_people", 1 )
register_native ( "get_sentry_team", "native_get_sentry_team", 1 )
register_native ( "get_SentryCount", "nativegetSentryCount", 1)
register_native ( "get_SentryLevel", "nativeget_SentryLevel", 1)
register_native ( "set_freezSentry", "native_CreateSentry", 1)
register_native ( "set_sentrGrand", "native_CreateSentry", 1)
register_native ( "native_create_sentry", "native_CreateSentry", 1)
register_native ( "get_leader", "native_get_leader", 1)
}
public native_get_leader() return 1
public native_CreateSentry(id) return 0
public nativeget_SentryLevel(sentry)
{
return GetSentryLevel ( sentry )
}
public nativegetSentryCount(id)
{
return sentries_num[id];
}
public native_get_sentry_people ( sentry, who )
{
return GetSentryPeople ( sentry, who )
}
public CsTeams:native_get_sentry_team ( sentry )
{
return GetSentryTeam ( sentry )
}
public informer(id)
{
set_dhudmessage(255, 0, 0, 0.41, 0.0, 0 , 0.0, 0.1,0.1,0.1);
show_dhudmessage(id, "Пушек ТТ [%d] ",g_teamsentriesNum[0]);
set_dhudmessage(29, 224, 215, 0.54, 0.0, 0, 0.0, 0.1,0.1,0.1);
show_dhudmessage(id, "[%d] Пушек КТ",g_teamsentriesNum[1]);
}
public checkhero()
{
//for ( new i = 1; i <= 500; i++ ) menu_destroy(i)
if ( sh_get_hero () ) return
new iDifference = g_teamsentriesNum[0]-g_teamsentriesNum[1]
if(iDifference>=8||iDifference<=-8)
{
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
TimerStart ( iData )
get_players(players, num, "ache", "TERRORIST")
heroenabled = true
}
if(heroenabled && num > 1)
{
for(--num; num>=0; num--)
{
if(get_user_frags(players[num]) >= bestfrags)
{
plid = players[num]
bestfrags = get_user_frags(plid)
}
}
if ( sh_set_hero ( plid ) )
{
sentry_detonate_by_owner ( plid )
}
}
}
}
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 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 )
sentry_detonate_by_owner ( id )
}
public fw_TakeDamage ( ent, idinflictor, idattacker, Float:damage, damagebits )
{
if ( !is_valid_ent ( ent ) )
return HAM_IGNORED
new sClassname[11]
pev ( ent, pev_classname, sClassname, charsmax ( sClassname ) )
if ( equal ( sClassname, SentryClassName ) || equal ( sClassname, "sentrybase" ) )
{
if ( sClassname[6] == 'b' )
ent = entity_get_edict(ent, BASE_ENT_SENTRY)
if ( is_valid_ent ( 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
if ( pev ( ent, pev_health ) - damage <= 0.0 )
{
ChatColor ( idattacker, "^3[^4Информация^3]^1 Вы получили ^4%i^1$ за разрушение пушки", get_pcvar_num(g_Nagrada))
cs_set_user_money ( idattacker, cs_get_user_money ( idattacker ) + get_pcvar_num(g_Nagrada))
}
cs_set_user_money(idattacker,cs_get_user_money(idattacker) + (floatround(damage)-10))
}
}
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 )
{
if ( !is_user_alive ( id ) )
{
ChatColor ( id, "^3[^4Информация^3]^1 Мертвым нельзя ставить пушку!" )
return
}
new iSentryCount = sentries_num[id]
if (get_user_flags(id) & get_pcvar_flags(g_FlagVip))
{
if ( iSentryCount >= get_pcvar_num(g_Count_sentry_vip))
{
ChatColor ( id, "^3[^4Информация^3]^1 Увы, ты уже построил %d пушки!", get_pcvar_num(g_Count_sentry_vip))
return
}
}
else
{
if ( iSentryCount >= get_pcvar_num(g_Count_sentry))
{
ChatColor ( id, "^3[^4Информация^3]^1 Нельзя установить более %d пушки!", get_pcvar_num(g_Count_sentry))
return
}
}
if ( g_inBuilding[id] )
{
ChatColor ( id, "^3[^4Информация^3]^1 Эй, не так быстро..." )
return
}
if ( !is_entity_on_ground ( id ) )
{
ChatColor ( id, "^3[^4Информация^3]^1 Встань на землю, чтобы установить пушку!" )
return
}
if (get_user_flags(id) & get_pcvar_flags(g_FlagVip))
{
if ( cs_get_user_money ( id ) < g_SENTRYCOST_VIP[iSentryCount] )
{
client_print(id, print_center, "У тебя не хватает денег! (нужно %d$)", g_SENTRYCOST_VIP[iSentryCount] )
return
}
}
else
{
if ( cs_get_user_money ( id ) < g_SENTRYCOST[iSentryCount] )
{
client_print(id, print_center, "У тебя не хватает денег! (нужно %d$)", 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, "^3[^4Информация^3]^1 Здесь не получается установить пушку!" )
return
}
if ( CreateSentryBase ( fOrigin, id ) )
{
if (get_user_flags(id) & get_pcvar_flags(g_FlagVip))
{
cs_set_user_money ( id, cs_get_user_money ( id ) - g_SENTRYCOST_VIP[iSentryCount] )
}
else
{
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, "^3[^4Информация^3]^1 Пушка не ставится! %f %f %f",fOrigin[0],fOrigin[1],fOrigin[2] )
ChatColor ( id, "^3[^4Информация^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 10.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]
}
}
}
new Float:fHighest[3]
fHighest = origin
fHighest[2] = 1000.0
engfunc ( EngFunc_TraceLine, origin, fHighest, DONT_IGNORE_MONSTERS, 0, tr )
get_tr2 ( tr, TR_vecEndPos, fHighest )
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, SentryBaseClassName)
entity_set_model(entbase, "models/error_csdm/sentry/base.mdl") // later set according to level
SetSentryPeople ( entbase, 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] = floatclamp ( vector_distance ( origin, fHighest ), 128.0, 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
entity_get_vector(creator, EV_VEC_angles, origin)
origin[0] = 0.0
entity_set_vector(entbase, EV_VEC_angles, origin)
emit_sound(creator, CHAN_AUTO, "error_csdm/sentry/building.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
set_task(0.7, "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 + 9287)
sentries_num[creator]--
return
}
new CsTeams:crteam = cs_get_user_team(creator)
if ( !is_valid_team ( _:crteam ) )
{
if (is_valid_ent(entbase))
remove_entity(entbase + 9287)
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 + 9287)
}
return
}
new Float:mins[3], Float:maxs[3]
if (is_valid_ent(entbase)) {
mins[0] = -5.0
mins[1] = -5.0
mins[2] = 0.0
maxs[0] = 5.0
maxs[1] = 5.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)
}
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, SentryClassName)
switch(_:crteam)
{
case 1:
{
entity_set_model(ent, "models/error_csdm/sentry/te_1.mdl")
}
case 2:
{
entity_set_model(ent, "models/error_csdm/sentry/ct_1.mdl")
}
}
mins[0] = -10.0
mins[1] = -10.0
mins[2] = 0.0
maxs[0] = 10.0
maxs[1] = 10.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)
SetSentryTeam ( ent, crteam )
SetSentryLevel ( ent, level )
g_teamsentriesNum[_:crteam-1]++
emit_sound(ent, CHAN_AUTO, "error_csdm/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 )
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 10.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
}
}
}
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
new ent = -1
while ((ent = find_ent_by_class(ent, SentryClassName)))
{
if (entity_get_float ( ent, EV_FL_health ) <= 0.0) sentry_detonate ( ent, false, false )
}
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 = GetSentryTarget ( 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 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
SetSentryTarget(ent, TARGET, iHitEnt)
}
if ( iHitEnt == target )
{
SentryTurnToTarget ( ent, fOriginSentry, fOriginTarget )
new Float:fHitRatio = random_float ( 0.0, 1.0 ) - g_HITRATIOS // ie 0.5 - 0.7 = -0.2, a hit and 0.8 - 0.7 = a miss by 0.1
new iLevel = GetSentryLevel(ent)
if(iLevel == SENTRY_LEVEL_4){
- if(sh_get_hero() == target)
+ if(target)
{
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)
}
}
} else if(iLevel == SENTRY_LEVEL_5) {
FireZevs(fOriginSentry,fOriginTarget);
emit_sound ( ent, CHAN_WEAPON, "weapons/tok.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
}
else emit_sound ( ent, CHAN_WEAPON, "error_csdm/sentry/fire.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
if ( !get_user_godmode ( target ) && fHitRatio <= 0.0 )
sentry_damagetoplayer ( ent, 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 )
new Float:fAngle[3]
entity_get_vector(ent, EV_VEC_angles, fAngle)
fAngle[0] = 0.0
entity_set_vector(ent, EV_VEC_angles, fAngle)
}
}
else if ( firemode == SENTRY_FIREMODE_NUTS )
{
new iHitEnt2 = EntViewHitPoint ( ent, fOriginSentry, fOriginHit )
emit_sound(ent, CHAN_WEAPON, "error_csdm/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, 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, "error_csdm/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, "error_csdm/sentry/turrspot.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
SentryTurnToTarget ( ent, fOriginSentry, closestOrigin )
SetSentryFiremode ( ent, SENTRY_FIREMODE_YES )
SetSentryTarget ( ent, TARGET, closestTarget )
}
else
{
SetSentryFiremode ( ent, SENTRY_FIREMODE_NO )
new Float:fAngle[3]
entity_get_vector(ent, EV_VEC_angles, fAngle)
fAngle[0] = 0.0
entity_set_vector(ent, EV_VEC_angles, fAngle)
}
entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + g_THINKFREQUENCIES )
}
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 )
}
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, "^3[^4Действие^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 ( is_valid_ent ( ent ) )
remove_entity ( ent )
}
sentry_detonate_by_owner(owner, bool:quiet = false) {
if(sentries_num[owner]>0)
{
static ent = -1
while ((ent = find_ent_by_class(ent, SentryClassName)))
{
if( GetSentryPeople(ent,OWNER) != owner) continue;
sentry_detonate ( ent, quiet, false )
}
}
}
public client_disconnect(id) {
sentry_detonate_by_owner ( id )
}
// урон игроку
stock sentry_damagetoplayer(sentry, Float:sentryOrigin[3], target) {
new newHealth = get_user_health(target) - g_DMG
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[5]
contributors[0] = owner
contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
contributors[4] = GetSentryPeople(sentry, UPGRADER_4)
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)
case 4: SetSentryPeople(sentry,UPGRADER_4,0)
}
continue
}
// izvini 4yvak, no menya nakrilo
cs_set_user_money(contributors[i], cs_get_user_money(contributors[i]) + (i == 0 ? SENTRYOWNERAWARD : SENTRYASSISTAWARD))
}
// 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()
//add_user_exp ( owner )
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)
write_byte(g_DMG)
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 )
} */
SentryTurnToTarget (ent, Float:sentryOrigin[3], Float:closestOrigin[3]) {
new Float:newAngle[3]
entity_get_vector(ent, EV_VEC_angles, newAngle)
new Float:x = closestOrigin[0] - sentryOrigin[0]
new Float:z = closestOrigin[1] - sentryOrigin[1]
new Float:y = closestOrigin[2] - sentryOrigin[2]
newAngle[1] = floatasin(z/floatsqroot(x*x+z*z), degrees)
new Float:radians = floatatan(z/x, radian)
newAngle[1] = radians * g_ONEEIGHTYTHROUGHPI
if (closestOrigin[0] < sentryOrigin[0])
newAngle[1] -= 180.0
entity_set_float(ent, SENTRY_FL_ANGLE, newAngle[1])
new Float:h = closestOrigin[2] - sentryOrigin[2]
new Float:b = vector_distance(sentryOrigin, closestOrigin)
radians = floatatan(h/b, radian)
newAngle[0] = floatasin(x/floatsqroot(x*x+y*y), degrees)
newAngle[0] = radians * g_ONEEIGHTYTHROUGHPI
entity_set_vector(ent, EV_VEC_angles, newAngle)
}
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, SentryClassName))
l_sentry = hitEnt
else
l_sentry = 0
return l_sentry
}
return 0
}
// улучшение уровня пушки
bool:SentryUpgrade ( id, sentry )
{
if(!is_user_alive(id)||!is_user_connected(id))
return false
if ( GetSentryFiremode ( sentry ) == SENTRY_FIREMODE_NUTS )
return false
new iLevel = GetSentryLevel ( sentry )
if ( iLevel == SENTRY_LEVEL_5 )
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
// e ron don don
if (get_user_flags(id) & get_pcvar_flags(g_FlagVip))
{
}
else
{
// e ron don don
if(GetSentryPeople(sentry,UPGRADER_1) == id ||
GetSentryPeople(sentry,UPGRADER_2) == id ||
GetSentryPeople(sentry,UPGRADER_3) == id ||
GetSentryPeople(sentry,UPGRADER_4) == id
)
return false
}
iLevel++
if (get_user_flags(id) & get_pcvar_flags(g_FlagVip))
{
if ( cs_get_user_money ( id ) - g_COST_VIP[iLevel] < 0 )
{
client_print(id, print_center, "У тебя не хватает денег (нужно %d$)", g_COST_VIP[iLevel])
return false
}
}
else
{
if ( cs_get_user_money ( id ) - g_COST[iLevel] < 0 )
{
client_print(id, print_center, "У тебя не хватает денег (нужно %d$)", g_COST[iLevel])
return false
}
}
if (get_user_flags(id) &get_pcvar_flags(g_FlagVip))
{
cs_set_user_money ( id, cs_get_user_money ( id ) - g_COST_VIP[iLevel] )
}
else
{
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/error_csdm/sentry/te_2.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_2.mdl" )
}
iUpgraderField = UPGRADER_1
}
case SENTRY_LEVEL_3:
{
switch ( iTeam )
{
case 1:entity_set_model ( sentry, "models/error_csdm/sentry/te_3.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_3.mdl" )
}
iUpgraderField = UPGRADER_2
}
case SENTRY_LEVEL_4:{
switch(iTeam){
case 1:entity_set_model ( sentry, "models/error_csdm/sentry/te_3.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_3.mdl" )
}
iUpgraderField = UPGRADER_3
}
case SENTRY_LEVEL_5:{
switch(iTeam){
case 1:entity_set_model ( sentry, "models/error_csdm/sentry/te_3.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_3.mdl" )
}
// entity_set_byte(sentry,EV_BYTE_controller2,120)
// entity_set_byte(sentry,EV_BYTE_controller3,120)
iUpgraderField = UPGRADER_4
}
}
new Float:fMins[3], Float:fMaxs[3]
fMins[0] = -10.0
fMins[1] = -10.0
fMins[2] = 0.0
fMaxs[0] = 10.0
fMaxs[1] = 10.0
fMaxs[2] = 40.0 // 4.0
entity_set_size ( sentry, fMins, fMaxs )
emit_sound ( sentry, CHAN_AUTO, "error_csdm/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 )
{
g_inBuilding[id] = false
sentry_detonate_by_owner ( id )
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, SentryClassName ) )
{
sentry = iHitEnt
base = entity_get_edict ( sentry, SENTRY_ENT_BASE )
}
if ( !is_valid_ent ( 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 ( 255, 255, 255, -1.0, 0.75, 0, 0.0, 0.6, 0.0, 0.0 )
show_dhudmessage(id, tempStatusBuffer)
show_dhudmessage(id, tempStatusBuffer2)
return FMRES_IGNORED
}
// прикосновение к пушке игрока
new Float:flood_touch[33]
public fw_TouchSentry ( sentry, player )
{
static Float:time;time=get_gametime()
if(flood_touch[player] < time)
SentryUpgrade ( player, sentry );
flood_touch[player] = time+1.0
return 1
}
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,GetSentryTarget(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/error_csdm/sentry/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)
}
// 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
new sentry = entity_get_edict(rocket,EV_ENT_owner)
for (new i = 1; i <= g_iMaxPlayers; i++) {
if (!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(sentry,origin_,i,flDmgToDo)
}
}
remove_entity(rocket)
}
// 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(sentry, Float:sentryOrigin[3], target, Float:dmg) {
new newHealth = get_user_health(target) - floatround(dmg)
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[5]
contributors[0] = owner
contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
contributors[4] = GetSentryPeople(sentry, UPGRADER_4)
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)
case 4: SetSentryPeople(sentry,UPGRADER_4,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)
write_byte(g_DMG)
write_long(DMG_BLAST)
write_coord(floatround(sentryOrigin[0]))
write_coord(floatround(sentryOrigin[1]))
write_coord(floatround(sentryOrigin[2]))
message_end()
}
FireZevs(Float:starting[3], Float:ending[3])
{
new OriginStr[3],OriginEnd[3];
//Еффект луча от пушки до цели.
FVecIVec(starting,OriginStr)
FVecIVec(ending,OriginEnd)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMPOINTS);
write_coord(OriginStr[0]);
write_coord(OriginStr[1]);
write_coord(OriginStr[2]);
write_coord(OriginEnd[0]);
write_coord(OriginEnd[1]);
write_coord(OriginEnd[2]);
write_short(g_Sprt_Tok);
write_byte(0);
write_byte(1);
write_byte(1);
write_byte(random_num(10, 50));
write_byte(random_num(10, 25));
write_byte(random_num(0, 255));
write_byte(random_num(0, 255));
write_byte(random_num(0, 255));
write_byte(1000);
write_byte(0);
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;
}
Код:
#include <amxmodx>
#include <engine>
#include <fun>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#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 MAXUPGRADERANGE 75.0
#define SENTRYEXPLODERADIUS 250.0 // радиус отброса при взрыве
#define SENTRYTILTRADIUS 830.0 // Насколько точно пушка будет нацелена на цель вертикально (вверх/вниз, просто для взглядов, цель рассчитывается по-разному)
#define SENTRYMINDISTANCE 256.0
#define MAXSENTRIES 1000
#define TASK_GODMODE 114455
#define SENTRY_INT_TARGET EV_INT_iuser3
#define SENTRY_TARGET_BITS 6
#define TARGET 0
#define MASK_TARGET 0xFFFFFFC0 // 11111111111111111111111111000000
new const MASKS_TARGET[1] = {MASK_TARGET}
GetSentryTarget(const SENTRY, const WHO) {
new data = entity_get_int(SENTRY, SENTRY_INT_TARGET)
data |= MASKS_TARGET[WHO]
data ^= MASKS_TARGET[WHO]
data = (data>>(WHO*SENTRY_TARGET_BITS))
return data
}
SetSentryTarget(const SENTRY, const WHO, const IS) {
new data = entity_get_int(SENTRY, SENTRY_INT_TARGET)
data &= MASKS_TARGET[WHO] // nullify the setting
data |= (IS<<(WHO*SENTRY_TARGET_BITS)) // set the setting
entity_set_int(SENTRY, SENTRY_INT_TARGET, data) // store
}
#define SENTRY_INT_PEOPLE EV_INT_iuser2 // max 5 users using 6 bits!
#define SENTRY_PEOPLE_BITS 6
#define OWNER 0
#define UPGRADER_1 1
#define UPGRADER_2 2
#define UPGRADER_3 3
#define UPGRADER_4 4
#define MASK_OWNER 0xFFFFFFC0 // 11111111111111111111111111000000
#define MASK_UPGRADER_1 0xFFFFF03F // 11111111111111111111000000111111
#define MASK_UPGRADER_2 0xFFFC0FFF // 11111111111111000000111111111111
#define MASK_UPGRADER_3 0xFF03FFFF // 11111111000000111111111111111111
#define MASK_UPGRADER_4 0xC0FFFFFF // 11000000111111111111111111111111
new const MASKS_PEOPLE[5] = {MASK_OWNER, MASK_UPGRADER_1, MASK_UPGRADER_2, MASK_UPGRADER_3, MASK_UPGRADER_4}
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 3
#define SENTRY_SETTING_FIREMODE 0
#define SENTRY_SETTING_TEAM 1
#define SENTRY_SETTING_LEVEL 2
#define SENTRY_SETTING_PENDDIR 3
#define MASK_FIREMODE 0xFFFFFFF8 // 11111111111111111111111111111000 = FFFFFFFC
#define MASK_TEAM 0xFFFFFFC7 // 11111111111111111111111111000111 = FFFFFFF3
#define MASK_LEVEL 0xFFFFFE3F // 11111111111111111111111000111111 = FFFFFFCF
#define MASK_PENDDIR 0xFFFFF1FF // 11111111111111111111000111111111 = 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_LEVEL_5 4
#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) // Урон от взрыва
#define TE_EXPLFLAG_NONE 0
#define TE_EXPLOSION 3
#define TE_TRACER 6
#define TE_BREAKMODEL 108
#define PENDULUM_MAX 45.0 // Как далеко сторожевая башня поворачивается в каждом направлении на холостом ходу, прежде чем повернуть назад
#define PENDULUM_INCREMENT 10.0 // Скорость поворота башни
#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
#define FLAG_VIP ADMIN_LEVEL_H // Флаг VIP игрока
#define MAX_VIP 2 // Максимальное кол-во пушек для VIP игрока [ FLAG_VIP ]
#define MAX_PL 1 // Максимальное кол-во пушек для игрока
#define NAGRADA 2000 // Награда за разрушение пушки
new const szModels[][] =
{
"models/error_csdm/sentry/base.mdl",
"models/error_csdm/sentry/te_1.mdl",
"models/error_csdm/sentry/te_2.mdl",
"models/error_csdm/sentry/te_3.mdl",
"models/error_csdm/sentry/ct_1.mdl",
"models/error_csdm/sentry/ct_2.mdl",
"models/error_csdm/sentry/ct_3.mdl",
"models/error_csdm/sentry/rpgrocket.mdl",
"models/computergibs.mdl"
}
new const szSounds[][] =
{
"debris/bustmetal1.wav",
"debris/bustmetal2.wav",
"debris/metal1.wav",
"debris/metal3.wav",
"error_csdm/sentry/turridle.wav",
"error_csdm/sentry/turrset.wav",
"error_csdm/sentry/turrspot.wav",
"error_csdm/sentry/building.wav",
"error_csdm/sentry/fire.wav",
"weapons/rocket1.wav",
"weapons/tok.wav"
}
new expDecal
#define SENTRYOWNERAWARD 300
#define SENTRYASSISTAWARD 150
#define g_DMG 30 // количество урона от пушки в зависимости от ее уровня
#define g_THINKFREQUENCIES 0.7 // через сколько захватывается цель
#define g_HITRATIOS 0.7 // разброс
new const g_SENTRYCOST[5] = {3500, 4000, 7000, 8000, 9000} // стоимость установки
new const g_SENTRYCOST_VIP[5] = {200,300,400,700,800} // стоимость установки
new const g_COST_VIP[5] = {300, 100, 150, 850, 1000} // стоимость улучшения пушек VIP
new const Float:g_HEALTHS[5] = {3500.0, 4500.0, 5500.0, 6500.0, 7500.0} // сколько хп у пушки в зависимости от ее уровня (верхняя часть)
new const g_COST[5] = {3500, 1500, 2500, 10000, 12000} // стоимость улучшения пушек
#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][5]
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 m_iTrail
new g_Sprt_Tok
enum _:menuStatus {
CURRENT_SENTRYID
}
#define SentryClassName "sentry"
#define SentryBaseClassName "sentrybase"
new attach_viewmod[33]
public plugin_init() {
register_plugin("Sentry Guns", "1.0", "pro100web")
register_event ( "Spectator", "ev_Spectation", "a" )
register_clcmd("sentry_build", "cmd_CreateSentry", 0, "- build a sentry gun where you are")
RegisterHam ( Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1 )
RegisterHam ( Ham_TakeDamage, "func_breakable", "fw_TakeDamage" )
register_forward ( FM_TraceLine, "fw_TraceLine_Post", 1 )
register_touch ( SentryClassName, "player", "fw_TouchSentry" )
register_touch("rpg_rocket","*","fw_RpgTouch")
register_message ( 23, "msg_TempEntity" )
register_think("sentrybase", "think_sentrybase")
register_think ( SentryClassName, "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(0.2,"informer",_,_,_,"b"); // Информер, сколько пушек КТ и ТТ
}
public DelayRemoveAttachView(idoff){
new id = idoff+9250
attach_viewEx(id,id)
}
stock attach_viewEx(id,target){
attach_view(id,target)
if(id == target) attach_viewmod[id] = 0, remove_task(id-100)
else attach_viewmod[id] = target, set_task ( 1.0, "set_taskdhudmessagebg", id-100, .flags = "b" )
}
public set_taskdhudmessagebg(idoff){
new id = idoff+100
if(!attach_viewmod[id]) remove_task(idoff)
new Float:health = entity_get_float ( attach_viewmod[id], EV_FL_health )
set_dhudmessage ( 255, 255, 255, 0.0, 0.75, 0, 0.0, 0.99, 0.0, 0.0 )
static tempStatusBuffer[192]
new level = GetSentryLevel ( attach_viewmod[id] )
new OwnName[33]
get_user_name ( GetSentryPeople ( attach_viewmod[id], OWNER ), OwnName, 32 )
formatex ( tempStatusBuffer, charsmax ( tempStatusBuffer ), "Установил: %s^nЗдоровье: %d/%d^n", OwnName, floatround(health), floatround(g_HEALTHS[level]))
show_dhudmessage(id, tempStatusBuffer)
}
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")
g_Sprt_Tok = precache_model("sprites/tok.spr")
}
public plugin_natives ()
{
register_native ("get_sentry_people", "native_get_sentry_people", 1)
register_native ("get_sentry_team", "native_get_sentry_team", 1)
register_native ("get_SentryCount", "nativegetSentryCount", 1)
register_native ("get_SentryLevel", "nativeget_SentryLevel", 1)
register_native ("set_freezSentry", "native_CreateSentry", 1)
register_native ("set_sentrGrand", "native_CreateSentry", 1)
register_native ("native_create_sentry", "native_CreateSentry", 1)
register_native ("get_leader", "native_get_leader", 1)
}
public native_get_leader() return 1
public native_CreateSentry(id) return 0
public nativeget_SentryLevel(sentry)
{
return GetSentryLevel ( sentry )
}
public nativegetSentryCount(id)
{
return sentries_num[id];
}
public native_get_sentry_people ( sentry, who )
{
return GetSentryPeople ( sentry, who )
}
public CsTeams:native_get_sentry_team ( sentry )
{
return GetSentryTeam ( sentry )
}
public informer(id)
{
set_dhudmessage(255, 0, 0, 0.41, 0.0, 0 , 0.0, 0.1,0.1,0.1);
show_dhudmessage(id, "Пушек ТТ [%d] ",g_teamsentriesNum[0]);
set_dhudmessage(29, 224, 215, 0.54, 0.0, 0, 0.0, 0.1,0.1,0.1);
show_dhudmessage(id, "[%d] Пушек КТ",g_teamsentriesNum[1]);
}
public ev_Spectation()
{
new id = read_data (1)
if(is_user_connected(id) && cs_get_user_team(id) == CS_TEAM_SPECTATOR)
sentry_detonate_by_owner(id)
}
public fw_TakeDamage ( ent, idinflictor, idattacker, Float:damage, damagebits)
{
if ( !is_valid_ent ( ent ) )
return HAM_IGNORED
new sClassname[11]
pev ( ent, pev_classname, sClassname, charsmax ( sClassname ) )
if ( equal ( sClassname, SentryClassName ) || equal ( sClassname, "sentrybase" ) )
{
if ( sClassname[6] == 'b' )
ent = entity_get_edict(ent, BASE_ENT_SENTRY)
if ( is_valid_ent ( 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
if ( pev ( ent, pev_health ) - damage <= 0.0 )
{
ChatColor ( idattacker, "^3[^4Информация^3]^1 Вы получили ^4%i^1$ за разрушение пушки", NAGRADA)
cs_set_user_money ( idattacker, cs_get_user_money ( idattacker ) + NAGRADA)
}
cs_set_user_money(idattacker,cs_get_user_money(idattacker) + (floatround(damage)-10))
}
}
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 )
{
if ( !is_user_alive ( id ) )
{
ChatColor ( id, "^3[^4Информация^3]^1 Мертвым нельзя ставить пушку!" )
return
}
new iSentryCount = sentries_num[id]
if (get_user_flags(id) & FLAG_VIP)
{
if ( iSentryCount >= MAX_VIP)
{
ChatColor ( id, "^3[^4Информация^3]^1 Увы, ты уже построил %d пушки!", MAX_VIP)
return
}
}
else
{
if ( iSentryCount >= MAX_PL)
{
ChatColor ( id, "^3[^4Информация^3]^1 Нельзя установить более %d пушки!", MAX_PL)
return
}
}
if ( g_inBuilding[id] )
{
ChatColor ( id, "^3[^4Информация^3]^1 Эй, не так быстро..." )
return
}
if ( !is_entity_on_ground ( id ) )
{
ChatColor ( id, "^3[^4Информация^3]^1 Встань на землю, чтобы установить пушку!" )
return
}
if (get_user_flags(id) & FLAG_VIP)
{
if ( cs_get_user_money ( id ) < g_SENTRYCOST_VIP[iSentryCount] )
{
client_print(id, print_center, "У тебя не хватает денег! (нужно %d$)", g_SENTRYCOST_VIP[iSentryCount] )
return
}
}
else
{
if ( cs_get_user_money ( id ) < g_SENTRYCOST[iSentryCount] )
{
client_print(id, print_center, "У тебя не хватает денег! (нужно %d$)", 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, "^3[^4Информация^3]^1 Здесь не получается установить пушку!" )
return
}
if ( CreateSentryBase ( fOrigin, id ) )
{
if (get_user_flags(id) & FLAG_VIP)
{
cs_set_user_money ( id, cs_get_user_money ( id ) - g_SENTRYCOST_VIP[iSentryCount] )
}
else
{
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, "^3[^4Информация^3]^1 Пушка не ставится! %f %f %f",fOrigin[0],fOrigin[1],fOrigin[2] )
ChatColor ( id, "^3[^4Информация^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 10.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]
}
}
}
new Float:fHighest[3]
fHighest = origin
fHighest[2] = 1000.0
engfunc ( EngFunc_TraceLine, origin, fHighest, DONT_IGNORE_MONSTERS, 0, tr )
get_tr2 ( tr, TR_vecEndPos, fHighest )
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, SentryBaseClassName)
entity_set_model(entbase, "models/error_csdm/sentry/base.mdl") // later set according to level
SetSentryPeople ( entbase, 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] = floatclamp ( vector_distance ( origin, fHighest ), 128.0, 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
entity_get_vector(creator, EV_VEC_angles, origin)
origin[0] = 0.0
entity_set_vector(entbase, EV_VEC_angles, origin)
emit_sound(creator, CHAN_AUTO, "error_csdm/sentry/building.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
set_task(0.7, "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 + 9287)
sentries_num[creator]--
return
}
new CsTeams:crteam = cs_get_user_team(creator)
if ( !is_valid_team ( _:crteam ) )
{
if (is_valid_ent(entbase))
remove_entity(entbase + 9287)
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 + 9287)
}
return
}
new Float:mins[3], Float:maxs[3]
if (is_valid_ent(entbase)) {
mins[0] = -5.0
mins[1] = -5.0
mins[2] = 0.0
maxs[0] = 5.0
maxs[1] = 5.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)
}
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, SentryClassName)
switch(_:crteam)
{
case 1:
{
entity_set_model(ent, "models/error_csdm/sentry/te_1.mdl")
}
case 2:
{
entity_set_model(ent, "models/error_csdm/sentry/ct_1.mdl")
}
}
mins[0] = -10.0
mins[1] = -10.0
mins[2] = 0.0
maxs[0] = 10.0
maxs[1] = 10.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)
SetSentryTeam ( ent, crteam )
SetSentryLevel ( ent, level )
g_teamsentriesNum[_:crteam-1]++
emit_sound(ent, CHAN_AUTO, "error_csdm/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 )
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 10.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
}
}
}
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
new ent = -1
while ((ent = find_ent_by_class(ent, SentryClassName)))
{
if (entity_get_float ( ent, EV_FL_health ) <= 0.0) sentry_detonate ( ent, false, false )
}
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 = GetSentryTarget ( 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 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
SetSentryTarget(ent, TARGET, iHitEnt)
}
if ( iHitEnt == target )
{
SentryTurnToTarget ( ent, fOriginSentry, fOriginTarget )
new Float:fHitRatio = random_float ( 0.0, 1.0 ) - g_HITRATIOS // ie 0.5 - 0.7 = -0.2, a hit and 0.8 - 0.7 = a miss by 0.1
new iLevel = GetSentryLevel(ent)
if(iLevel == SENTRY_LEVEL_4){
if(target)
{
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)
}
}
} else if(iLevel == SENTRY_LEVEL_5) {
FireZevs(fOriginSentry,fOriginTarget);
emit_sound ( ent, CHAN_WEAPON, "weapons/tok.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
}
else emit_sound ( ent, CHAN_WEAPON, "error_csdm/sentry/fire.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
if ( !get_user_godmode ( target ) && fHitRatio <= 0.0 )
sentry_damagetoplayer ( ent, 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 )
new Float:fAngle[3]
entity_get_vector(ent, EV_VEC_angles, fAngle)
fAngle[0] = 0.0
entity_set_vector(ent, EV_VEC_angles, fAngle)
}
}
else if ( firemode == SENTRY_FIREMODE_NUTS )
{
new iHitEnt2 = EntViewHitPoint ( ent, fOriginSentry, fOriginHit )
emit_sound(ent, CHAN_WEAPON, "error_csdm/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, 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, "error_csdm/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, "error_csdm/sentry/turrspot.wav", 1.0, ATTN_NORM, 0, PITCH_NORM )
SentryTurnToTarget ( ent, fOriginSentry, closestOrigin )
SetSentryFiremode ( ent, SENTRY_FIREMODE_YES )
SetSentryTarget ( ent, TARGET, closestTarget )
}
else
{
SetSentryFiremode ( ent, SENTRY_FIREMODE_NO )
new Float:fAngle[3]
entity_get_vector(ent, EV_VEC_angles, fAngle)
fAngle[0] = 0.0
entity_set_vector(ent, EV_VEC_angles, fAngle)
}
entity_set_float ( ent, SENTRY_FL_LASTTHINK, fGameTime + g_THINKFREQUENCIES )
}
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 )
}
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, "^3[^4Действие^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 ( is_valid_ent ( ent ) )
remove_entity ( ent )
}
sentry_detonate_by_owner(owner, bool:quiet = false) {
if(sentries_num[owner]>0)
{
static ent = -1
while ((ent = find_ent_by_class(ent, SentryClassName)))
{
if( GetSentryPeople(ent,OWNER) != owner) continue;
sentry_detonate ( ent, quiet, false )
}
}
}
public client_disconnected(id) {
sentry_detonate_by_owner ( id )
}
// урон игроку
stock sentry_damagetoplayer(sentry, Float:sentryOrigin[3], target) {
new newHealth = get_user_health(target) - g_DMG
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[5]
contributors[0] = owner
contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
contributors[4] = GetSentryPeople(sentry, UPGRADER_4)
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)
case 4: SetSentryPeople(sentry,UPGRADER_4,0)
}
continue
}
// izvini 4yvak, no menya nakrilo
cs_set_user_money(contributors[i], cs_get_user_money(contributors[i]) + (i == 0 ? SENTRYOWNERAWARD : SENTRYASSISTAWARD))
}
// 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()
//add_user_exp ( owner )
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)
write_byte(g_DMG)
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 )
} */
SentryTurnToTarget (ent, Float:sentryOrigin[3], Float:closestOrigin[3]) {
new Float:newAngle[3]
entity_get_vector(ent, EV_VEC_angles, newAngle)
new Float:x = closestOrigin[0] - sentryOrigin[0]
new Float:z = closestOrigin[1] - sentryOrigin[1]
new Float:y = closestOrigin[2] - sentryOrigin[2]
newAngle[1] = floatasin(z/floatsqroot(x*x+z*z), degrees)
new Float:radians = floatatan(z/x, radian)
newAngle[1] = radians * g_ONEEIGHTYTHROUGHPI
if (closestOrigin[0] < sentryOrigin[0])
newAngle[1] -= 180.0
entity_set_float(ent, SENTRY_FL_ANGLE, newAngle[1])
new Float:h = closestOrigin[2] - sentryOrigin[2]
new Float:b = vector_distance(sentryOrigin, closestOrigin)
radians = floatatan(h/b, radian)
newAngle[0] = floatasin(x/floatsqroot(x*x+y*y), degrees)
newAngle[0] = radians * g_ONEEIGHTYTHROUGHPI
entity_set_vector(ent, EV_VEC_angles, newAngle)
}
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, SentryClassName))
l_sentry = hitEnt
else
l_sentry = 0
return l_sentry
}
return 0
}
// улучшение уровня пушки
bool:SentryUpgrade ( id, sentry )
{
if(!is_user_alive(id)||!is_user_connected(id))
return false
if ( GetSentryFiremode ( sentry ) == SENTRY_FIREMODE_NUTS )
return false
new iLevel = GetSentryLevel ( sentry )
if ( iLevel == SENTRY_LEVEL_5 )
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
// e ron don don
if (get_user_flags(id) & FLAG_VIP)
{
}
else
{
// e ron don don
if(GetSentryPeople(sentry,UPGRADER_1) == id ||
GetSentryPeople(sentry,UPGRADER_2) == id ||
GetSentryPeople(sentry,UPGRADER_3) == id ||
GetSentryPeople(sentry,UPGRADER_4) == id
)
return false
}
iLevel++
if (get_user_flags(id) & FLAG_VIP)
{
if ( cs_get_user_money ( id ) - g_COST_VIP[iLevel] < 0 )
{
client_print(id, print_center, "У тебя не хватает денег (нужно %d$)", g_COST_VIP[iLevel])
return false
}
}
else
{
if ( cs_get_user_money ( id ) - g_COST[iLevel] < 0 )
{
client_print(id, print_center, "У тебя не хватает денег (нужно %d$)", g_COST[iLevel])
return false
}
}
if (get_user_flags(id) & FLAG_VIP)
{
cs_set_user_money ( id, cs_get_user_money ( id ) - g_COST_VIP[iLevel] )
}
else
{
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/error_csdm/sentry/te_2.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_2.mdl" )
}
iUpgraderField = UPGRADER_1
}
case SENTRY_LEVEL_3:
{
switch ( iTeam )
{
case 1:entity_set_model ( sentry, "models/error_csdm/sentry/te_3.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_3.mdl" )
}
iUpgraderField = UPGRADER_2
}
case SENTRY_LEVEL_4:{
switch(iTeam){
case 1:entity_set_model ( sentry, "models/error_csdm/sentry/te_3.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_3.mdl" )
}
iUpgraderField = UPGRADER_3
}
case SENTRY_LEVEL_5:{
switch(iTeam){
case 1:entity_set_model ( sentry, "models/error_csdm/sentry/te_3.mdl" )
case 2:entity_set_model ( sentry, "models/error_csdm/sentry/ct_3.mdl" )
}
// entity_set_byte(sentry,EV_BYTE_controller2,120)
// entity_set_byte(sentry,EV_BYTE_controller3,120)
iUpgraderField = UPGRADER_4
}
}
new Float:fMins[3], Float:fMaxs[3]
fMins[0] = -10.0
fMins[1] = -10.0
fMins[2] = 0.0
fMaxs[0] = 10.0
fMaxs[1] = 10.0
fMaxs[2] = 40.0 // 4.0
entity_set_size ( sentry, fMins, fMaxs )
emit_sound ( sentry, CHAN_AUTO, "error_csdm/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 )
{
g_inBuilding[id] = false
sentry_detonate_by_owner ( id )
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, SentryClassName ) )
{
sentry = iHitEnt
base = entity_get_edict ( sentry, SENTRY_ENT_BASE )
}
if ( !is_valid_ent ( 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 ( 255, 255, 255, -1.0, 0.75, 0, 0.0, 0.6, 0.0, 0.0 )
show_dhudmessage(id, tempStatusBuffer)
show_dhudmessage(id, tempStatusBuffer2)
return FMRES_IGNORED
}
// прикосновение к пушке игрока
new Float:flood_touch[33]
public fw_TouchSentry ( sentry, player )
{
static Float:time;time=get_gametime()
if(flood_touch[player] < time)
SentryUpgrade ( player, sentry );
flood_touch[player] = time+1.0
return 1
}
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,GetSentryTarget(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/error_csdm/sentry/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)
}
// 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
new sentry = entity_get_edict(rocket,EV_ENT_owner)
for (new i = 1; i <= g_iMaxPlayers; i++) {
if (!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(sentry,origin_,i,flDmgToDo)
}
}
remove_entity(rocket)
}
// 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(sentry, Float:sentryOrigin[3], target, Float:dmg) {
new newHealth = get_user_health(target) - floatround(dmg)
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[5]
contributors[0] = owner
contributors[1] = GetSentryPeople(sentry, UPGRADER_1)
contributors[2] = GetSentryPeople(sentry, UPGRADER_2)
contributors[3] = GetSentryPeople(sentry, UPGRADER_3)
contributors[4] = GetSentryPeople(sentry, UPGRADER_4)
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)
case 4: SetSentryPeople(sentry,UPGRADER_4,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)
write_byte(g_DMG)
write_long(DMG_BLAST)
write_coord(floatround(sentryOrigin[0]))
write_coord(floatround(sentryOrigin[1]))
write_coord(floatround(sentryOrigin[2]))
message_end()
}
FireZevs(Float:starting[3], Float:ending[3])
{
new OriginStr[3],OriginEnd[3];
//Еффект луча от пушки до цели.
FVecIVec(starting,OriginStr)
FVecIVec(ending,OriginEnd)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMPOINTS);
write_coord(OriginStr[0]);
write_coord(OriginStr[1]);
write_coord(OriginStr[2]);
write_coord(OriginEnd[0]);
write_coord(OriginEnd[1]);
write_coord(OriginEnd[2]);
write_short(g_Sprt_Tok);
write_byte(0);
write_byte(1);
write_byte(1);
write_byte(random_num(10, 50));
write_byte(random_num(10, 25));
write_byte(random_num(0, 255));
write_byte(random_num(0, 255));
write_byte(random_num(0, 255));
write_byte(1000);
write_byte(0);
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;
}
Download all Attachments
-
64.5 KB Просмотры: 32
-
72 KB Просмотры: 40