Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.94 KB | None | 0 0
  1. #include <amxmodx>
  2. #include <engine>
  3. #include <fakemeta>
  4. #include <hamsandwich>
  5. #include <xs>
  6. #include <zp50_gamemodes>
  7. #include <zp50_ammopacks>
  8. #include <zombieplague>
  9. #include <amx_settings_api>
  10. #include <zp50_items>
  11. #include <zp50_class_dragon>
  12. #include <zp50_class_nightcrawler>
  13. #include <zp50_colorchat>
  14.  
  15. #define ZP_ITEM_NAME "Sandbag"
  16. #define ZP_ITEM_DESC "Protective breakable wall"
  17. #define ZP_ITEM_COST 30
  18. #define ZP_ITEM_LIMIT_PLAYER 2
  19. #define ZP_ITEM_LIMIT_ROUND 0
  20.  
  21. new const g_szGameFile[ ] = "zp_items.ini"
  22.  
  23. new g_iBarricadesPerPurchase = 1
  24.  
  25. // Max stuff
  26. #define MAX_ENTITIES 1024
  27.  
  28. // Custom forwards
  29. enum _:CustomForwards( )
  30. {
  31. FW_BARRICADE_SPAWN = 0,
  32. FW_BARRICADE_DELETE,
  33. FW_BARRICADE_TAKE_DAMAGE,
  34. FW_BARRICADE_DESTROYED
  35. };
  36.  
  37. enum ( += 100 )
  38. {
  39. TASK_BARRICADE_SPAWN = 100,
  40. TASK_BARRICADE_DELETE,
  41. TASK_BARRICADE_INFO
  42. };
  43.  
  44. #define ID_BARRICADE_SPAWN ( task_id - TASK_BARRICADE_SPAWN )
  45. #define ID_BARRICADE_DELETE ( task_id - TASK_BARRICADE_DELETE )
  46. #define ID_BARRICADE_INFO ( task_id - TASK_BARRICADE_INFO )
  47.  
  48. enum ( )
  49. {
  50. matGlass = 0,
  51. matWood,
  52. matMetal,
  53. matFlesh,
  54. matCinderBlock,
  55. matCeilingTile,
  56. matComputer,
  57. matUnbreakableGlass,
  58. matRocks,
  59. matNone,
  60. matLastMaterial
  61. };
  62.  
  63. new const g_szEntityBarricade[ ] = "func_barricade";
  64. new const g_szEntityBreakable[ ] = "func_breakable";
  65. new const g_szBarricadeModel[ ] = "models/pallet_with_bags.mdl";
  66.  
  67. new const g_szSoundCrateHit[ ][ ] =
  68. {
  69. "debris/bustcrate1.wav",
  70. "debris/bustcrate2.wav",
  71. "debris/bustcrate3.wav"
  72. };
  73. const OFFSET_CSMENUCODE = 205
  74.  
  75. new bool:g_bIsBarricadeDestroyed[ MAX_ENTITIES ];
  76.  
  77. new g_iForward[ CustomForwards ];
  78. new g_iForwardReturn;
  79. new g_iBarricadeCached[ MAX_PLAYERS + 1 ];
  80. new g_iBarricadeSet[ MAX_PLAYERS + 1 ];
  81. new g_iBarricadeLimit[ MAX_PLAYERS + 1 ];
  82. new g_iAmmoPacks[ MAX_PLAYERS + 1 ], g_iItemID
  83.  
  84. // Cvar binds (Floats)
  85. new Float:g_fBarricadeHealth;
  86.  
  87. // Cvar binds (Intgers)
  88. new g_iBarricadeSetDistanceMax;
  89. new g_iBarricadeSetDistanceMin;
  90. new g_iBarricadeSetTime;
  91. new g_iBarricadeDeleteDistance;
  92. new g_iBarricadeDeleteTime;
  93. new g_iBarricadeRewardDestroy;
  94.  
  95. new g_msgBarTime;
  96.  
  97. public plugin_init( )
  98. {
  99. register_plugin( "[ZP] Barricade", "2.0.0", "Taurus" );
  100.  
  101. // Cvars (Floats)
  102. bind_pcvar_float( register_cvar( "zp_barricade_health", "600.0" ), g_fBarricadeHealth );
  103.  
  104. // Cvars (Integers)
  105. bind_pcvar_num( register_cvar( "zp_barricade_set_distance_max", "300" ), g_iBarricadeSetDistanceMax );
  106. bind_pcvar_num( register_cvar( "zp_barricade_set_distance_min", "50" ), g_iBarricadeSetDistanceMin );
  107. bind_pcvar_num( register_cvar( "zp_barricade_set_time", "2" ), g_iBarricadeSetTime );
  108. bind_pcvar_num( register_cvar( "zp_barricade_delete_distance", "150" ), g_iBarricadeDeleteDistance );
  109. bind_pcvar_num( register_cvar( "zp_barricade_delete_time", "1" ), g_iBarricadeDeleteTime );
  110. bind_pcvar_num( register_cvar( "zp_barricade_reward_destroy", "6" ), g_iBarricadeRewardDestroy );
  111.  
  112. // Player messages
  113. g_msgBarTime = get_user_msgid( "BarTime" );
  114.  
  115. // Custom forwards
  116. g_iForward[ FW_BARRICADE_SPAWN ] = CreateMultiForward( "zp_fw_barricade_spawn", ET_IGNORE, FP_CELL, FP_CELL );
  117. g_iForward[ FW_BARRICADE_DELETE ] = CreateMultiForward( "zp_fw_barricade_delete", ET_IGNORE, FP_CELL, FP_CELL );
  118. g_iForward[ FW_BARRICADE_TAKE_DAMAGE ] = CreateMultiForward( "zp_fw_barricade_take_damage", ET_CONTINUE, FP_CELL, FP_CELL );
  119. g_iForward[ FW_BARRICADE_DESTROYED ] = CreateMultiForward( "zp_fw_barricade_destroyed", ET_IGNORE, FP_CELL, FP_CELL );
  120.  
  121. // Client commands
  122. register_clcmd( "+setbc", "ClCmd_StartSetBarricade" );
  123. register_clcmd( "-setbc", "ClCmd_ResetSetBarricade" );
  124. register_clcmd( "+delbc", "ClCmd_StartDelBarricade" );
  125. register_clcmd( "-delbc", "ClCmd_ResetDelBarricade" );
  126. register_clcmd( "say /ra_bc", "ClCmd_RemoveBarricade" );
  127. register_clcmd( "say ra_bc", "ClCmd_RemoveBarricade" );
  128.  
  129. // Ham forwards
  130. RegisterHamPlayer( Ham_Killed, "fw_Killed" );
  131. RegisterHamPlayer( Ham_Killed, "fw_Killed_Post", true )
  132.  
  133. register_clcmd("say /sb","show_the_menu");
  134. register_clcmd("say_team /sb","show_the_menu")
  135.  
  136. g_iItemID = zp_items_register( ZP_ITEM_NAME, ZP_ITEM_DESC, ZP_ITEM_COST, ZP_ITEM_LIMIT_PLAYER, ZP_ITEM_LIMIT_ROUND );
  137. }
  138.  
  139. public plugin_precache( )
  140. {
  141. // Barricade model
  142. precache_model( g_szBarricadeModel );
  143.  
  144. // Precache sounds
  145. for( new iLoop = 0; iLoop < sizeof( g_szSoundCrateHit ); iLoop ++ )
  146. precache_sound( g_szSoundCrateHit[ iLoop ] );
  147.  
  148. // I don't know what exactly does this thing do, apparently it makes the server happy!
  149. new iEntity = CreateBarricade( 0 );
  150.  
  151. if( !pev_valid( iEntity ) )
  152. return;
  153.  
  154. set_pev( iEntity, pev_flags, pev( iEntity, pev_flags ) | FL_KILLME );
  155.  
  156. if( !amx_load_setting_int( g_szGameFile, ZP_ITEM_NAME, "BARRICADES PER PURCHASE", g_iBarricadesPerPurchase ) )
  157. amx_save_setting_int( g_szGameFile, ZP_ITEM_NAME, "BARRICADES PER PURCHASE", g_iBarricadesPerPurchase );
  158. }
  159.  
  160. public zp_fw_items_select_pre( id, item_id )
  161. {
  162. if( item_id != g_iItemID )
  163. return ZP_ITEM_AVAILABLE
  164.  
  165. if(zp_core_is_zombie(id))
  166. return ZP_ITEM_DONT_SHOW
  167.  
  168. return ZP_ITEM_AVAILABLE
  169. }
  170.  
  171. public zp_fw_items_select_post( id, item_id )
  172. {
  173. if( item_id != g_iItemID )
  174. return
  175.  
  176. g_iBarricadeLimit[id] += g_iBarricadesPerPurchase
  177. zp_colored_print(id, "!tType !g/sb !tto bring up the !gsandbag menu.")
  178. show_the_menu(id)
  179. }
  180.  
  181. public show_the_menu(id)
  182. {
  183. new menuid = menu_create("\ySandbags:", "menu_command")
  184. menu_additem(menuid, "Place a sandbag")
  185. menu_additem(menuid, "Remove a sandbag")
  186.  
  187. if (!zp_core_is_zombie(id) && is_user_alive(id))
  188. {
  189. set_pdata_int(id, OFFSET_CSMENUCODE, 0)
  190. menu_display(id, menuid)
  191. }
  192. }
  193.  
  194. public menu_command(id, menuid, item)
  195. {
  196. // Menu was closed
  197. if (item == MENU_EXIT)
  198. {
  199. menu_destroy(menuid)
  200. return PLUGIN_HANDLED
  201. }
  202.  
  203. // Dead players are not allowed to buy items
  204. if (zp_core_is_zombie(id) || !is_user_alive(id))
  205. {
  206. menu_destroy(menuid)
  207. return PLUGIN_HANDLED
  208. }
  209.  
  210. switch(item)
  211. {
  212. case 0: ClCmd_StartSetBarricade(id)
  213. case 1: ClCmd_StartDelBarricade(id)
  214. }
  215. menu_destroy(menuid)
  216. return PLUGIN_HANDLED
  217. }
  218.  
  219. public plugin_natives( )
  220. {
  221. register_library("zp_barricade")
  222. register_native("open_sb_menu", "_open_sb_menu", 1)
  223. register_native("zp_barricade_get", "native_barricade_get", 1)
  224. register_native("zp_barricade_set", "native_barricade_set", 1)
  225. }
  226.  
  227. public native_barricade_get(id)
  228. {
  229. if( !is_user_connected( id ) )
  230. {
  231. log_error( AMX_ERR_NATIVE, "[ZP] Player is not in-game (%d)", id );
  232. return -1
  233. }
  234.  
  235. return g_iBarricadeLimit[ id ]
  236. }
  237.  
  238. public native_barricade_set( id, amount )
  239. {
  240. if( !is_user_connected( id ) )
  241. {
  242. log_error( AMX_ERR_NATIVE, "[ZP] Player is not in-game (%d)", id );
  243. return -1
  244. }
  245.  
  246. g_iBarricadeLimit[ id ] += amount
  247. return true
  248. }
  249.  
  250. public _open_sb_menu(id)
  251. {
  252. if(!is_user_connected(id))
  253. {
  254. log_error( AMX_ERR_NATIVE, "[ZP] Player is not in-game (%d)", id )
  255. return false
  256. }
  257. show_the_menu(id)
  258. return true
  259. }
  260.  
  261. public client_disconnected( id )
  262. {
  263. // Remove spawn task
  264. if( task_exists( id + TASK_BARRICADE_SPAWN ) )
  265. remove_task( id + TASK_BARRICADE_SPAWN );
  266.  
  267. // Remove delete task
  268. if( task_exists( id + TASK_BARRICADE_DELETE ) )
  269. remove_task( id + TASK_BARRICADE_DELETE );
  270.  
  271. // Remove info task
  272. if( task_exists( id + TASK_BARRICADE_INFO ) )
  273. remove_task( id + TASK_BARRICADE_INFO );
  274.  
  275. // Remove barricade put by player
  276. RemoveBarricadesByOwner( id, true );
  277. }
  278.  
  279. public client_PreThink( id )
  280. {
  281. // Player is not alive
  282. if (!is_user_alive(id))
  283. return;
  284.  
  285. // Delete barricade task in progress?
  286. if( task_exists( id + TASK_BARRICADE_DELETE ) )
  287. {
  288. // Get aim entity
  289. new iEntity, iPart;
  290. get_user_aiming( id, iEntity, iPart );
  291.  
  292. // Is that entity a valid one?
  293. if( !pev_valid( iEntity ) && task_exists( id + TASK_BARRICADE_DELETE ) )
  294. {
  295. remove_task( id + TASK_BARRICADE_DELETE );
  296.  
  297. SendBarTime( id );
  298. return;
  299. }
  300. }
  301. // Spawning barricade
  302. else if( task_exists( id + TASK_BARRICADE_SPAWN ) )
  303. UpdateEntityPosition( id );
  304. }
  305.  
  306. public zp_fw_core_spawn_post( id )
  307. {
  308. // Player is not longer connected
  309. if( !is_user_connected( id ) )
  310. return
  311.  
  312. // Show barricade info (Have to check task's existence so we do not call multiple tasks pointlessly)
  313. if( !task_exists( id + TASK_BARRICADE_INFO ) )
  314. set_task( 0.1, "_tBarricadeInfo", id + TASK_BARRICADE_INFO, _, _, "b" );
  315. }
  316.  
  317. public zp_fw_core_infect_post( id, attacker_id )
  318. {
  319. // Remove spawn task
  320. if( task_exists( id + TASK_BARRICADE_SPAWN ) )
  321. {
  322. remove_task( id + TASK_BARRICADE_SPAWN );
  323.  
  324. // Remove bartime message
  325. SendBarTime( id );
  326. }
  327.  
  328. // Remove delete task
  329. if( task_exists( id + TASK_BARRICADE_DELETE ) )
  330. {
  331. remove_task( id + TASK_BARRICADE_DELETE );
  332.  
  333. // Remove bartime message
  334. SendBarTime( id );
  335. }
  336.  
  337. // Reward player for having victim's barricades removed
  338. if( id != attacker_id && is_user_alive( attacker_id ) )
  339. {
  340. // Get barricade count
  341. new iCount = GetCountBarricadesByOwner( id );
  342.  
  343. if( !iCount )
  344. return;
  345.  
  346. // Reward player for how many barricades have been removed
  347. new ammopacks_reward = iCount * g_iBarricadeRewardDestroy;
  348. zp_ammopacks_set( attacker_id, g_iAmmoPacks[ attacker_id ] + ammopacks_reward );
  349.  
  350. // Notify players about barricade removal reward
  351. static szName[ 2 ][ 32 ];
  352. get_user_name( attacker_id, szName[ 0 ], charsmax( szName[ ] ) );
  353. get_user_name( id, szName[ 1 ], charsmax( szName[ ] ) );
  354.  
  355. zp_colored_print( 0, "%L", LANG_SERVER, "MSG_BARRICADE_DESTROYED_ALL", szName[ 0 ], szName[ 1 ], ammopacks_reward );
  356. }
  357.  
  358. // Remove barricade when a player to be infected
  359. RemoveBarricadesByOwner( id, true );
  360. }
  361.  
  362. public zp_fw_gamemodes_end( )
  363. {
  364. // When the round ends, remove all barricades!
  365. RemoveBarricades( );
  366. }
  367.  
  368. public zp_fw_ammopacks_update( id, iAmount )
  369. {
  370. // Player is not longer connected
  371. if( !is_user_connected( id ) )
  372. return;
  373.  
  374. // Update player's ammo packs (Less natives used)
  375. g_iAmmoPacks[ id ] = iAmount;
  376. }
  377.  
  378. public ClCmd_StartSetBarricade( id )
  379. {
  380. // Player is not alive?
  381. if (!is_user_alive(id) || zp_core_is_zombie(id))
  382. return PLUGIN_HANDLED;
  383.  
  384. // Limit has been exceeded?
  385. if( g_iBarricadeSet[ id ] >= g_iBarricadeLimit[ id ] )
  386. return PLUGIN_HANDLED;
  387.  
  388. // Let's try creating our entity
  389. new iEntity = CreateBarricade( id );
  390.  
  391. // Invalid entity?
  392. if( !pev_valid( iEntity ) )
  393. return PLUGIN_HANDLED;
  394.  
  395. // Check distance between entity and owner, and glow it!
  396. if( CheckEntityDistance( iEntity, id ) > g_iBarricadeSetDistanceMin )
  397. set_pev( iEntity, pev_rendercolor, Float:{ 0.0, 255.0, 0.0 } );
  398. else
  399. set_pev( iEntity, pev_rendercolor, Float:{ 255.0, 0.0, 0.0 } );
  400.  
  401. // Send bartime message in order to show how much left to finish placing barricades!
  402. SendBarTime( id, g_iBarricadeSetTime );
  403.  
  404. // Set task to placing a barricades
  405. set_task( float( g_iBarricadeSetTime ), "_tBarricadeSpawn", id + TASK_BARRICADE_SPAWN );
  406. return PLUGIN_HANDLED;
  407. }
  408.  
  409. public ClCmd_ResetSetBarricade( id )
  410. {
  411. // Player is not alive?
  412. if (!is_user_alive(id) || zp_core_is_zombie(id))
  413. return PLUGIN_HANDLED;
  414.  
  415. // Spawn task does not exist?
  416. if( !task_exists( id + TASK_BARRICADE_SPAWN ) )
  417. return PLUGIN_HANDLED;
  418.  
  419. // Get cached entity
  420. new iEntity = g_iBarricadeCached[ id ];
  421.  
  422. // Valid entity? Remove it!
  423. if( pev_valid( iEntity ) )
  424. engfunc( EngFunc_RemoveEntity, iEntity );
  425.  
  426. // Remove bartime message, we do not need it anymore!
  427. SendBarTime( id );
  428.  
  429. // Remove barricade spawn task
  430. remove_task( id + TASK_BARRICADE_SPAWN );
  431.  
  432. return PLUGIN_HANDLED;
  433. }
  434.  
  435. public ClCmd_StartDelBarricade( id )
  436. {
  437. // Player is not alive?
  438. if (!is_user_alive(id) || zp_core_is_zombie(id))
  439. return PLUGIN_HANDLED;
  440.  
  441. // Spwan task exists?
  442. if( task_exists( id + TASK_BARRICADE_SPAWN ) )
  443. return PLUGIN_HANDLED;
  444.  
  445. // Get aim entity
  446. new iEntity, iPart;
  447. get_user_aiming( id, iEntity, iPart );
  448.  
  449. // Are we aiming at a valid barricade entity?
  450. if( !CheckEntityByName( iEntity, g_szEntityBarricade ) )
  451. return PLUGIN_HANDLED;
  452.  
  453. // Not owner?
  454. if( pev( iEntity, pev_iuser1 ) != id )
  455. {
  456. zp_colored_print( id, "!t%L", id, "MSG_BARRICADE_NOT_OWNER" );
  457. return PLUGIN_HANDLED;
  458. }
  459.  
  460. // Not close enough?
  461. if( CheckEntityDistance( iEntity, id ) > g_iBarricadeDeleteDistance )
  462. return PLUGIN_HANDLED;
  463.  
  464. // Get entity health
  465. new Float:fHealth;
  466. pev( iEntity, pev_health, fHealth );
  467.  
  468. // Damaged entity?
  469. if( fHealth < g_fBarricadeHealth )
  470. {
  471. zp_colored_print( id, "!t%L", id, "MSG_BARRICADE_DAMAGED" );
  472. return PLUGIN_HANDLED;
  473. }
  474.  
  475. // Start progress
  476. SendBarTime( id, g_iBarricadeDeleteTime );
  477.  
  478. // Remove barricade after that defined time
  479. set_task( float( g_iBarricadeDeleteTime ), "_tBarricadeDelete", id + TASK_BARRICADE_DELETE );
  480. return PLUGIN_HANDLED;
  481. }
  482.  
  483. public ClCmd_ResetDelBarricade( id )
  484. {
  485. // Player is not alive?
  486. if (!is_user_alive(id) || zp_core_is_zombie(id))
  487. return PLUGIN_HANDLED;
  488.  
  489. // Spawn task does not exist?
  490. if( !task_exists( id + TASK_BARRICADE_DELETE ) )
  491. return PLUGIN_HANDLED;
  492.  
  493. // Reset progress
  494. SendBarTime( id );
  495.  
  496. // Terminate barricade deletion task
  497. remove_task( id + TASK_BARRICADE_DELETE );
  498. return PLUGIN_HANDLED;
  499. }
  500.  
  501. public ClCmd_RemoveBarricade( id )
  502. {
  503. // Player is not alive?
  504. if (!is_user_alive(id) || zp_core_is_zombie(id))
  505. return PLUGIN_HANDLED;
  506.  
  507. // Remove barricades by owner
  508. RemoveBarricadesByOwner( id );
  509. return PLUGIN_HANDLED;
  510. }
  511.  
  512. public fw_Killed( victim_id, attacker_id )
  513. {
  514. // Player is no longer connected
  515. if( !is_user_connected( victim_id ) || !is_user_connected(attacker_id))
  516. return;
  517.  
  518. // Remove task
  519. if( task_exists( victim_id + TASK_BARRICADE_INFO ) )
  520. remove_task( victim_id + TASK_BARRICADE_INFO )
  521.  
  522. // Reward player for having victim's barricades removed
  523. if( victim_id != attacker_id && is_user_alive( attacker_id ) )
  524. {
  525. // Get barricade count
  526. new iCount = GetCountBarricadesByOwner( victim_id );
  527.  
  528. if( !iCount )
  529. return;
  530.  
  531. // Reward player for how many barricades have been removed
  532. new ammopacks_reward = iCount * g_iBarricadeRewardDestroy;
  533. zp_ammopacks_set( attacker_id, g_iAmmoPacks[ attacker_id ] + ammopacks_reward );
  534.  
  535. // Notify players about barricade removal reward
  536. static szName[ 2 ][ 32 ];
  537. get_user_name( attacker_id, szName[ 0 ], charsmax( szName[ ] ) );
  538. get_user_name( victim_id, szName[ 1 ], charsmax( szName[ ] ) );
  539.  
  540. zp_colored_print( 0, "!t%L", LANG_SERVER, "MSG_BARRICADE_DESTROYED_ALL", szName[ 0 ], szName[ 1 ], ammopacks_reward );
  541. }
  542. }
  543.  
  544. public fw_Killed_Post( victim_id, attacker_id )
  545. {
  546. // Remove spawn task
  547. if( task_exists( victim_id + TASK_BARRICADE_SPAWN ) )
  548. {
  549. remove_task( victim_id + TASK_BARRICADE_SPAWN );
  550.  
  551. // Remove progress (Bar message)
  552. SendBarTime( victim_id );
  553. }
  554.  
  555. // Remove delete task
  556. if( task_exists( victim_id + TASK_BARRICADE_DELETE ) )
  557. {
  558. remove_task( victim_id + TASK_BARRICADE_DELETE );
  559.  
  560. // Remove progress (Bar message)
  561. SendBarTime( victim_id );
  562. }
  563.  
  564. // Remove barricades put by player
  565. RemoveBarricadesByOwner( victim_id, true );
  566. }
  567.  
  568. public Ham_BarricadeTakeDamage_Pre( victim_id, inflictor_id, attacker_id, Float:fDamage, iDamageBits )
  569. {
  570. // Is the victim a valid barricade?
  571. if( !CheckEntityByName( victim_id, g_szEntityBarricade ) )
  572. return HAM_IGNORED;
  573.  
  574. // Check who's attacking it?
  575. if( pev( victim_id, pev_iuser1 ) == attacker_id || !zp_core_is_zombie(attacker_id))
  576. return HAM_SUPERCEDE;
  577.  
  578. // Maybe other plugins want to prevent barricade from taking damage! (victim, attacker)
  579. ExecuteForward( g_iForward[ FW_BARRICADE_TAKE_DAMAGE ], g_iForwardReturn, victim_id, attacker_id );
  580.  
  581. if( g_iForwardReturn >= PLUGIN_HANDLED )
  582. return HAM_SUPERCEDE;
  583.  
  584. return HAM_IGNORED;
  585. }
  586.  
  587. public Ham_BarricadeTakeDamage_Post( victim_id, inflictor_id, attacker_id, Float:fDamage, iDamageBits )
  588. {
  589. // Is the victim a valid barricade?
  590. if( !CheckEntityByName( victim_id, g_szEntityBarricade ) )
  591. return HAM_IGNORED;
  592.  
  593. // Get barricade health
  594. new Float:fHealth;
  595. pev( victim_id, pev_health, fHealth );
  596.  
  597. // barricade's health is now 0, means it is destroyed!
  598. if( fHealth <= 0.0 && !g_bIsBarricadeDestroyed[ victim_id ] )
  599. {
  600. // Now it is destroyed
  601. g_bIsBarricadeDestroyed[ victim_id ] = true;
  602.  
  603. // Boom! Our barricade has been destroyed! :/
  604. ExecuteForward( g_iForward[ FW_BARRICADE_DESTROYED ], g_iForwardReturn, victim_id, attacker_id );
  605.  
  606. // Reward player for destroying a barricade
  607. zp_ammopacks_set( attacker_id, g_iAmmoPacks[ attacker_id ] + g_iBarricadeRewardDestroy );
  608.  
  609. // Notify all players that barricade has been destroyed
  610. static szName[ 32 ];
  611. get_user_name( attacker_id, szName, charsmax( szName ) );
  612.  
  613. zp_colored_print( 0, "!t%L", LANG_SERVER, "MSG_BARRICADE_DESTROYED", szName, g_iBarricadeRewardDestroy );
  614. return HAM_IGNORED;
  615. }
  616.  
  617. new Float:fColour[ 3 ];
  618. ComputeColours( fHealth * 100.0 / g_fBarricadeHealth, fColour );
  619.  
  620. set_pev( victim_id, pev_rendercolor, fColour );
  621. return HAM_IGNORED;
  622. }
  623.  
  624. public _tBarricadeSpawn( task_id )
  625. {
  626. // Player is not alive?
  627. if( !is_user_alive( ID_BARRICADE_SPAWN ) )
  628. return;
  629.  
  630. // Get our entity :)
  631. new iEntity = g_iBarricadeCached[ ID_BARRICADE_SPAWN ];
  632.  
  633. // Is our entity a valid one?
  634. if( !pev_valid( iEntity ) )
  635. return;
  636.  
  637. // Play cannot place barricade?
  638. if( !pev( iEntity, pev_iuser2 ) )
  639. {
  640. engfunc( EngFunc_RemoveEntity, iEntity );
  641. SendBarTime( ID_BARRICADE_SPAWN );
  642.  
  643. zp_colored_print( ID_BARRICADE_SPAWN, "!t%L", ID_BARRICADE_SPAWN, "MSG_BARRICADE_NOT_SPAWN" );
  644. return;
  645. }
  646.  
  647. // Make our entity a solid one
  648. set_pev( iEntity, pev_solid, SOLID_BBOX );
  649.  
  650. // Make our entity take damage and set health for it
  651. set_pev( iEntity, pev_takedamage, 1.0 );
  652. set_pev( iEntity, pev_health, g_fBarricadeHealth );
  653.  
  654. // Make our entity glow a normal one
  655. set_pev( iEntity, pev_renderfx, kRenderFxGlowShell );
  656. set_pev( iEntity, pev_renderamt, 5.0 );
  657.  
  658. // Once it has spawned, let's register some stuff!
  659. RegisterHamFromEntity( Ham_TakeDamage, iEntity, "Ham_BarricadeTakeDamage_Pre", false );
  660. RegisterHamFromEntity( Ham_TakeDamage, iEntity, "Ham_BarricadeTakeDamage_Post", true );
  661.  
  662. // This entity was never destroyed before!
  663. g_iBarricadeSet[ ID_BARRICADE_SPAWN ] ++
  664. g_bIsBarricadeDestroyed[ iEntity ] = false;
  665.  
  666. // Notify all players that someone planted a barricade
  667. static szName[ 32 ];
  668. get_user_name( ID_BARRICADE_SPAWN, szName, charsmax( szName ) );
  669.  
  670. zp_colored_print( 0, "%L", LANG_SERVER, "MSG_BARRICADE_SPAWNED", szName );
  671.  
  672. // Now that the entity spawned, call a forward (entity, owner)
  673. ExecuteForward( g_iForward[ FW_BARRICADE_SPAWN ], g_iForwardReturn, iEntity, ID_BARRICADE_SPAWN );
  674.  
  675. if (g_iBarricadeLimit[ID_BARRICADE_SPAWN] > 0)
  676. show_the_menu(ID_BARRICADE_SPAWN)
  677. }
  678.  
  679. public _tBarricadeDelete( task_id )
  680. {
  681. // Player is not alive?
  682. if( !is_user_alive( ID_BARRICADE_DELETE ) )
  683. return;
  684.  
  685. // Get aim entity
  686. new iEntity, iPart;
  687. get_user_aiming( ID_BARRICADE_DELETE, iEntity, iPart );
  688.  
  689. // Is the victim a valid barricade?
  690. if( !CheckEntityByName( iEntity, g_szEntityBarricade ) )
  691. return;
  692.  
  693. // Not the owner of the barricade
  694. if( pev( iEntity, pev_iuser1 ) != ID_BARRICADE_DELETE )
  695. return;
  696.  
  697. // Remove barricade
  698. RemoveBarricadeByOwner( iEntity, ID_BARRICADE_DELETE );
  699.  
  700. // Now that the entity spawned, call a forward (entity, owner)
  701. ExecuteForward( g_iForward[ FW_BARRICADE_DELETE ], g_iForwardReturn, iEntity, ID_BARRICADE_DELETE );
  702.  
  703. if (g_iBarricadeLimit[ID_BARRICADE_DELETE] > 0)
  704. show_the_menu(ID_BARRICADE_DELETE)
  705. }
  706.  
  707. public _tBarricadeInfo( task_id )
  708. {
  709. new iPart, iEntity;
  710. get_user_aiming( ID_BARRICADE_INFO, iEntity, iPart, g_iBarricadeSetDistanceMax );
  711.  
  712. if( !CheckEntityByName( iEntity, g_szEntityBarricade ) )
  713. return;
  714.  
  715. new owner_id = pev( iEntity, pev_iuser1 );
  716.  
  717. if( !is_user_alive( owner_id ) )
  718. return;
  719.  
  720. static szName[ 32 ];
  721. get_user_name( owner_id, szName, charsmax( szName ) );
  722.  
  723. new Float:fHealth;
  724. pev( iEntity, pev_health, fHealth );
  725.  
  726. if( fHealth <= 0.0 )
  727. return;
  728.  
  729. new iHealth = floatround( fHealth );
  730.  
  731. static msgHudSync;
  732.  
  733. if( !msgHudSync )
  734. msgHudSync = CreateHudSyncObj( );
  735.  
  736. set_hudmessage( 0, 100, 200, -1.0, 0.55, 0, 0.0, 0.1, 0.1, 0.1, 3 );
  737. ShowSyncHudMsg( ID_BARRICADE_INFO, msgHudSync, "Owner: %s | Health: %d", szName, iHealth );
  738. }
  739.  
  740. CreateBarricade( id )
  741. {
  742. // Create a breakable entity
  743. static func_breakable_id;
  744.  
  745. if( !func_breakable_id )
  746. func_breakable_id = engfunc( EngFunc_AllocString, g_szEntityBreakable );
  747.  
  748. new iEntity = engfunc( EngFunc_CreateNamedEntity, func_breakable_id );
  749.  
  750. // Invalid entity created?
  751. if( !pev_valid( iEntity ) )
  752. return FM_NULLENT;
  753.  
  754. // Make it a woody material
  755. static szMaterial[ 3 ];
  756. num_to_str( matWood, szMaterial, charsmax( szMaterial ) );
  757.  
  758. DispatchKeyValue( iEntity, "material", szMaterial );
  759.  
  760. // Spawn entity!
  761. dllfunc( DLLFunc_Spawn, iEntity );
  762.  
  763. if( !id )
  764. return iEntity;
  765.  
  766. // Set entity information
  767. set_pev( iEntity, pev_classname, g_szEntityBarricade );
  768.  
  769. // Set entity owner
  770. set_pev( iEntity, pev_iuser1, id );
  771.  
  772. // Set entity nature
  773. set_pev( iEntity, pev_solid, SOLID_NOT );
  774. set_pev( iEntity, pev_movetype, MOVETYPE_FLY );
  775.  
  776. // Entity cannot take any damage while being created!
  777. set_pev( iEntity, pev_takedamage, 0.0 );
  778.  
  779. // Entity glow
  780. set_pev( iEntity, pev_renderfx, kRenderFxGlowShell );
  781. set_pev( iEntity, pev_renderamt, 5.0 );
  782.  
  783. // Set entity model and size
  784. engfunc( EngFunc_SetModel, iEntity, g_szBarricadeModel );
  785. engfunc( EngFunc_SetSize, iEntity, Float:{ -27.260000, -22.280001, -22.290001 }, Float:{ 27.340000, 26.629999, 29.020000 } );
  786.  
  787. // Check entity position again!
  788. CheckEntityPosition( iEntity, id );
  789.  
  790. // Set player's cached entity
  791. g_iBarricadeCached[ id ] = iEntity;
  792.  
  793. // Return entity id?
  794. return iEntity;
  795. }
  796.  
  797. UpdateEntityPosition( id )
  798. {
  799. // Player is not alive?
  800. if( !is_user_alive( id ) )
  801. return;
  802.  
  803. // Get our entity :)
  804. new iEntity = g_iBarricadeCached[ id ];
  805.  
  806. // Is it a valid one?
  807. if( !pev_valid( iEntity ) )
  808. return;
  809.  
  810. // Spawn task exists?
  811. if( task_exists( id + TASK_BARRICADE_SPAWN ) )
  812. {
  813. if( CheckEntityPosition( iEntity, id ) )
  814. {
  815. set_pev( iEntity, pev_rendercolor, Float:{ 0.0, 255.0, 0.0 } );
  816. set_pev( iEntity, pev_iuser2, 1 );
  817. }
  818. else
  819. {
  820. set_pev( iEntity, pev_rendercolor, Float:{ 255.0, 0.0, 0.0 } );
  821. set_pev( iEntity, pev_iuser2, 0 );
  822. }
  823. }
  824. }
  825.  
  826. CheckEntityPosition( iEntity, id )
  827. {
  828. // Is entity valid?
  829. if( !pev_valid( iEntity ) )
  830. return false;
  831.  
  832. // Trace direction
  833. new Float:fOrigin[ 3 ];
  834. GetAimOrigin( id, fOrigin );
  835.  
  836. // Check fraction
  837. new Float:fFraction;
  838. get_tr2( 0, TR_flFraction, fFraction );
  839.  
  840. // Normal vector
  841. new Float:fNormal[ 3 ];
  842.  
  843. // We hit something
  844. if( fFraction < 1.0 )
  845. {
  846. get_tr2( 0, TR_vecEndPos, fOrigin );
  847. get_tr2( 0, TR_vecPlaneNormal, fNormal );
  848. }
  849.  
  850. // Update normal vector and new origin
  851. xs_vec_mul_scalar( fNormal, 8.0, fNormal );
  852. xs_vec_add( fOrigin, fNormal, fOrigin );
  853.  
  854. fOrigin[ 2 ] += 16.0;
  855.  
  856. // Set entity's origin
  857. engfunc( EngFunc_SetOrigin, iEntity, fOrigin );
  858.  
  859. // Check for collides
  860. if( CheckEntityCollides( fOrigin, 17.0 ) )
  861. return false;
  862.  
  863. // Follow terrain
  864. EntityFollowTerrain( iEntity, fOrigin, 0 );
  865.  
  866. // Check placement points
  867. new iPointContents = engfunc( EngFunc_PointContents, fOrigin );
  868.  
  869. if( iPointContents != CONTENTS_EMPTY )
  870. return false;
  871.  
  872. // Check if it is hitting an entity we don't want glitch
  873. new iHit = get_tr2( 0, TR_pHit );
  874.  
  875. if( pev_valid( iHit ) && !CheckEntityHitAllowed( iHit ) )
  876. return false;
  877.  
  878. // Entity is too close?
  879. if( CheckEntityDistance( iEntity, id ) <= g_iBarricadeSetDistanceMin )
  880. return false;
  881.  
  882. // Entity is too far?
  883. if( CheckEntityDistance( iEntity, id ) > g_iBarricadeSetDistanceMax )
  884. return false;
  885.  
  886. return true;
  887. }
  888.  
  889. CheckEntityDistance( iEntity, id )
  890. {
  891. // Get entity and player origin
  892. new Float:fOrigin[ 2 ][ 3 ];
  893. pev( iEntity, pev_origin, fOrigin[ 0 ] );
  894. pev( id, pev_origin, fOrigin[ 1 ] );
  895.  
  896. // Return distance as an integer
  897. return floatround( get_distance_f( fOrigin[ 0 ], fOrigin[ 1 ] ) );
  898. }
  899.  
  900. CheckEntityByName( iEntity, const szClassName[ ] )
  901. {
  902. // Is it a valid entity?
  903. if( !pev_valid( iEntity ) )
  904. return false;
  905.  
  906. // Check entity name
  907. static szNameCheck[ 32 ];
  908. pev( iEntity, pev_classname, szNameCheck, charsmax( szNameCheck ) );
  909.  
  910. // Class name maches?
  911. if( equal( szClassName, szNameCheck ) )
  912. return true;
  913.  
  914. return false;
  915. }
  916.  
  917. // Sends bar message, iTime = 0 means cancel bar message
  918. SendBarTime( id, iTime = 0 )
  919. {
  920. // Send BarTime message to a player
  921. message_begin( MSG_ONE, g_msgBarTime, _, id );
  922. write_byte( iTime );
  923. write_byte( 0 );
  924. message_end( );
  925. }
  926.  
  927. // Removes a barricade by a specified owner
  928. RemoveBarricadeByOwner( iEntity, id )
  929. {
  930. // Remove entity
  931. engfunc( EngFunc_RemoveEntity, iEntity );
  932.  
  933. // Decrease deployed count
  934. g_iBarricadeSet[ id ] --;
  935. }
  936.  
  937. // Removes ALL barricades by a specified owner
  938. RemoveBarricadesByOwner( id, bool:bIgnoreHealth = false )
  939. {
  940. // Get our start index
  941. new iEntity = FM_NULLENT, iCount = 0;
  942.  
  943. if( bIgnoreHealth )
  944. {
  945. // Loop through all entities, find our barricade with the respective owner! If found, remove it!
  946. while( ( iEntity = engfunc( EngFunc_FindEntityByString, iEntity, "classname", g_szEntityBarricade ) ) != 0 )
  947. {
  948. if( pev( iEntity, pev_iuser1 ) == id )
  949. engfunc( EngFunc_RemoveEntity, iEntity );
  950. }
  951.  
  952. // Reset player data
  953. g_iBarricadeCached[ id ] = FM_NULLENT;
  954. g_iBarricadeSet[ id ] = 0;
  955. g_iBarricadeLimit[ id ] = 0;
  956. }
  957. else
  958. {
  959. // Loop through all entities, find our barricade with the respective owner! If found, remove it!
  960. while( ( iEntity = engfunc( EngFunc_FindEntityByString, iEntity, "classname", g_szEntityBarricade ) ) != 0 )
  961. {
  962. // Get entity health
  963. new Float:fHealth;
  964. pev( iEntity, pev_health, fHealth );
  965.  
  966. if( pev( iEntity, pev_iuser1 ) == id && !g_bIsBarricadeDestroyed[ iEntity ] && fHealth >= g_fBarricadeHealth )
  967. {
  968. // Remove entity
  969. engfunc( EngFunc_RemoveEntity, iEntity );
  970.  
  971. // How many barricades have been removed
  972. iCount ++;
  973. }
  974. }
  975.  
  976. // Reset player data
  977. g_iBarricadeCached[ id ] = FM_NULLENT;
  978. g_iBarricadeSet[ id ] -= iCount;
  979. }
  980. }
  981.  
  982. // Removes ALL barricades from the map
  983. RemoveBarricades( )
  984. {
  985. // Get our start index
  986. new iEntity = FM_NULLENT;
  987.  
  988. // Loop through all entities, find our barricade and if found, remove it!
  989. while( ( iEntity = engfunc( EngFunc_FindEntityByString, iEntity, "classname", g_szEntityBarricade ) ) != 0 )
  990. engfunc( EngFunc_RemoveEntity, iEntity );
  991.  
  992. // Loop through all players and reset their data
  993. for( new id = 1; id <= MaxClients; id ++ )
  994. {
  995. // Player is not connected? Ignore!
  996. if(!is_user_connected(id))
  997. continue
  998.  
  999. g_iBarricadeCached[ id ] = FM_NULLENT;
  1000. g_iBarricadeSet[ id ] = 0;
  1001. g_iBarricadeLimit[ id ] = 0;
  1002.  
  1003. // Remove spawn task
  1004. if( task_exists( id + TASK_BARRICADE_SPAWN ) )
  1005. remove_task( id + TASK_BARRICADE_SPAWN );
  1006.  
  1007. // Remove delete task
  1008. if( task_exists( id + TASK_BARRICADE_DELETE ) )
  1009. remove_task( id + TASK_BARRICADE_DELETE );
  1010.  
  1011. // If there is a progress bar, remove it!
  1012. SendBarTime( id );
  1013. }
  1014. }
  1015.  
  1016. // Returns the count of barricades owned by the specified owner
  1017. GetCountBarricadesByOwner( id )
  1018. {
  1019. // Get our start index
  1020. new iEntity = FM_NULLENT, iCount = 0;
  1021.  
  1022. // Loop through all entities, find our barricade with the respective owner! If found, remove it!
  1023. while( ( iEntity = engfunc( EngFunc_FindEntityByString, iEntity, "classname", g_szEntityBarricade ) ) != 0 )
  1024. {
  1025. if( pev( iEntity, pev_iuser1 ) == id && !g_bIsBarricadeDestroyed[ iEntity ] )
  1026. iCount ++;
  1027. }
  1028.  
  1029. // Return the count
  1030. return iCount;
  1031. }
  1032.  
  1033. // Calculate colours according to a specified percentage
  1034. ComputeColours( Float:fPercent, Float:fColour[ 3 ] )
  1035. {
  1036. // Percent is not valid anymore
  1037. if( fPercent < 0.0 )
  1038. return;
  1039.  
  1040. // Calculate colours according to the percent :P
  1041. fColour[ 1 ] = 255.0 * fPercent / 100.0;
  1042. fColour[ 0 ] = 255.0 - fColour[ 1 ];
  1043. fColour[ 2 ] = 0.0;
  1044. }
  1045.  
  1046. CheckEntityCollides( Float:fOrigin[ 3 ], Float:fBounds )
  1047. {
  1048. new Float:fTraceEnd[ 8 ][ 3 ];
  1049.  
  1050. // Calculate X, Y and Z
  1051. fTraceEnd[ 0 ][ 0 ] = fOrigin[ 0 ] - fBounds;
  1052. fTraceEnd[ 0 ][ 1 ] = fOrigin[ 1 ] - fBounds;
  1053. fTraceEnd[ 0 ][ 2 ] = fOrigin[ 2 ] - fBounds;
  1054.  
  1055. fTraceEnd[ 1 ][ 0 ] = fOrigin[ 0 ] - fBounds;
  1056. fTraceEnd[ 1 ][ 1 ] = fOrigin[ 1 ] - fBounds;
  1057. fTraceEnd[ 1 ][ 2 ] = fOrigin[ 2 ] + fBounds;
  1058.  
  1059. fTraceEnd[ 2 ][ 0 ] = fOrigin[ 0 ] - fBounds;
  1060. fTraceEnd[ 2 ][ 1 ] = fOrigin[ 1 ] + fBounds;
  1061. fTraceEnd[ 2 ][ 2 ] = fOrigin[ 2 ] + fBounds;
  1062.  
  1063. fTraceEnd[ 3 ][ 0 ] = fOrigin[ 0 ] + fBounds;
  1064. fTraceEnd[ 3 ][ 1 ] = fOrigin[ 1 ] + fBounds;
  1065. fTraceEnd[ 3 ][ 2 ] = fOrigin[ 2 ] + fBounds;
  1066.  
  1067. fTraceEnd[ 4 ][ 0 ] = fOrigin[ 0 ] + fBounds;
  1068. fTraceEnd[ 4 ][ 1 ] = fOrigin[ 1 ] - fBounds;
  1069. fTraceEnd[ 4 ][ 2 ] = fOrigin[ 2 ] - fBounds;
  1070.  
  1071. fTraceEnd[ 5 ][ 0 ] = fOrigin[ 0 ] + fBounds;
  1072. fTraceEnd[ 5 ][ 1 ] = fOrigin[ 1 ] + fBounds;
  1073. fTraceEnd[ 5 ][ 2 ] = fOrigin[ 2 ] - fBounds;
  1074.  
  1075. fTraceEnd[ 6 ][ 0 ] = fOrigin[ 0 ] + fBounds;
  1076. fTraceEnd[ 6 ][ 1 ] = fOrigin[ 1 ] - fBounds;
  1077. fTraceEnd[ 6 ][ 2 ] = fOrigin[ 2 ] + fBounds;
  1078.  
  1079. fTraceEnd[ 7 ][ 0 ] = fOrigin[ 0 ] - fBounds;
  1080. fTraceEnd[ 7 ][ 1 ] = fOrigin[ 1 ] + fBounds;
  1081. fTraceEnd[ 7 ][ 2 ] = fOrigin[ 2 ] - fBounds;
  1082.  
  1083. // Get trace hits, and check point contents
  1084. new Float:fTraceHit[ 3 ], iLoop, iPointContents, iHit, iInnerLoop;
  1085.  
  1086. for( iLoop = 0; iLoop < sizeof( fTraceEnd ); iLoop ++ )
  1087. {
  1088. // Get point contents
  1089. iPointContents = engfunc( EngFunc_PointContents, fTraceEnd[ iLoop ] );
  1090.  
  1091. if( iPointContents != CONTENTS_EMPTY )
  1092. return true;
  1093.  
  1094. // Is it hitting something?
  1095. iHit = trace_line( 0, fOrigin, fTraceEnd[ iLoop ], fTraceHit );
  1096.  
  1097. if( iHit != 0 )
  1098. return true;
  1099.  
  1100. for( iInnerLoop = 0; iInnerLoop < sizeof( fTraceHit ); iInnerLoop ++ )
  1101. {
  1102. if( fTraceEnd[ iLoop ][ iInnerLoop ] != fTraceHit[ iInnerLoop ] )
  1103. return true;
  1104. }
  1105. }
  1106.  
  1107. // No collision!
  1108. return false;
  1109. }
  1110.  
  1111. CheckEntityHitAllowed( iEntity )
  1112. {
  1113. // Class names on which we cannot place our barricades!
  1114. new const szClassNameHitDenied[ ][ ] =
  1115. {
  1116. "func_door",
  1117. "func_door_rotating",
  1118. "func_plat",
  1119. "func_rotating",
  1120. "func_train",
  1121. "func_conveyor",
  1122. "hostage_entity",
  1123. "player"
  1124. };
  1125.  
  1126. // Get class name of the entity that has been hit
  1127. static szClassName[ 32 ];
  1128. pev( iEntity, pev_classname, szClassName, charsmax( szClassName ) );
  1129.  
  1130. // Check if it is hitting a denied class name
  1131. for( new iLoop = 0; iLoop < sizeof( szClassNameHitDenied ); iLoop ++ )
  1132. {
  1133. if( equali( szClassName, szClassNameHitDenied[ iLoop ] ) )
  1134. return false;
  1135. }
  1136.  
  1137. return true;
  1138. }
  1139.  
  1140. // Makes entity follow terrain
  1141. EntityFollowTerrain( iEntity, Float:fOrigin[ 3 ], iTraceResult )
  1142. {
  1143. // Trace
  1144. new Float:fTraceTo[ 3 ];
  1145. xs_vec_sub( fOrigin, Float:{ 0.0, 0.0, 10.0 }, fTraceTo );
  1146.  
  1147. // Get angles
  1148. new Float:fAngles[ 2 ][ 3 ];
  1149. pev( iEntity, pev_angles, fAngles[ 0 ] );
  1150.  
  1151. // Get forward vector
  1152. new Float:fForward[ 3 ];
  1153. angle_vector( fAngles[ 0 ], ANGLEVECTOR_FORWARD, fForward );
  1154.  
  1155. // Get up vector
  1156. new Float:fVectorUp[ 3 ];
  1157. get_tr2( iTraceResult, TR_vecPlaneNormal, fVectorUp );
  1158.  
  1159. // Calculate vectors
  1160. new Float:fVectorRight[ 3 ], Float:fVectorForward[ 3 ];
  1161.  
  1162. xs_vec_cross( fForward, fVectorUp, fVectorRight );
  1163. xs_vec_cross( fVectorUp, fVectorRight, fVectorForward );
  1164.  
  1165. vector_to_angle( fVectorForward, fAngles[ 0 ] );
  1166. vector_to_angle( fVectorRight, fAngles[ 1 ] );
  1167.  
  1168. // Update angles
  1169. fAngles[ 0 ][ 2 ] = -1.0 * fAngles[ 1 ][ 0 ];
  1170.  
  1171. // Set angles that we calculated
  1172. set_pev( iEntity, pev_angles, fAngles[ 0 ] );
  1173. }
  1174.  
  1175. GetAimOrigin( id, Float:fOriginAim[ 3 ], Float:fMaximumAimDistance = 8192.0 )
  1176. {
  1177. // Get player's origin and view ofs
  1178. static Float:fOrigin[ 3 ], Float:fViewOfs[ 3 ];
  1179. pev( id, pev_origin, fOrigin );
  1180. pev( id, pev_view_ofs, fViewOfs );
  1181.  
  1182. // Do some calculation stuff
  1183. xs_vec_add( fOrigin, fViewOfs, fOrigin );
  1184.  
  1185. // Get player's view angles
  1186. pev( id, pev_v_angle, fViewOfs );
  1187.  
  1188. // Make vectors
  1189. engfunc( EngFunc_MakeVectors, fViewOfs );
  1190.  
  1191. // Get forward vector
  1192. global_get( glb_v_forward, fViewOfs );
  1193.  
  1194. // Do some calculations
  1195. xs_vec_mul_scalar( fViewOfs, fMaximumAimDistance, fViewOfs );
  1196. xs_vec_add( fOrigin, fViewOfs, fViewOfs );
  1197.  
  1198. // Trace line?
  1199. engfunc( EngFunc_TraceLine, fOrigin, fViewOfs, DONT_IGNORE_MONSTERS, id, 0 );
  1200.  
  1201. // Get aim origin by trace line result
  1202. get_tr2( 0, TR_vecEndPos, fOriginAim );
  1203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement