Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2018
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 40.65 KB | None | 0 0
  1. #pragma semicolon 1
  2. #include <sourcemod>
  3. #include <sdktools>
  4. #include <sdktools_functions>
  5. #include <sdkhooks>
  6.  
  7. #define Pai 3.14159265358979323846
  8. #define DEBUG false
  9.  
  10. #define State_None 0
  11. #define State_Scan 1
  12. #define State_Sleep 2
  13. #define State_Carry 3
  14.  
  15. #define PARTICLE_MUZZLE_FLASH "weapon_muzzle_flash_autoshotgun"
  16. #define PARTICLE_WEAPON_TRACER "weapon_tracers"
  17. #define PARTICLE_WEAPON_TRACER2 "weapon_tracers_50cal"//weapon_tracers_50cal" //"weapon_tracers_explosive" weapon_tracers_50cal
  18.  
  19. #define PARTICLE_BLOOD "blood_impact_red_01"
  20. #define PARTICLE_BLOOD2 "blood_impact_headshot_01"
  21.  
  22. #define SOUND_IMPACT1 "physics/flesh/flesh_impact_bullet1.wav"
  23. #define SOUND_IMPACT2 "physics/concrete/concrete_impact_bullet1.wav"
  24. #define SOUND_FIRE "weapons/50cal/50cal_shoot.wav"
  25. #define MODEL_W_PIPEBOMB "models/w_models/weapons/w_eq_pipebomb.mdl"
  26. #define MODEL_GUN "models/w_models/weapons/w_minigun.mdl"
  27. #define MODEL_GUN2 "models/w_models/weapons/50cal.mdl"
  28.  
  29. new MachineCount=0;
  30.  
  31. new GameMode;
  32. new L4D2Version;
  33.  
  34. #define EnemyArraySize 300
  35. new InfectedsArray[EnemyArraySize];
  36. new InfectedCount;
  37.  
  38. new UseCount[MAXPLAYERS+1];
  39.  
  40. new Float:ScanTime=0.0;
  41. new GunType[MAXPLAYERS+1];
  42.  
  43. new GunState[MAXPLAYERS+1];
  44. new Gun[MAXPLAYERS+1];
  45. new GunOwner[MAXPLAYERS+1];
  46. new GunUser[MAXPLAYERS+1];
  47. new GunEnemy[MAXPLAYERS+1];
  48. new GunTeam[MAXPLAYERS+1];
  49. new GunAmmo[MAXPLAYERS+1];
  50. new AmmoIndicator[MAXPLAYERS+1];
  51.  
  52. new GunCarrier[MAXPLAYERS+1];
  53. new Float:GunCarrierOrigin[MAXPLAYERS+1][3];
  54. new Float:GunCarrierAngle[MAXPLAYERS+1][3];
  55.  
  56. new Float:GunFireStopTime[MAXPLAYERS+1];
  57. new Float:GunLastCarryTime[MAXPLAYERS+1];
  58.  
  59. new Float:GunFireTime[MAXPLAYERS+1];
  60. new Float:GunFireTotolTime[MAXPLAYERS+1];
  61. new GunScanIndex[MAXPLAYERS+1];
  62. new Float:GunHealth[MAXPLAYERS+1];
  63.  
  64. new bool:Broken[MAXPLAYERS+1];
  65. new LastButton[MAXPLAYERS+1];
  66. new Float:PressTime[MAXPLAYERS+1];
  67. new Float:LastTime[MAXPLAYERS+1];
  68.  
  69. new ShowMsg[MAXPLAYERS+1];
  70.  
  71. new g_PointHurt;
  72.  
  73.  
  74. public Plugin:myinfo =
  75. {
  76. name = "Sentry Gun",
  77. author = "Original: Pan Xiaohai - modded by Mr. Man",
  78. description = "",
  79. version = "1.08",
  80. }
  81. new Handle:l4d_machine_enable ;
  82. new Handle:l4d_machine_damage_to_infected ;
  83. new Handle:l4d_machine_damage_to_survivor ;
  84. new Handle:l4d_machine_maxcount ;
  85. new Handle:l4d_machine_range ;
  86. new Handle:l4d_machine_overheat ;
  87.  
  88. new Handle:l4d_machine_adminonly ;
  89. new Handle:l4d_machine_msg ;
  90. new Handle:l4d_machine_ammo_count ;
  91. new Handle:l4d_machine_ammo_type ;
  92. new Handle:l4d_machine_ammo_refill ;
  93. new Handle:l4d_machine_allow_carry ;
  94. new Handle:l4d_machine_sleep_time ;
  95. new Handle:l4d_machine_fire_rate ;
  96. new Handle:l4d_machine_health ;
  97.  
  98. new Handle:l4d_machine_betray_chance ;
  99.  
  100. new Handle:l4d_machine_limit ;
  101.  
  102. public OnPluginStart()
  103. {
  104. GameCheck();
  105. l4d_machine_enable = CreateConVar("l4d_machine_enable", "2", " 0:disable, 1:enable in coop mode, 2: enable in all mode ", FCVAR_PLUGIN);
  106. l4d_machine_damage_to_infected=CreateConVar("l4d_machine_damage_to_infected", "25.0", "bullet damage", FCVAR_PLUGIN);
  107. l4d_machine_damage_to_survivor=CreateConVar("l4d_machine_damage_to_survivor", "2.0", "bullet damage", FCVAR_PLUGIN);
  108. l4d_machine_maxcount=CreateConVar("l4d_machine_maxuser", "3", "maxmum of machine gun", FCVAR_PLUGIN);
  109. l4d_machine_range=CreateConVar("l4d_machine_range", "1000.0", "maxmum scan range of machine gun", FCVAR_PLUGIN);
  110. l4d_machine_overheat=CreateConVar("l4d_machine_overheat", "10.0", " seconds", FCVAR_PLUGIN);
  111.  
  112.  
  113. l4d_machine_adminonly=CreateConVar("l4d_machine_adminonly", "0", "1:admin use only", FCVAR_PLUGIN);
  114. l4d_machine_msg=CreateConVar("l4d_machine_msg", "1", "how many times to display usage information , 0 disable ", FCVAR_PLUGIN);
  115. l4d_machine_ammo_count=CreateConVar("l4d_machine_ammo_count", "1000", "ammo count", FCVAR_PLUGIN);
  116. l4d_machine_ammo_type=CreateConVar("l4d_machine_ammo_type", "0", "0: normal , 1:incendiary 2:explosive", FCVAR_PLUGIN);
  117. l4d_machine_ammo_refill=CreateConVar("l4d_machine_ammo_refill", "1", "0:disable, 1:enable", FCVAR_PLUGIN);
  118. l4d_machine_allow_carry=CreateConVar("l4d_machine_allow_carry", "1", "0:disable carray 1:every one, 2:only creator", FCVAR_PLUGIN);
  119. l4d_machine_sleep_time=CreateConVar("l4d_machine_sleep_time", "300.0", "how many seconds does a gun goto sleep while no enemy, must >0", FCVAR_PLUGIN);
  120. l4d_machine_fire_rate=CreateConVar("l4d_machine_fire_rate", "20", "rate of fire, how many shot per soncods [5, 30]", FCVAR_PLUGIN);
  121. l4d_machine_health=CreateConVar("l4d_machine_health", "500.0", "gun's health", FCVAR_PLUGIN);
  122.  
  123. l4d_machine_betray_chance=CreateConVar("l4d_machine_betray_chance", "0.0", "betray chance", FCVAR_PLUGIN);
  124.  
  125.  
  126. l4d_machine_limit=CreateConVar("l4d_machine_limit", "1", " ", FCVAR_PLUGIN);
  127.  
  128. AutoExecConfig(true, "l4d_machine");
  129.  
  130.  
  131. HookConVarChange(l4d_machine_range, ConVarChange);
  132. HookConVarChange(l4d_machine_overheat, ConVarChange);
  133. HookConVarChange(l4d_machine_sleep_time, ConVarChange);
  134. HookConVarChange(l4d_machine_fire_rate, ConVarChange);
  135. HookConVarChange(l4d_machine_ammo_count, ConVarChange);
  136.  
  137. HookEvent("player_bot_replace", player_bot_replace );
  138. HookEvent("witch_harasser_set", witch_harasser_set);
  139. HookEvent("entity_shoved", entity_shoved);
  140. HookEvent("player_use", player_use);
  141.  
  142. HookEvent("round_start", round_end);
  143. HookEvent("round_end", round_end);
  144. HookEvent("finale_win", round_end);
  145. HookEvent("mission_lost", round_end);
  146. HookEvent("map_transition", round_end);
  147.  
  148. RegConsoleCmd("sm_sentry", sm_sentry);
  149. RegConsoleCmd("sm_rsentry", sm_rsentry);
  150. ResetAllState();
  151. GetConVar();
  152.  
  153. }
  154. public ConVarChange(Handle:convar, const String:oldValue[], const String:newValue[])
  155. {
  156. GetConVar();
  157. }
  158. new Float:FireIntervual=0.05;
  159. new Float:FireOverHeatTime=25.0;
  160. new Float:FireRange=1200.0;
  161. new Float:SleepTime=300.0;
  162. new GunAmmoCount=1000;
  163. GetConVar()
  164. {
  165.  
  166. FireOverHeatTime=GetConVarFloat(l4d_machine_overheat );
  167. FireRange=GetConVarFloat(l4d_machine_range );
  168. SleepTime=GetConVarFloat(l4d_machine_sleep_time);
  169. FireIntervual=GetConVarFloat(l4d_machine_fire_rate);
  170. GunAmmoCount=GetConVarInt(l4d_machine_ammo_count);
  171.  
  172. if(FireOverHeatTime<=0.0)FireOverHeatTime=10.0;
  173. if(FireRange<=0.0)FireRange=1.0;
  174. if(SleepTime<=0.0)SleepTime=300.0;
  175. if(FireIntervual<=5.0)FireIntervual=5.0;
  176. if(FireIntervual>=30.0)FireIntervual=30.0;
  177. FireIntervual=1.0/FireIntervual;
  178. }
  179. bool:CanUse()
  180. {
  181. new mode=GetConVarInt(l4d_machine_enable);
  182. if(mode==0)return false;
  183. if(mode==1 && GameMode!=2)return true;
  184. if(mode==2)return true;
  185. return false;
  186. }
  187. public Action:entity_shoved(Handle:event, String:event_name[], bool:dontBroadcast)
  188. {
  189. if(!CanUse()) return Plugin_Continue;
  190. if(GetConVarInt(l4d_machine_allow_carry)==0)return Plugin_Continue;
  191. new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
  192.  
  193. if(attacker>0 && IsClientInGame(attacker) && GetClientTeam(attacker)==2)
  194. {
  195. new b=GetClientButtons(attacker);
  196. if(b & IN_DUCK)
  197. {
  198. new gun=GetMinigun(attacker);
  199. if(gun>0)
  200. {
  201. StartCarry(attacker, gun);
  202. }
  203. }
  204. }
  205. return Plugin_Continue;
  206. }
  207.  
  208.  
  209. public Action:player_use(Handle:hEvent, const String:strName[], bool:DontBroadcast)
  210. {
  211. if(!CanUse()) return Plugin_Continue;
  212. if(GetConVarInt(l4d_machine_ammo_refill)==0) return Plugin_Continue;
  213. new client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
  214. new ent=GetEventInt(hEvent, "targetid");
  215. {
  216. decl String:classname[64];
  217. if(IsValidEntity(ent) && IsValidEdict(ent) && GetEdictClassname(ent, classname, 64))
  218. if(StrContains(classname, "ammo")>=0)
  219. {
  220. new index=FindCarryIndex(client);
  221. if(index>=0)
  222. {
  223. PrintHintText(client, "Sentry gun ammo refilled");
  224. GunAmmo[index]=GetConVarInt(l4d_machine_ammo_count);
  225. }
  226. }
  227. }
  228. return Plugin_Continue;
  229.  
  230. }
  231. GetMinigun(client )
  232. {
  233. new ent= GetClientAimTarget(client, false);
  234. if(ent>0)
  235. {
  236. decl String:classname[64];
  237. GetEdictClassname(ent, classname, 64);
  238. if(StrEqual(classname, "prop_minigun") || StrEqual(classname, "prop_minigun_l4d1"))
  239. {
  240. }
  241. else ent=0;
  242. }
  243. return ent;
  244. }
  245.  
  246. public Action:sm_sentry(client,args)
  247. {
  248. if(UseCount[client]>=GetConVarInt(l4d_machine_limit))
  249. {
  250. PrintToChat(client, "\x04[Sentry] \x01You've reached the max sentry gun limit for yourself: \x04%d\x01.",GetConVarInt(l4d_machine_limit));
  251. return;
  252. }
  253.  
  254. if(client>0 && IsClientInGame(client) && IsPlayerAlive(client))
  255. {
  256. if(GetConVarInt(l4d_machine_adminonly)==1 && GetUserFlagBits(client)==0)
  257. {
  258. PrintToChatAll("\x04[Sentry] \x01Only an admin can spawn sentry guns.");
  259. return;
  260. }
  261. new String:str[32];
  262. new type=GetCmdArg(1, str, 32);
  263. if(strlen(str)==0)type=GetRandomInt(0,1);
  264. else
  265. {
  266. if(StrEqual(str, "0"))type=0;
  267. else type=1;
  268. }
  269. CreateMachine(client, type);
  270. }
  271. }
  272. public Action:sm_rsentry(client,args)
  273. {
  274. if(client>0 && IsClientInGame(client) && IsPlayerAlive(client))
  275. {
  276. new gun=GetMinigun(client);
  277. new index=FindGunIndex(gun);
  278. if(index<0)return;
  279. if(GetUserFlagBits(client)!=0)
  280. {
  281. new owner=GunOwner[index];
  282. if(owner==client)RemoveMachine(index);
  283. else if(owner>0 && IsClientInGame(owner) && IsPlayerAlive(owner))
  284. {
  285. PrintHintText(client, "You can't remove %N 's sentry gun", owner);
  286. }
  287. else
  288. {
  289. RemoveMachine(index);
  290. }
  291. }
  292. else
  293. {
  294. RemoveMachine(index);
  295. }
  296. }
  297. }
  298. public player_bot_replace(Handle:Spawn_Event, const String:Spawn_Name[], bool:Spawn_Broadcast)
  299. {
  300. if(!CanUse())return;
  301. new client = GetClientOfUserId(GetEventInt(Spawn_Event, "player"));
  302. new bot = GetClientOfUserId(GetEventInt(Spawn_Event, "bot"));
  303. StopClientCarry(client);
  304. StopClientCarry(bot);
  305. }
  306.  
  307. public Action:witch_harasser_set(Handle:hEvent, const String:strName[], bool:DontBroadcast)
  308. {
  309. if(!CanUse())return;
  310. new witch = GetEventInt(hEvent, "witchid") ;
  311. InfectedsArray[0]=witch;
  312. for(new i=0; i<MachineCount; i++)
  313. {
  314. GunEnemy[i]=witch;
  315. GunScanIndex[i]=0;
  316. }
  317. }
  318. public bool:TraceRayDontHitSelf(entity, mask, any:data)
  319. {
  320. if(entity == data)
  321. {
  322. return false;
  323. }
  324. return true;
  325. }
  326.  
  327. CopyVector(Float:source[3], Float:target[3])
  328. {
  329. target[0]=source[0];
  330. target[1]=source[1];
  331. target[2]=source[2];
  332. }
  333. SetVector(Float:target[3], Float:x, Float:y, Float:z)
  334. {
  335. target[0]=x;
  336. target[1]=y;
  337. target[2]=z;
  338. }
  339. GameCheck()
  340. {
  341. decl String:GameName[16];
  342. GetConVarString(FindConVar("mp_gamemode"), GameName, sizeof(GameName));
  343.  
  344.  
  345. if (StrEqual(GameName, "survival", false))
  346. GameMode = 3;
  347. else if (StrEqual(GameName, "versus", false) || StrEqual(GameName, "teamversus", false) || StrEqual(GameName, "scavenge", false) || StrEqual(GameName, "teamscavenge", false))
  348. GameMode = 2;
  349. else if (StrEqual(GameName, "coop", false) || StrEqual(GameName, "realism", false))
  350. GameMode = 1;
  351. else
  352. {
  353. GameMode = 0;
  354. }
  355.  
  356.  
  357. GetGameFolderName(GameName, sizeof(GameName));
  358. if (StrEqual(GameName, "left4dead2", false))
  359. {
  360. L4D2Version=true;
  361. }
  362. else
  363. {
  364. L4D2Version=false;
  365. }
  366.  
  367. }
  368. public Action:round_end(Handle:event, const String:name[], bool:dontBroadcast)
  369. {
  370. ResetAllState();
  371. }
  372.  
  373. public OnMapStart()
  374. {
  375. PrecacheModel(MODEL_W_PIPEBOMB);
  376. PrecacheModel(MODEL_GUN);
  377. PrecacheModel(MODEL_GUN2);
  378.  
  379. PrecacheSound(SOUND_FIRE);
  380. PrecacheSound(SOUND_IMPACT1);
  381. PrecacheSound(SOUND_IMPACT2);
  382.  
  383.  
  384. PrecacheParticle(PARTICLE_MUZZLE_FLASH);
  385.  
  386. if(L4D2Version)
  387. {
  388. PrecacheParticle(PARTICLE_WEAPON_TRACER2);
  389. PrecacheParticle(PARTICLE_BLOOD2);
  390. }
  391. else
  392. {
  393. PrecacheParticle(PARTICLE_WEAPON_TRACER);
  394. PrecacheParticle(PARTICLE_BLOOD);
  395. }
  396. }
  397.  
  398. public Action:ShowInfo(Handle:timer, any:client)
  399. {
  400. if(L4D2Version )DisplayHint(INVALID_HANDLE, client);
  401. else PrintToChat(client, "\x04[Sentry] \x01Press \x04CROUCH+SHOVE \x01at the sentry gun to carry it.");
  402. }
  403. //code from "DJ_WEST"
  404.  
  405. public Action:DisplayHint(Handle:h_Timer, any:i_Client)
  406. {
  407. if ( IsClientInGame(i_Client)) ClientCommand(i_Client, "gameinstructor_enable 1");
  408. CreateTimer(1.0, DelayDisplayHint, i_Client);
  409. }
  410. public Action:DelayDisplayHint(Handle:h_Timer, any:i_Client)
  411. {
  412. DisplayInstructorHint(i_Client, "DUCK+SHOVE to carry machine gun", "+attack2");
  413. }
  414. public DisplayInstructorHint(i_Client, String:s_Message[256], String:s_Bind[])
  415. {
  416. decl i_Ent, String:s_TargetName[32], Handle:h_RemovePack;
  417.  
  418. i_Ent = CreateEntityByName("env_instructor_hint");
  419. FormatEx(s_TargetName, sizeof(s_TargetName), "hint%d", i_Client);
  420. ReplaceString(s_Message, sizeof(s_Message), "\n", " ");
  421. DispatchKeyValue(i_Client, "targetname", s_TargetName);
  422. DispatchKeyValue(i_Ent, "hint_target", s_TargetName);
  423. DispatchKeyValue(i_Ent, "hint_timeout", "5");
  424. DispatchKeyValue(i_Ent, "hint_range", "0.01");
  425. DispatchKeyValue(i_Ent, "hint_color", "255 255 255");
  426. DispatchKeyValue(i_Ent, "hint_icon_onscreen", "use_binding");
  427. DispatchKeyValue(i_Ent, "hint_caption", s_Message);
  428. DispatchKeyValue(i_Ent, "hint_binding", s_Bind);
  429. DispatchSpawn(i_Ent);
  430. AcceptEntityInput(i_Ent, "ShowHint");
  431.  
  432. h_RemovePack = CreateDataPack();
  433. WritePackCell(h_RemovePack, i_Client);
  434. WritePackCell(h_RemovePack, i_Ent);
  435. CreateTimer(5.0, RemoveInstructorHint, h_RemovePack);
  436. }
  437.  
  438. public Action:RemoveInstructorHint(Handle:h_Timer, Handle:h_Pack)
  439. {
  440. decl i_Ent, i_Client;
  441.  
  442. ResetPack(h_Pack, false);
  443. i_Client = ReadPackCell(h_Pack);
  444. i_Ent = ReadPackCell(h_Pack);
  445. CloseHandle(h_Pack);
  446.  
  447. if (!i_Client || !IsClientInGame(i_Client))
  448. return Plugin_Handled;
  449.  
  450. if (IsValidEntity(i_Ent))
  451. RemoveEdict(i_Ent);
  452.  
  453. ClientCommand(i_Client, "gameinstructor_enable 0");
  454.  
  455. DispatchKeyValue(i_Client, "targetname", "");
  456.  
  457. return Plugin_Continue;
  458. }
  459.  
  460. public PrecacheParticle(String:particlename[])
  461. {
  462. new particle = CreateEntityByName("info_particle_system");
  463. if (IsValidEdict(particle))
  464. {
  465. DispatchKeyValue(particle, "effect_name", particlename);
  466. DispatchSpawn(particle);
  467. ActivateEntity(particle);
  468. AcceptEntityInput(particle, "start");
  469. CreateTimer(0.01, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
  470. }
  471. }
  472. public Action:DeleteParticles(Handle:timer, any:particle)
  473. {
  474. if (IsValidEntity(particle))
  475. {
  476. decl String:classname[64];
  477. GetEdictClassname(particle, classname, sizeof(classname));
  478. if (StrEqual(classname, "info_particle_system", false))
  479. {
  480. AcceptEntityInput(particle, "stop");
  481. AcceptEntityInput(particle, "kill");
  482. RemoveEdict(particle);
  483. }
  484. }
  485. }
  486. public Action:DeleteParticletargets(Handle:timer, any:target)
  487. {
  488. if (IsValidEntity(target))
  489. {
  490. decl String:classname[64];
  491. GetEdictClassname(target, classname, sizeof(classname));
  492. if (StrEqual(classname, "info_particle_target", false) || StrEqual(classname, "info_target", false))
  493. {
  494. AcceptEntityInput(target, "stop");
  495. AcceptEntityInput(target, "kill");
  496. RemoveEdict(target);
  497. }
  498. }
  499. }
  500. public ShowParticle(Float:pos[3], Float:ang[3],String:particlename[], Float:time)
  501. {
  502. new particle = CreateEntityByName("info_particle_system");
  503. if (IsValidEdict(particle))
  504. {
  505. DispatchKeyValue(particle, "effect_name", particlename);
  506. DispatchSpawn(particle);
  507. ActivateEntity(particle);
  508. TeleportEntity(particle, pos, ang, NULL_VECTOR);
  509. AcceptEntityInput(particle, "start");
  510. CreateTimer(time, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
  511. return particle;
  512. }
  513. return 0;
  514. }
  515.  
  516. ShowMuzzleFlash(Float:pos[3], Float:angle[3])
  517. {
  518. new particle = CreateEntityByName("info_particle_system");
  519. DispatchKeyValue(particle, "effect_name", PARTICLE_MUZZLE_FLASH);
  520. DispatchSpawn(particle);
  521. ActivateEntity(particle);
  522. TeleportEntity(particle, pos, angle, NULL_VECTOR);
  523. AcceptEntityInput(particle, "start");
  524. CreateTimer(0.01, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
  525. }
  526. ShowTrack( Float:pos[3], Float:endpos[3] )
  527. {
  528. decl String:temp[32];
  529. new target =0;
  530. if(L4D2Version)target=CreateEntityByName("info_particle_target");
  531. else target=CreateEntityByName("info_target");
  532. Format(temp, 32, "cptarget%d", target);
  533. DispatchKeyValue(target, "targetname", temp);
  534. TeleportEntity(target, endpos, NULL_VECTOR, NULL_VECTOR);
  535. ActivateEntity(target);
  536.  
  537. new particle = CreateEntityByName("info_particle_system");
  538. if(L4D2Version) DispatchKeyValue(particle, "effect_name", PARTICLE_WEAPON_TRACER2);
  539. else DispatchKeyValue(particle, "effect_name", PARTICLE_WEAPON_TRACER);
  540. DispatchKeyValue(particle, "cpoint1", temp);
  541. DispatchSpawn(particle);
  542. ActivateEntity(particle);
  543. TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR);
  544. AcceptEntityInput(particle, "start");
  545. CreateTimer(0.01, DeleteParticletargets, target, TIMER_FLAG_NO_MAPCHANGE);
  546. CreateTimer(0.01, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
  547. }
  548. CreatePointHurt()
  549. {
  550. new pointHurt=CreateEntityByName("point_hurt");
  551. if(pointHurt)
  552. {
  553. DispatchKeyValue(pointHurt,"Damage","10");
  554. if(L4D2Version) DispatchKeyValue(pointHurt,"DamageType","-2130706430");
  555. DispatchSpawn(pointHurt);
  556. }
  557. return pointHurt;
  558. }
  559. new String:N[10];
  560. DoPointHurtForInfected(victim, attacker=0, team)
  561. {
  562. if(g_PointHurt > 0)
  563. {
  564. if(IsValidEdict(g_PointHurt))
  565. {
  566. if(victim>0 && IsValidEdict(victim))
  567. {
  568.  
  569. Format(N, 20, "target%d", victim);
  570. DispatchKeyValue(victim,"targetname", N);
  571. DispatchKeyValue(g_PointHurt,"DamageTarget", N);
  572. new Float:FireDamage;
  573. if(team==2)FireDamage=GetConVarFloat(l4d_machine_damage_to_infected);
  574. else FireDamage=GetConVarFloat(l4d_machine_damage_to_survivor);
  575. DispatchKeyValueFloat(g_PointHurt,"Damage", FireDamage);
  576. new type=GetConVarInt(l4d_machine_ammo_type);
  577. if(type==1 && victim<=MaxClients)type=0;
  578. if(L4D2Version)
  579. {
  580. if(type==1 && victim<=MaxClients)type=0;
  581. if(type==1 && victim<=MaxClients)type=0;
  582. if(type==0)DispatchKeyValue(g_PointHurt,"DamageType","-2130706430");
  583. else if(type==1)
  584. {
  585. IntToString(DMG_BURN, N, sizeof(N));
  586. DispatchKeyValue(g_PointHurt,"DamageType",N); //incendiary
  587. }
  588. else if(type==2)
  589. {
  590. IntToString(DMG_BLAST, N, sizeof(N));
  591. DispatchKeyValue(g_PointHurt,"DamageType",N); //explosive
  592. }
  593. DispatchKeyValueFloat(g_PointHurt,"Damage", FireDamage);
  594. }
  595. else
  596. {
  597. if(victim<=MaxClients)type=0;
  598. if(type==0)
  599. {
  600. new h=GetEntProp(victim, Prop_Data, "m_iHealth");
  601. if(h*1.0<=FireDamage) DispatchKeyValue(g_PointHurt, "DamageType", "64");
  602. else DispatchKeyValue(g_PointHurt, "DamageType", "-1073741822");
  603. }
  604. else if(type==1)
  605. {
  606. DispatchKeyValue(g_PointHurt, "DamageType", "8");
  607. }
  608. else if(type==2)
  609. {
  610. DispatchKeyValue(g_PointHurt, "DamageType", "64");
  611. }
  612. }
  613. AcceptEntityInput(g_PointHurt,"Hurt",(attacker>0)?attacker:-1);
  614. }
  615. }
  616. else g_PointHurt=CreatePointHurt();
  617. }
  618. else g_PointHurt=CreatePointHurt();
  619. }
  620.  
  621. ResetAllState()
  622. {
  623. g_PointHurt=0;
  624. MachineCount=0;
  625. ScanTime=0.0;
  626. for(new i=1; i<=MaxClients; i++)
  627. {
  628. GunState[i]=State_None;
  629. ShowMsg[i]=0;
  630. GunOwner[i]=GunCarrier[i]=Gun[i]=0;
  631. UseCount[i]=0;
  632. }
  633. ClearEnemys();
  634. GetConVar();
  635. }
  636. ScanEnemys()
  637. {
  638. if(IsWitch(InfectedsArray[0]))
  639. {
  640. InfectedCount=1;
  641. }
  642. else InfectedCount=0;
  643.  
  644. for(new i=1 ; i<=MaxClients; i++)
  645. {
  646. if(IsClientInGame(i) && IsPlayerAlive(i))
  647. {
  648. InfectedsArray[InfectedCount++]=i;
  649. }
  650. }
  651. new ent=-1;
  652. while ((ent = FindEntityByClassname(ent, "infected" )) != -1 && InfectedCount<EnemyArraySize-1)
  653. {
  654. InfectedsArray[InfectedCount++]=ent;
  655. }
  656. }
  657. ClearEnemys()
  658. {
  659. InfectedCount=0;
  660. }
  661. IsWitch(witch)
  662. {
  663. if(witch>0 && IsValidEdict(witch) && IsValidEntity(witch))
  664. {
  665. decl String:classname[32];
  666. GetEdictClassname(witch, classname, sizeof(classname));
  667. if(StrEqual(classname, "witch"))
  668. {
  669. return true;
  670. }
  671. }
  672. return false;
  673. }
  674. CreateMachine(client, type=0)
  675. {
  676. if(MachineCount>=GetConVarInt(l4d_machine_maxcount))
  677. {
  678. PrintToChat(client, "\x04[Sentry] \x01The maximum number of sentry guns on this map has been reached.");
  679. return;
  680. }
  681. if(IsClientInGame(client) && IsPlayerAlive(client))
  682. {
  683. if(!(GetEntityFlags(client) & FL_ONGROUND))return;
  684. Gun[MachineCount]=SpawnMiniGun(client, MachineCount, type);
  685. new gun=Gun[MachineCount];
  686. GunState[MachineCount]=State_Scan;
  687. LastTime[MachineCount]=GetEngineTime();
  688. Broken[MachineCount]=false;
  689.  
  690. GunScanIndex[MachineCount]=0;
  691. GunEnemy[MachineCount]=0;
  692. GunFireTime[MachineCount]=0.0;
  693. GunFireStopTime[MachineCount]=0.0;
  694. GunFireTotolTime[MachineCount]=0.0;
  695. GunOwner[MachineCount]=client;
  696. GunUser[MachineCount]=client;
  697. GunCarrier[MachineCount]=0;
  698. GunTeam[MachineCount]=2;
  699. AmmoIndicator[MachineCount]=0;
  700. GunLastCarryTime[MachineCount]=GetEngineTime();
  701. GunAmmo[MachineCount]=GetConVarInt(l4d_machine_ammo_count);
  702. GunHealth[MachineCount]=GetConVarFloat(l4d_machine_health);
  703. SDKUnhook( Gun[MachineCount], SDKHook_Think, PreThinkGun);
  704. SDKHook( Gun[MachineCount], SDKHook_Think, PreThinkGun);
  705.  
  706. UseCount[client]++;
  707. if(MachineCount==0)
  708. {
  709. ScanEnemys();
  710. }
  711.  
  712. if(ShowMsg[client]<GetConVarInt(l4d_machine_msg))
  713. {
  714. ShowMsg[client]++;
  715. CreateTimer(1.0, ShowInfo,client);
  716. }
  717.  
  718. MachineCount++;
  719.  
  720. SDKUnhook(gun, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
  721. SDKHook(gun, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
  722. }
  723. }
  724.  
  725. RemoveMachine(index)
  726. {
  727. if(GunState[index]==State_None)return;
  728. GunState[index]=State_None;
  729. SDKUnhook( Gun[index], SDKHook_Think, PreThinkGun);
  730. SDKUnhook(Gun[index], SDKHook_OnTakeDamagePost, OnTakeDamagePost);
  731. if(Gun[index]>0 && IsValidEdict(Gun[index]) && IsValidEntity(Gun[index]))AcceptEntityInput((Gun[index]), "Kill");
  732. Gun[index]=0;
  733. if(MachineCount>1)
  734. {
  735. Gun[index]=Gun[MachineCount-1];
  736. GunState[index]=GunState[MachineCount-1];
  737. LastTime[index]=LastTime[MachineCount-1];
  738. Broken[index]=Broken[MachineCount-1];
  739. GunScanIndex[index]=GunScanIndex[MachineCount-1];
  740. GunEnemy[index]=GunEnemy[MachineCount-1];
  741. GunFireTime[index]=GunFireTime[MachineCount-1];
  742. GunFireStopTime[index]=GunFireStopTime[MachineCount-1];
  743. GunFireTotolTime[index]=GunFireTotolTime[MachineCount-1];
  744. GunOwner[index]=GunOwner[MachineCount-1];
  745. GunUser[index]=GunUser[MachineCount-1];
  746. GunCarrier[index]=GunCarrier[MachineCount-1];
  747. GunLastCarryTime[index]=GunLastCarryTime[MachineCount-1];
  748. GunAmmo[index]=GunAmmo[MachineCount-1];
  749. AmmoIndicator[index]=AmmoIndicator[MachineCount-1];
  750. GunHealth[index]=GunHealth[MachineCount-1];
  751. GunTeam[index]=GunTeam[MachineCount-1];
  752. GunType[index]=GunType[MachineCount-1];
  753. }
  754. MachineCount--;
  755.  
  756. if(MachineCount<0)MachineCount=0;
  757. }
  758.  
  759. /* code from "Movable Machine Gun", author = "hihi1210"
  760. */
  761. SpawnMiniGun(client , index ,type)
  762. {
  763. decl Float:VecOrigin[3], Float:VecAngles[3], Float:VecDirection[3];
  764. new gun=0;
  765.  
  766. if(L4D2Version)
  767. {
  768. if(type==0)
  769. {
  770. gun=CreateEntityByName ( "prop_minigun_l4d1");
  771. SetEntityModel (gun, MODEL_GUN);
  772. GunType[index]=0;
  773. }
  774. else if(type==1)
  775. {
  776. gun=CreateEntityByName ( "prop_minigun");
  777. SetEntityModel (gun, MODEL_GUN2);
  778. GunType[index]=1;
  779. }
  780. }
  781. else
  782. {
  783. gun=CreateEntityByName ( "prop_minigun");
  784. SetEntityModel (gun, MODEL_GUN);
  785. GunType[index]=0;
  786. }
  787.  
  788. DispatchSpawn(gun);
  789.  
  790. GetClientAbsOrigin(client, VecOrigin);
  791. GetClientEyeAngles(client, VecAngles);
  792. GetAngleVectors(VecAngles, VecDirection, NULL_VECTOR, NULL_VECTOR);
  793. VecOrigin[0] += VecDirection[0] * 45;
  794. VecOrigin[1] += VecDirection[1] * 45;
  795. VecOrigin[2] += VecDirection[2] * 1;
  796. VecAngles[0] = 0.0;
  797. VecAngles[2] = 0.0;
  798. DispatchKeyValueVector(gun, "Angles", VecAngles);
  799.  
  800. TeleportEntity(gun, VecOrigin, NULL_VECTOR, NULL_VECTOR);
  801.  
  802. SetEntProp(gun, Prop_Send, "m_iTeamNum", 2);
  803. //SetEntProp(index, Prop_Data, "m_CollisionGroup", 2);
  804. SetColor(gun, 2);
  805.  
  806. return gun;
  807. }
  808. SetColor(gun, team)
  809. {
  810. if(!L4D2Version)return;
  811. SetEntProp(gun, Prop_Send, "m_iGlowType", 3);
  812. SetEntProp(gun, Prop_Send, "m_nGlowRange", 0);
  813. SetEntProp(gun, Prop_Send, "m_nGlowRangeMin", 1);
  814. new red=0;
  815. new gree=0;
  816. new blue=0;
  817. if(team==3)
  818. {
  819. red=200;
  820. gree=0;
  821. blue=0;
  822. }
  823. else
  824. {
  825. red=0;
  826. gree=100;
  827. blue=0;
  828. }
  829. SetEntProp(gun, Prop_Send, "m_glowColorOverride", red + (gree * 256) + (blue* 65536));
  830. }
  831. PutMiniGun(gun, Float:VecOrigin[3],Float:VecAngles[3])
  832. {
  833. new Float:VecDirection[3];
  834. GetAngleVectors(VecAngles, VecDirection, NULL_VECTOR, NULL_VECTOR);
  835. VecOrigin[0] += VecDirection[0] * 45;
  836. VecOrigin[1] += VecDirection[1] * 45;
  837. VecOrigin[2] += VecDirection[2] * 1;
  838. VecAngles[0] = 0.0;
  839. VecAngles[2] = 0.0;
  840. DispatchKeyValueVector(gun, "Angles", VecAngles);
  841. TeleportEntity(gun, VecOrigin, NULL_VECTOR, NULL_VECTOR);
  842. if(L4D2Version)
  843. {
  844. SetEntProp(gun, Prop_Send, "m_iGlowType", 3 ); //3
  845. SetEntProp(gun, Prop_Send, "m_nGlowRange", 0 ); //0
  846. SetEntProp(gun, Prop_Send, "m_glowColorOverride", 1); //1
  847. }
  848. return gun;
  849. }
  850. FindGunIndex(gun)
  851. {
  852. new index=-1;
  853. for(new i=0; i<MachineCount; i++)
  854. {
  855. if(Gun[i]==gun)
  856. {
  857. index=i;
  858. break;
  859. }
  860. }
  861. return index;
  862. }
  863. FindCarryIndex(client)
  864. {
  865. new index=-1;
  866. for(new i=0; i<MachineCount; i++)
  867. {
  868. if(GunCarrier[i]==client)
  869. {
  870. index=i;
  871. break;
  872. }
  873. }
  874. return index;
  875. }
  876. StartCarry(client, gun)
  877. {
  878. if(FindCarryIndex(client)>=0)return;
  879. new index=FindGunIndex(gun);
  880. if(index>=0)
  881. {
  882. if(GunCarrier[index]>0)return;
  883. if(GetConVarInt(l4d_machine_allow_carry)==2)
  884. {
  885. new owner=GunOwner[index];
  886. if(owner>0 && IsClientInGame(owner) && IsPlayerAlive(owner))
  887. {
  888. if(owner!=client)
  889. {
  890. PrintHintText(client, "You can't pick up %N 's sentry gun", owner);
  891. return;
  892. }
  893. }
  894. else
  895. {
  896. GunOwner[index]=client;
  897. }
  898. }
  899. GunCarrier[index]=client;
  900. SetEntProp(gun, Prop_Send, "m_CollisionGroup", 2);
  901. SetEntProp(gun, Prop_Send, "m_firing", 0);
  902. new Float:ang[3];
  903. SetVector(ang, 0.0, 0.0, 90.0);
  904. new Float:pos[3];
  905. SetVector(pos, -5.0, 20.0, 0.0);
  906. if(GetClientTeam(client)==2) AttachEnt(client, gun, "medkit", pos, ang);
  907. else AttachEnt(client, gun, "medkit", pos, ang);
  908. LastButton[index]=0;
  909. PressTime[index]=0.0;
  910. GunState[index]=State_Carry;
  911. GunUser[index]=client;
  912. GunLastCarryTime[index]=GetEngineTime();
  913. GunHealth[index]=GetConVarFloat(l4d_machine_health);
  914.  
  915. SDKUnhook(Gun[index], SDKHook_OnTakeDamagePost, OnTakeDamagePost);
  916.  
  917. GunTeam[index]=2;
  918.  
  919. SetColor(Gun[index], 2);
  920. if(GunAmmo[index]>0)
  921. {
  922. PrintHintText(client, "Sentry gun ammo count: %d ", GunAmmo[index] );
  923. }
  924. else
  925. {
  926. PrintHintText(client, "Your sentry gun is out of ammo - refill");
  927. }
  928. }
  929. }
  930. StopClientCarry(client)
  931. {
  932. if(client<=0)return;
  933. new index=FindCarryIndex(client);
  934. if(index>=0)
  935. {
  936. StopCarry(index);
  937. }
  938. return;
  939. }
  940. StopCarry(index)
  941. {
  942. if(GunCarrier[index]>0)
  943. {
  944. GunCarrier[index]=0;
  945. AcceptEntityInput(Gun[index], "ClearParent");
  946. PutMiniGun(Gun[index], GunCarrierOrigin[index], GunCarrierAngle[index]);
  947. SetEntProp(Gun[index], Prop_Send, "m_CollisionGroup", 0);
  948.  
  949. GunLastCarryTime[index]=GetEngineTime();
  950. GunState[index]=State_Scan;
  951. Broken[index]=false;
  952. GunEnemy[index]=0;
  953. GunScanIndex[index]=0;
  954. GunFireTotolTime[index]=0.0;
  955. GunTeam[index]=2;
  956. SDKHook(Gun[index], SDKHook_OnTakeDamagePost, OnTakeDamagePost);
  957. SetColor(Gun[index], 2);
  958. }
  959. }
  960. Carrying(index, Float:intervual)
  961. {
  962. new client=GunCarrier[index];
  963. new button=GetClientButtons(client);
  964. GetClientAbsOrigin(client , GunCarrierOrigin[index]);
  965. GetClientEyeAngles(client, GunCarrierAngle[index]);
  966. if(button & IN_USE)
  967. {
  968. PressTime[index]+=intervual;
  969. if(PressTime[index]>0.5)
  970. {
  971. if(GetEntityFlags(client) & FL_ONGROUND)StopCarry(index);
  972. }
  973. }
  974. else
  975. {
  976. PressTime[index]=0.0;
  977. }
  978.  
  979. LastButton[index]=client;
  980. }
  981. AttachEnt(owner, ent, String:positon[]="medkit", Float:pos[3]=NULL_VECTOR,Float:ang[3]=NULL_VECTOR)
  982. {
  983. decl String:tname[60];
  984. Format(tname, sizeof(tname), "target%d", owner);
  985. DispatchKeyValue(owner, "targetname", tname);
  986. DispatchKeyValue(ent, "parentname", tname);
  987.  
  988. SetVariantString(tname);
  989. AcceptEntityInput(ent, "SetParent",ent, ent, 0);
  990. if(strlen(positon)!=0)
  991. {
  992. SetVariantString(positon);
  993. AcceptEntityInput(ent, "SetParentAttachment");
  994. }
  995. TeleportEntity(ent, pos, ang, NULL_VECTOR);
  996. }
  997.  
  998. public PreThinkGun(gun)
  999. {
  1000. new index=FindGunIndex(gun);
  1001. if(index!=-1)
  1002. {
  1003. new Float:time=GetEngineTime( );
  1004. new Float:intervual=time-LastTime[index];
  1005. LastTime[index]=time;
  1006.  
  1007. if(GunState[index]==State_Scan || GunState[index]==State_Sleep)
  1008. {
  1009. ScanAndShotEnmey(index, time, intervual);
  1010. }
  1011. else if(GunState[index]==State_Carry)
  1012. {
  1013. new carrier=GunCarrier[index];
  1014. if(IsClientInGame(carrier) && IsPlayerAlive(carrier) && !IsFakeClient(carrier))
  1015. {
  1016. Carrying(index, intervual);
  1017. }
  1018. else
  1019. {
  1020. StopCarry(index);
  1021. }
  1022. }
  1023. }
  1024. }
  1025. public OnTakeDamagePost(victim, attacker, inflictor, Float:damage, damagetype)
  1026. {
  1027. new index=FindGunIndex(victim);
  1028. if(GunState[index]==State_Carry)return;
  1029. if(damage<=0.0)return;
  1030. if(index>=0)
  1031. {
  1032. new bool:betrayToInfected=false;
  1033. new bool:betrayToSurvivor=false;
  1034. new bool:print=false;
  1035. new bool:wakeup =false;
  1036. new bool:attackerIsPlayer=false;
  1037. if(attacker>0 && attacker<=MaxClients)
  1038. {
  1039. if(IsClientInGame(attacker))
  1040. {
  1041.  
  1042. if(GetClientTeam(attacker)==2 && damagetype==128)
  1043. {
  1044. if(GunTeam[index]==3)
  1045. {
  1046. betrayToInfected=false;
  1047. betrayToSurvivor=true;
  1048. }
  1049.  
  1050. }
  1051. else if(GunTeam[index]==2 )
  1052. {
  1053. betrayToInfected=true;
  1054. }
  1055. if(damagetype==128)wakeup=true;
  1056. attackerIsPlayer=true;
  1057. if(GetClientTeam(attacker)==3)
  1058. {
  1059. wakeup=true;
  1060. }
  1061. print=true;
  1062. }
  1063. else print=false;
  1064. }
  1065. else
  1066. {
  1067. if(GunTeam[index]==2)
  1068. {
  1069. betrayToInfected=true;
  1070. }
  1071. wakeup=true;
  1072. }
  1073. if(betrayToInfected && GetRandomFloat(0.0, 100.0)<GetConVarFloat(l4d_machine_betray_chance))
  1074. {
  1075. PrintHintTextToAll("A sentry gun has betrayed the survivors!");
  1076. GunLastCarryTime[index]=GetEngineTime();
  1077. //GunState[index]=State_Scan;
  1078. Broken[index]=false;
  1079. GunEnemy[index]=0;
  1080. GunScanIndex[index]=0;
  1081. GunFireTotolTime[index]=0.0;
  1082. GunTeam[index]=3;
  1083. GunHealth[index]=GetConVarFloat(l4d_machine_health);
  1084. if(attackerIsPlayer)GunUser[index]=attacker;
  1085. print=false;
  1086. SetColor(Gun[index], GunTeam[index]);
  1087.  
  1088. }
  1089. if(betrayToSurvivor)
  1090. {
  1091. PrintHintTextToAll("A sentry gun has defected to the infected!");
  1092. GunLastCarryTime[index]=GetEngineTime();
  1093. //GunState[index]=State_Scan;
  1094. Broken[index]=false;
  1095. GunEnemy[index]=0;
  1096. GunScanIndex[index]=0;
  1097. GunFireTotolTime[index]=0.0;
  1098. GunTeam[index]=2;
  1099. GunHealth[index]=GetConVarFloat(l4d_machine_health);
  1100. if(attackerIsPlayer)GunUser[index]=attacker;
  1101. print=false;
  1102. SetColor(Gun[index], GunTeam[index]);
  1103. }
  1104. if(wakeup && GunState[index]==State_Sleep)
  1105. {
  1106. PrintHintTextToAll("A sentry gun has woken up from hibernation");
  1107. GunLastCarryTime[index]=GetEngineTime();
  1108. GunState[index]=State_Scan;
  1109. Broken[index]=false;
  1110. GunEnemy[index]=0;
  1111. GunScanIndex[index]=0;
  1112. GunFireTotolTime[index]=0.0;
  1113. GunHealth[index]=GetConVarFloat(l4d_machine_health);
  1114. if(attackerIsPlayer)GunUser[index]=attacker;
  1115. print=false;
  1116. wakeup=true;
  1117. SetColor(Gun[index], GunTeam[index]);
  1118. }
  1119. else wakeup=false;
  1120. new Float:oldHealth=GunHealth[index];
  1121. if(!betrayToInfected && !betrayToSurvivor && !wakeup)GunHealth[index]-=damage;
  1122. if(GunHealth[index]<=0.0)
  1123. {
  1124. AcceptEntityInput(Gun[index], "Kill")
  1125. {
  1126. PrintHintText(GunUser[index], "Your sentry gun has been destroyed");
  1127. }
  1128. }
  1129. if(print)PrintHintText(attacker, "Sentry gun health: %d", RoundFloat(GunHealth[index]));
  1130.  
  1131. }
  1132.  
  1133. }
  1134. ScanAndShotEnmey(index , Float:time, Float:intervual)
  1135. {
  1136. new bool:ok=false;
  1137. new gun1=Gun[index];
  1138. if(gun1>0 && IsValidEdict(gun1) && IsValidEntity(gun1) ) ok=true;
  1139.  
  1140. new user=GunUser[index];
  1141. if(user>0 && IsClientInGame(user))user=user+0;
  1142. else user=0;
  1143.  
  1144. if(ok==false || Broken[index])
  1145. {
  1146. if(user>0)PrintHintText(user, "Your sentry gun is broken");
  1147. RemoveMachine(index);
  1148. }
  1149.  
  1150. Broken[index]=true;
  1151.  
  1152. if(GunState[index]==State_Sleep)
  1153. {
  1154. SetEntProp(gun1, Prop_Send, "m_firing", 0);
  1155. Broken[index]=false;
  1156. return;
  1157. }
  1158. if(time-ScanTime>1.0)
  1159. {
  1160. ScanTime=time;
  1161. ScanEnemys();
  1162. }
  1163.  
  1164. decl Float:gun1pos[3];
  1165. decl Float:gun1angle[3];
  1166. decl Float:hitpos[3];
  1167. decl Float:temp[3];
  1168. decl Float:shotangle[3];
  1169. decl Float:gunDir[3];
  1170.  
  1171. GetEntPropVector(gun1, Prop_Send, "m_vecOrigin", gun1pos);
  1172. GetEntPropVector(gun1, Prop_Send, "m_angRotation", gun1angle);
  1173.  
  1174. if(GunLastCarryTime[index]+SleepTime<time)
  1175. {
  1176. GunState[index]=State_Sleep;
  1177. gun1angle[0]=-45.0;
  1178. DispatchKeyValueVector(gun1, "Angles", gun1angle);
  1179. SetEntProp(gun1, Prop_Send, "m_firing", 0);
  1180. PrintToChatAll("\x04[Sentry] \x01A sentry gun is now hibernating.");
  1181. return;
  1182. }
  1183. GetAngleVectors(gun1angle, gunDir, NULL_VECTOR, NULL_VECTOR );
  1184. NormalizeVector(gunDir, gunDir);
  1185. CopyVector(gunDir, temp);
  1186. if(GunType[index]==0)ScaleVector(temp, 20.0);
  1187. else ScaleVector(temp, 50.0);
  1188. AddVectors(gun1pos, temp ,gun1pos);
  1189. GetAngleVectors(gun1angle, NULL_VECTOR, NULL_VECTOR, temp );
  1190. NormalizeVector(temp, temp);
  1191. //ShowDir(2, gun1pos, temp, 0.06);
  1192. ScaleVector(temp, 43.0);
  1193.  
  1194. AddVectors(gun1pos, temp ,gun1pos);
  1195.  
  1196.  
  1197. new newenemy=GunEnemy[index];
  1198. if( IsVilidEenmey(newenemy , GunTeam[index]))
  1199. {
  1200. newenemy=IsEnemyVisible(gun1, newenemy, gun1pos, hitpos,shotangle, GunTeam[index]);
  1201. }
  1202. else newenemy=0;
  1203.  
  1204. if(InfectedCount>0 && newenemy==0)
  1205. {
  1206. if(GunScanIndex[index]>=InfectedCount)
  1207. {
  1208. GunScanIndex[index]=0;
  1209. }
  1210. GunEnemy[index]=InfectedsArray[GunScanIndex[index]];
  1211. GunScanIndex[index]++;
  1212. newenemy=0;
  1213. //if(IsVilidEenmey(newenemy, GunTeam[index]))
  1214. //{
  1215. //newenemy=IsEnemyVisible(gun1, newenemy, gun1pos, hitpos, shotangle,GunTeam[index]);
  1216. //}
  1217. }
  1218. //GunEnemy[index]=newenemy;
  1219.  
  1220.  
  1221. //PrintToChatAll("team %d enemy %d",GunTeam[index], newenemy);
  1222. if(newenemy==0)
  1223. {
  1224. SetEntProp(gun1, Prop_Send, "m_firing", 0);
  1225. Broken[index]=false;
  1226. return;
  1227. }
  1228.  
  1229. decl Float:enemyDir[3];
  1230. decl Float:newGunAngle[3];
  1231. if(newenemy>0)
  1232. {
  1233. SubtractVectors(hitpos, gun1pos, enemyDir);
  1234. }
  1235. else
  1236. {
  1237. CopyVector(gunDir, enemyDir);
  1238. enemyDir[2]=0.0;
  1239. }
  1240. NormalizeVector(enemyDir,enemyDir);
  1241.  
  1242. decl Float:targetAngle[3];
  1243. GetVectorAngles(enemyDir, targetAngle);
  1244. new Float:diff0=AngleDiff(targetAngle[0], gun1angle[0]);
  1245. new Float:diff1=AngleDiff(targetAngle[1], gun1angle[1]);
  1246.  
  1247. new Float:turn0=45.0*Sign(diff0)*intervual;
  1248. new Float:turn1=180.0*Sign(diff1)*intervual;
  1249. if(FloatAbs(turn0)>=FloatAbs(diff0))
  1250. {
  1251. turn0=diff0;
  1252. }
  1253. if(FloatAbs(turn1)>=FloatAbs(diff1))
  1254. {
  1255. turn1=diff1;
  1256. }
  1257.  
  1258. newGunAngle[0]=gun1angle[0]+turn0;
  1259. newGunAngle[1]=gun1angle[1]+turn1;
  1260.  
  1261. newGunAngle[2]=0.0;
  1262.  
  1263. //PrintVector(newGunAngle);
  1264. DispatchKeyValueVector(gun1, "Angles", newGunAngle);
  1265. new overheated=GetEntProp(gun1, Prop_Send, "m_overheated");
  1266.  
  1267. GetAngleVectors(newGunAngle, gunDir, NULL_VECTOR, NULL_VECTOR);
  1268. //PrintToChatAll("find %d %f %f", newenemy );
  1269. if(overheated==0)
  1270. {
  1271. if( newenemy>0 && FloatAbs(diff1)<40.0)
  1272. {
  1273. if(time>=GunFireTime[index] && GunAmmo[index] >0)
  1274. {
  1275. GunFireTime[index]=time+FireIntervual;
  1276. Shot(user,index, gun1, GunTeam[index], gun1pos, newGunAngle);
  1277. GunAmmo[index]--;
  1278. AmmoIndicator[index]++;
  1279. if(AmmoIndicator[index]>=GunAmmoCount/20.0)
  1280. {
  1281. AmmoIndicator[index]=0;
  1282. if(user>0)PrintCenterText(user, "Machine gun's ammo: %d ( %d %%)", GunAmmo[index], RoundFloat(GunAmmo[index]*100.0/GunAmmoCount ));
  1283. }
  1284. if(GunAmmo[index]==0)
  1285. {
  1286. if(user>0)PrintHintText(user, "Your sentry gun is out of ammo - refill");
  1287. }
  1288. GunFireStopTime[index]=time+0.05;
  1289. GunLastCarryTime[index]=time;
  1290. }
  1291. }
  1292. }
  1293. new Float:heat=GetEntPropFloat(gun1, Prop_Send, "m_heat");
  1294.  
  1295. if(time<GunFireStopTime[index])
  1296. {
  1297. GunFireTotolTime[index]+=intervual;
  1298. heat=GunFireTotolTime[index]/FireOverHeatTime;
  1299. if(heat>=1.0)heat=1.0;
  1300. SetEntProp(gun1, Prop_Send, "m_firing", 1);
  1301. SetEntPropFloat(gun1, Prop_Send, "m_heat", heat);
  1302. }
  1303. else
  1304. {
  1305. SetEntProp(gun1, Prop_Send, "m_firing", 0);
  1306. heat=heat-intervual/4.0;
  1307. if(heat<0.0)
  1308. {
  1309. heat=0.0;
  1310. SetEntProp(gun1, Prop_Send, "m_overheated", 0);
  1311. SetEntPropFloat(gun1, Prop_Send, "m_heat", 0.0 );
  1312. }
  1313. else SetEntPropFloat(gun1, Prop_Send, "m_heat", heat );
  1314. GunFireTotolTime[index]=FireOverHeatTime*heat;
  1315. }
  1316. Broken[index]=false;
  1317. return;
  1318. }
  1319.  
  1320.  
  1321. IsEnemyVisible( gun, ent, Float:gunpos[3], Float:hitpos[3], Float:angle[3] ,team)
  1322. {
  1323.  
  1324. if(ent<=0)return 0;
  1325.  
  1326. GetEntPropVector(ent, Prop_Send, "m_vecOrigin", hitpos);
  1327. hitpos[2]+=35.0;
  1328.  
  1329. SubtractVectors(hitpos, gunpos, angle);
  1330. GetVectorAngles(angle, angle);
  1331. new Handle:trace=TR_TraceRayFilterEx(gunpos, angle, MASK_SHOT, RayType_Infinite, TraceRayDontHitSelf, gun);
  1332. if(team==2)team=3;
  1333. else team=2;
  1334. new newenemy=0;
  1335.  
  1336. if(TR_DidHit(trace))
  1337. {
  1338. TR_GetEndPosition(hitpos, trace);
  1339. newenemy=TR_GetEntityIndex(trace);
  1340. if(GetVectorDistance(gunpos, hitpos)>FireRange)newenemy=0;
  1341. }
  1342. else
  1343. {
  1344. newenemy=ent;
  1345. }
  1346. if(newenemy>0)
  1347. {
  1348. if(newenemy<=MaxClients)
  1349. {
  1350. if(IsClientInGame(newenemy) && IsPlayerAlive(newenemy) && GetClientTeam(newenemy)==team)
  1351. {
  1352. newenemy=newenemy+0;
  1353. }
  1354. else newenemy=0;
  1355. }
  1356. else if(team==3)
  1357. {
  1358. decl String:classname[32];
  1359. GetEdictClassname(newenemy, classname,32);
  1360. if(StrEqual(classname, "infected", true) || StrEqual(classname, "witch", true) )
  1361. {
  1362. newenemy=newenemy+0;
  1363. }
  1364. else newenemy=0;
  1365. }
  1366. }
  1367. CloseHandle(trace);
  1368. return newenemy;
  1369. }
  1370.  
  1371. Shot(client, index ,gun, team, Float:gunpos[3], Float:shotangle[3])
  1372. {
  1373. decl Float:temp[3];
  1374. decl Float:ang[3];
  1375. GetAngleVectors(shotangle, temp, NULL_VECTOR,NULL_VECTOR);
  1376. NormalizeVector(temp, temp);
  1377.  
  1378. new Float:acc=0.020;
  1379. temp[0] += GetRandomFloat(-1.0, 1.0)*acc;
  1380. temp[1] += GetRandomFloat(-1.0, 1.0)*acc;
  1381. temp[2] += GetRandomFloat(-1.0, 1.0)*acc;
  1382. GetVectorAngles(temp, ang);
  1383.  
  1384. new Handle:trace= TR_TraceRayFilterEx(gunpos, ang, MASK_SHOT, RayType_Infinite, TraceRayDontHitSelf, gun);
  1385. new enemy=0;
  1386.  
  1387. if(TR_DidHit(trace))
  1388. {
  1389. decl Float:hitpos[3];
  1390. TR_GetEndPosition(hitpos, trace);
  1391. enemy=TR_GetEntityIndex(trace);
  1392.  
  1393. new bool:blood=false;
  1394. if(enemy>0)
  1395. {
  1396. decl String:classname[32];
  1397. GetEdictClassname(enemy, classname, 32);
  1398. if(enemy >=1 && enemy<=MaxClients)
  1399. {
  1400. if(GetClientTeam(enemy)==team) {enemy=0;}
  1401. blood=true;
  1402. }
  1403. else if(StrEqual(classname, "infected") || StrEqual(classname, "witch" ) ){ }
  1404. else enemy=0;
  1405. }
  1406. if(enemy>0)
  1407. {
  1408. if(client>0 &&IsPlayerAlive(client))client=client+0;
  1409. else client=0;
  1410. DoPointHurtForInfected(enemy, client, team);
  1411. decl Float:Direction[3];
  1412. GetAngleVectors(ang, Direction, NULL_VECTOR, NULL_VECTOR);
  1413. ScaleVector(Direction, -1.0);
  1414. GetVectorAngles(Direction,Direction);
  1415. if(!L4D2Version || blood)ShowParticle(hitpos, Direction, PARTICLE_BLOOD, 0.1);
  1416. EmitSoundToAll(SOUND_IMPACT1, 0, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS,1.0, SNDPITCH_NORMAL, -1,hitpos, NULL_VECTOR,true, 0.0);
  1417. }
  1418. else
  1419. {
  1420. decl Float:Direction[3];
  1421. Direction[0] = GetRandomFloat(-1.0, 1.0);
  1422. Direction[1] = GetRandomFloat(-1.0, 1.0);
  1423. Direction[2] = GetRandomFloat(-1.0, 1.0);
  1424. TE_SetupSparks(hitpos,Direction,1,3);
  1425. TE_SendToAll();
  1426. EmitSoundToAll(SOUND_IMPACT2, 0, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS,1.0, SNDPITCH_NORMAL, -1,hitpos, NULL_VECTOR,true, 0.0);
  1427.  
  1428. }
  1429.  
  1430. ShowMuzzleFlash(gunpos, ang);
  1431. if(L4D2Version)ShowTrack(gunpos, hitpos);
  1432. else
  1433. {
  1434. //ShowPos(0, gunpos, hitpos, 0.06, 0.0, 0.5, 1.0);
  1435. }
  1436. if(GunType[index]==1)EmitSoundToAll(SOUND_FIRE, 0, SNDCHAN_WEAPON, SNDLEVEL_NORMAL, SND_NOFLAGS,1.0, SNDPITCH_NORMAL, -1,gunpos, NULL_VECTOR,true, 0.0);
  1437. }
  1438.  
  1439. CloseHandle(trace);
  1440.  
  1441. }
  1442. Float:AngleDiff(Float:a, Float:b)
  1443. {
  1444. new Float:d=0.0;
  1445. if(a>=b)
  1446. {
  1447. d=a-b;
  1448. if(d>=180.0)d=d-360.0;
  1449. }
  1450. else
  1451. {
  1452. d=a-b;
  1453. if(d<=-180.0)d=360+d;
  1454. }
  1455. return d;
  1456. }
  1457. Float:Sign(Float:v)
  1458. {
  1459. if(v==0.0)return 0.0;
  1460. else if(v>0.0)return 1.0;
  1461. else return -1.0;
  1462. }
  1463.  
  1464. bool:IsVilidEenmey(enemy ,team)
  1465. {
  1466. new bool:r=false;
  1467. if(enemy<=0)return r;
  1468. if(team==2)team=3;
  1469. else team=2;
  1470. if( enemy<=MaxClients)
  1471. {
  1472. if(IsClientInGame(enemy) && IsPlayerAlive(enemy) && GetClientTeam(enemy)==team)
  1473. {
  1474. r=true;
  1475. }
  1476. }
  1477. else if( team ==3 && IsValidEntity(enemy) && IsValidEdict(enemy))
  1478. {
  1479. decl String:classname[32];
  1480. GetEdictClassname(enemy, classname,32);
  1481. if(StrEqual(classname, "infected", true) )
  1482. {
  1483. r=true;
  1484. if(L4D2Version)
  1485. {
  1486. new flag=GetEntProp(enemy, Prop_Send, "m_bIsBurning");
  1487. if(flag==1)
  1488. {
  1489. r=false;
  1490. }
  1491. }
  1492. }
  1493. else if (StrEqual(classname, "witch", true))
  1494. {
  1495. r=true;
  1496. }
  1497. }
  1498. return r;
  1499. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement