HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. /*
  2. Copyright © 2009, NiHiLaNTh
  3.  
  4. Satchel Charge plugin is free software;
  5. you can redistribute it and/or modify it under the terms of the
  6. GNU General Public License as published by the Free Software Foundation.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with Satchel Charge plugin; if not, write to the
  15. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. Boston, MA 02111-1307, USA.
  17.  
  18. --- Intro ---
  19. Satchel Charges from HL, which replaces he grenade To plant a charge press
  20. secondary attack button.To detonate a charge press primary attack button.By
  21. default Satchel cost is 15 Ammo packs
  22.  
  23. --- CVARs ---
  24. zp_satchel_damage -- 100 // maxdamage
  25. zp_satchel_oneround -- 0 // If set to 1 all player will stripped from Satchel Charge; else ignored
  26. zp_satchel_radius -- 300 // damage radius
  27. zp_satchel_knockback --- 10 // knockback power
  28.  
  29. --- Changelog: ---
  30. v3.0 - First release
  31. v3.1 - Now satchel lays on the ground and fixed bug with radius
  32. v3.2 - Fixed bugs when satchel did not dissappear
  33. v3.3 - Full code rewrite and many major and minor chages, fixed a lot of issues'
  34. v3.4 - Coded this plugin in much better way
  35. - Fixed bunch of gameplayer bugs
  36.  
  37. --- Credits ---
  38. V3x - his Satchel Charge plugin
  39. NiHiLaNTh - Author
  40. Arkshine - Animation stock
  41. meTaLiCroSS - Weapon model reset stuff
  42.  
  43. If you find any bug - report it on plugin thread, which can be found here
  44. http://forums.alliedmods.net/showthread.php?t=96755
  45.  
  46. */
  47.  
  48. #include <amxmodx>
  49. #include <cstrike>
  50. #include <engine>
  51. #include <fakemeta>
  52. #include <fun>
  53. #include <hamsandwich>
  54. #include <zombieplague>
  55.  
  56. // Plugin stuff
  57. new const PLUGIN[] = "[ZP] Extra Item: Satchel Charge"
  58. new const VERSION[] = "3.4"
  59. new const AUTHOR[] = "NiHiLaNTh"
  60.  
  61. // Satchel and satchel radio models
  62. new const p_satchel[] = "models/mdL_cfg/p_satchel.mdl"
  63. new const v_satchel[] = "models/mdL_cfg/v_satchel.mdl"
  64. new const w_satchel[] = "models/mdL_cfg/w_satchel.mdl"
  65. new const w_satchelT[] = "models/mdL_cfg/w_satchelt.mdl"
  66. new const p_satchel_radio[] = "models/mdL_cfg/p_satchel_radio.mdl"
  67. new const v_satchel_radio[] = "models/mdL_cfg/v_satchel_radio.mdl"
  68.  
  69. // Sprite
  70. new const explode_sprite[] = "sprites/mdL_cfg/zerogxplode.spr"
  71. new const smoke_sprite[] = "sprites/mdL_cfg/steam1.spr"
  72.  
  73. // Item cost
  74. #define COST 15
  75.  
  76. // Cached sprite indexes
  77. new g_exploSpr, g_smokeSpr
  78.  
  79. // Message ID
  80. new g_msgScoreInfo
  81.  
  82. // CVAR Pointers
  83. new cvar_dmg, cvar_oneround, cvar_radius, cvar_knockback
  84.  
  85. // Item ID
  86. new g_satchel
  87.  
  88. // Player variables
  89. new g_hasRadio[33] // has detonator
  90. new g_hasSatchel[33] // has S.Charge
  91. new g_hasPlanted[33] // has planted the bomb
  92. new g_CanPlant[33] // I had to do it
  93. new g_CurrentWeapon[33] // Current weapon player is holding
  94.  
  95. // Game variables
  96. new g_maxplayers
  97. new g_restarted
  98.  
  99. // Animations
  100. // Satchel
  101. enum
  102. {
  103. satchel_idle1 = 0,
  104. satchel_fidget1,
  105. satchel_draw,
  106. satchel_drop
  107. }
  108.  
  109. // Satchel Radio
  110. enum
  111. {
  112. radio_idle1 = 0,
  113. radio_fidget1,
  114. radio_draw,
  115. radio_fire,
  116. radio_holster
  117. }
  118.  
  119. // Chat messages(Translate here)
  120. new const
  121. NOTICE_USE1[] = { "[ZP_mdL] Kaptal egy detonatort!" },
  122. NOTICE_USE2[] = { "[ZP_mdL] Aktivald a detonatort!" },
  123. NOTICE_YOUPLANT[] = { "[ZP_mdL] Mar raktal le egy detonatort!" },
  124. NOTICE_PLANT[] = { "[ZP_mdL] Leraktal a foldre egy detonatort!" },
  125. NOTICE_HAVE[] = { "[ZP_mdL] Mar van egy detonatorod!" },
  126. NOTICE_PLANT1[] = { "[ZP_mdL] Nem lehet eldobni a detonatort!" }
  127.  
  128. // Plugin precache
  129. public plugin_precache()
  130. {
  131. // Precache models...
  132. precache_model(p_satchel)
  133. precache_model(v_satchel)
  134. precache_model(w_satchel)
  135. precache_model(w_satchelT)
  136. precache_model(p_satchel_radio)
  137. precache_model(v_satchel_radio)
  138.  
  139. // and sprites
  140. g_exploSpr = precache_model(explode_sprite)
  141. g_smokeSpr = precache_model(smoke_sprite)
  142. }
  143.  
  144. // Plugin initialization
  145. public plugin_init()
  146. {
  147. // Register my new plugin
  148. register_plugin(PLUGIN, VERSION, AUTHOR)
  149. register_cvar("zp_satchel_version", VERSION, FCVAR_SERVER|FCVAR_SPONLY)
  150.  
  151. // Register new extra item
  152. g_satchel = zp_register_extra_item("Satchel Charge", COST, ZP_TEAM_HUMAN)
  153.  
  154. // Client command
  155. register_clcmd("drop", "clcmd_drop")
  156.  
  157. // Events
  158. register_event("CurWeapon", "Event_CurrentWeapon", "b", "1=1")
  159. register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");
  160. register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
  161.  
  162. // Log Event
  163. register_logevent("LogEvent_RoundEnd", 2, "1=Round_End")
  164.  
  165. // Forwards
  166. register_forward(FM_CmdStart, "fw_CmdStart")
  167. RegisterHam(Ham_Item_Deploy, "weapon_hegrenade", "fw_SatchelDeploy", 1)
  168. RegisterHam(Ham_Item_Deploy, "weapon_knife", "fw_RadioDeploy", 1)
  169. //register_forward(FM_Touch, "fw_Touch")
  170. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
  171.  
  172. // Register cvars
  173. cvar_dmg = register_cvar("zp_satchel_dmg", "1000")
  174. cvar_oneround = register_cvar("zp_satchel_oneround", "0")
  175. cvar_radius = register_cvar("zp_satchel_radius", "300")
  176. cvar_knockback = register_cvar("zp_satchel_knockback", "10")
  177.  
  178. // Messages
  179. g_msgScoreInfo = get_user_msgid("ScoreInfo")
  180.  
  181. // Touch
  182. register_touch("drop_satchel", "player", "satchel_touch")
  183.  
  184. // Store maxplayers in a global variable
  185. g_maxplayers = get_maxplayers()
  186. }
  187.  
  188. // Client connected
  189. public client_connect(id)
  190. {
  191. // Don't have satchel
  192. g_hasSatchel[id] = false
  193. g_hasRadio[id] = false
  194. g_hasPlanted[id] = false
  195. g_CanPlant[id] = false
  196. }
  197.  
  198. // Drop command
  199. public clcmd_drop(id)
  200. {
  201. // Has Satchel
  202. if (g_hasSatchel[id] && g_CurrentWeapon[id] == CSW_HEGRENADE)
  203. {
  204. // Drop it
  205. drop_satchel(id)
  206.  
  207. // Fix
  208. touch_fix(id)
  209.  
  210. // Force to loose HE grenade
  211. ham_strip_weapon(id, "weapon_hegrenade")
  212.  
  213. // Reset knife model
  214. reset_user_knife(id)
  215.  
  216. // Reset vars
  217. g_hasSatchel[id] = false
  218. g_hasPlanted[id] = false
  219. g_hasRadio[id] = false
  220. g_CanPlant[id] = false
  221. }
  222. // Player planted Satchel - can't drop
  223. if (g_hasPlanted[id] && g_CurrentWeapon[id] == CSW_KNIFE)
  224. {
  225. client_print(id, print_chat, "%s", NOTICE_PLANT1)
  226. return PLUGIN_HANDLED
  227. }
  228. return PLUGIN_CONTINUE
  229. }
  230.  
  231. // Buy some extra items
  232. public zp_extra_item_selected(id, itemid)
  233. {
  234. // Our extra item
  235. if (itemid == g_satchel)
  236. {
  237. // Already own Satchel
  238. if (g_hasSatchel[id] || g_hasPlanted[id])
  239. {
  240. // Warn
  241. client_print(id, print_center, "%s", NOTICE_HAVE)
  242. return ZP_PLUGIN_HANDLED
  243. }
  244. else
  245. {
  246. // Notices
  247. client_print(id, print_chat, "%s", NOTICE_USE1)
  248. client_print(id, print_chat, "%s", NOTICE_USE2)
  249.  
  250. // Reset vars
  251. g_hasSatchel[id] = true
  252. g_hasPlanted[id] = false
  253. g_hasRadio[id] = true
  254. g_CanPlant[id] = true
  255.  
  256. // Give him hegrenade
  257. give_item(id, "weapon_hegrenade")
  258.  
  259. // Force to he grenade
  260. engclient_cmd(id, "weapon_hegrenade")
  261.  
  262. // Change weapon models
  263. ChangeModelsSatchel(id)
  264.  
  265. // Play animation
  266. UTIL_PlayWeaponAnimation(id, satchel_draw)
  267. }
  268. }
  269. return PLUGIN_CONTINUE
  270. }
  271.  
  272. // Someone has been injected
  273. public zp_user_infected_post(id, infector)
  274. {
  275. // Have Satchel
  276. if (g_hasSatchel[id] || g_hasPlanted[id])
  277. {
  278. // Reset vars
  279. g_hasSatchel[id] = false
  280. g_hasRadio[id] = false
  281. g_hasPlanted[id] = false
  282. g_CanPlant[id] = false
  283.  
  284. // Drop it
  285. drop_satchel(id)
  286.  
  287. /************DONT TOUCH IT OR SERVER WILL CRASH ON RESTART***********/
  288. // Update Score
  289. //UpdateScore(infector, id, 0, 0, 1)
  290.  
  291. // Fix
  292. touch_fix(id)
  293.  
  294. // Reset knife model
  295. reset_user_knife(id)
  296.  
  297. // Remove planted satchel
  298. remove_planted_satchel()
  299. }
  300. }
  301.  
  302. // Current weapon
  303. public Event_CurrentWeapon(id)
  304. {
  305. // Dead
  306. if (!is_user_alive(id))
  307. return PLUGIN_CONTINUE
  308.  
  309. // Update array
  310. g_CurrentWeapon[id] = read_data(2)
  311.  
  312. return PLUGIN_CONTINUE
  313. }
  314.  
  315. // New round
  316. public Event_NewRound()
  317. {
  318. if (g_restarted)
  319. {
  320. // Make a loop
  321. for (new i = 1; i <= get_maxplayers(); i++)
  322. {
  323. // Strip from Satchel
  324. if (g_hasSatchel[i] || g_hasPlanted[i])
  325. {
  326. // Reset vars
  327. g_hasSatchel[i] = false
  328. g_hasRadio[i] = false
  329. g_CanPlant[i] = false
  330. g_hasPlanted[i] = false
  331. }
  332. }
  333. g_restarted = false
  334. }
  335. }
  336.  
  337. // Restart event
  338. public Event_GameRestart()
  339. {
  340. g_restarted = true
  341. }
  342.  
  343. public LogEvent_RoundEnd()
  344. {
  345. // One round only cvar enabled
  346. if (get_pcvar_num(cvar_oneround) == 1)
  347. {
  348. // Loop
  349. for (new i = 1; i < g_maxplayers; i++)
  350. {
  351. // Reset vars
  352. g_hasSatchel[i] = false
  353. g_hasPlanted[i] = false
  354. g_hasRadio[i] = false
  355. g_CanPlant[i] = false
  356. }
  357. }
  358.  
  359. // Remove dropped satchels
  360. remove_dropped_satchel()
  361.  
  362. // Remove planted satchel
  363. remove_planted_satchel()
  364. }
  365.  
  366. // Command start
  367. public fw_CmdStart(id, uc_handle, seed)
  368. {
  369. // Dead/Zombie/Nemesis
  370. if (!is_user_alive(id) || zp_get_user_zombie(id) || zp_get_user_nemesis(id))
  371. return FMRES_IGNORED
  372.  
  373. // Get weapon and player buttons
  374. new weapon = get_user_weapon(id)
  375. new buttons = get_uc(uc_handle, UC_Buttons)
  376.  
  377. // HE grenade(Satchel)
  378. if (weapon == CSW_HEGRENADE)
  379. {
  380. // Secondary attack
  381. if (buttons & IN_ATTACK2)
  382. {
  383. // Already planted
  384. if (g_hasPlanted[id])
  385. {
  386. // Wanr
  387. client_print(id, print_center, "%s", NOTICE_YOUPLANT)
  388. return FMRES_IGNORED
  389. }
  390. // Can plant
  391. else if (g_hasSatchel[id])
  392. {
  393. // Plant satchel
  394. plant_satchel(id)
  395. }
  396. }
  397. }
  398. // Knife(Radio)
  399. else if (weapon == CSW_KNIFE)
  400. {
  401. // Primary attck
  402. if (buttons & IN_ATTACK)
  403. {
  404. // Have planted or have radio
  405. if (g_hasPlanted[id] || g_hasRadio[id])
  406. {
  407. // Play animation
  408. UTIL_PlayWeaponAnimation(id, radio_fire)
  409.  
  410. // Detonate it
  411. detonate_satchel(id)
  412. }
  413. }
  414. }
  415. return FMRES_IGNORED
  416. }
  417.  
  418. // Satchel deploy
  419. public fw_SatchelDeploy(iEnt)
  420. {
  421. // Get id
  422. new id = get_pdata_cbase(iEnt, 41, 5)
  423.  
  424. // have satchel
  425. if (g_hasSatchel[id])
  426. {
  427. // Change models
  428. ChangeModelsSatchel(id)
  429.  
  430. // Play animation
  431. UTIL_PlayWeaponAnimation(id, satchel_draw)
  432.  
  433. // Modify time until next primary attack
  434. set_pdata_float(iEnt, 46, 9999.0, 4);
  435.  
  436. // Modify time until next attack
  437. set_pdata_float(id, 83, 9999.0);
  438. }
  439. }
  440.  
  441. // Radio deploy
  442. public fw_RadioDeploy(iEnt)
  443. {
  444. // Get id
  445. new id = get_pdata_cbase(iEnt, 41, 5)
  446.  
  447. // have satchel
  448. if (g_hasPlanted[id] || g_hasRadio[id] )
  449. {
  450. // Change radio models
  451. ChangeModelsRadio(id)
  452.  
  453. // Play animation
  454. UTIL_PlayWeaponAnimation(id, radio_draw)
  455.  
  456. // Modify time until next primary attack
  457. set_pdata_float(iEnt, 46, 9999.0, 4);
  458.  
  459. // Modify time until next attack
  460. set_pdata_float(id, 83, 9999.0);
  461.  
  462. }
  463. }
  464.  
  465. // Player killed
  466. public fw_PlayerKilled(victim, attacker, shouldgib)
  467. {
  468. // Have satchel
  469. if (g_hasSatchel[victim] || g_hasPlanted[victim])
  470. {
  471. // Reset vars
  472. g_hasSatchel[victim] = false
  473. g_hasPlanted[victim] = false
  474. g_CanPlant[victim] = false
  475. g_hasRadio[victim] = false
  476.  
  477. // Drop satchel
  478. drop_satchel(victim)
  479.  
  480. // Fix
  481. touch_fix(victim)
  482.  
  483. // Remove planted satchel
  484. remove_planted_satchel()
  485. }
  486. }
  487.  
  488. // Plant satchel
  489. public plant_satchel(id)
  490. {
  491. // Zombie/Nemesis/Dead
  492. if (zp_get_user_zombie(id) || zp_get_user_nemesis(id) || !is_user_alive(id))
  493. return PLUGIN_CONTINUE
  494.  
  495. // Now all is OK
  496. set_task(0.1 ,"CreateBomb", id, _, _, _)
  497.  
  498. // Strip from hegrenade
  499. ham_strip_weapon(id, "weapon_hegrenade")
  500.  
  501. // Change models
  502. ChangeModelsRadio(id)
  503.  
  504. // Switch to knife
  505. engclient_cmd(id, "weapon_knife")
  506.  
  507. // Reset stuff
  508. g_hasPlanted[id] = true
  509. g_hasRadio[id] = true
  510. g_hasSatchel[id] = false
  511. g_CanPlant[id] = false
  512.  
  513. return PLUGIN_CONTINUE
  514. }
  515.  
  516. // Create bomb
  517. public CreateBomb(id)
  518. {
  519. // Play animation
  520. UTIL_PlayWeaponAnimation(id, satchel_drop)
  521.  
  522. // Create entity
  523. new iBomb = create_entity("info_target")
  524.  
  525. if(iBomb == 0)
  526. return PLUGIN_HANDLED
  527.  
  528. // Set it's classname
  529. entity_set_string(iBomb, EV_SZ_classname, "remote_bomb")
  530.  
  531. // Set it's model
  532. entity_set_model(iBomb, w_satchel)
  533.  
  534. // Set it's size
  535. entity_set_size(iBomb, Float:{-2.0,-2.0,-1.0}, Float:{2.0,2.0,1.0})
  536.  
  537. entity_set_int(iBomb, EV_INT_movetype, MOVETYPE_TOSS)
  538. entity_set_int(iBomb, EV_INT_solid, SOLID_TRIGGER)
  539.  
  540. // Set it's gravity
  541. entity_set_float(iBomb, EV_FL_gravity, 0.9)
  542.  
  543. // Drop it to flooe
  544. engfunc(EngFunc_DropToFloor, iBomb)
  545.  
  546. // Get origin and vector
  547. new Float:iOrigin[3]
  548. entity_get_vector(id, EV_VEC_origin, iOrigin)
  549. //iOrigin[1] += 50
  550.  
  551. // Set angle
  552. new Float:angles[3]
  553. angles[0] += 180
  554. angles[1] += 90
  555. angles[2] += 90
  556. entity_set_vector(iBomb, EV_VEC_angles, angles)
  557.  
  558. // Set origin and angles
  559. entity_set_origin(iBomb, iOrigin)
  560.  
  561. // Get owner
  562. entity_set_int(iBomb, EV_ENT_owner, id)
  563.  
  564. // Notice player
  565. client_print(id, print_center ,"%s", NOTICE_PLANT)
  566.  
  567. // Play sound
  568. emit_sound(id, CHAN_WEAPON, "weapons/c4_plant.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
  569.  
  570. // Next think
  571. entity_set_float(iBomb, EV_FL_nextthink, halflife_time() + 0.01)
  572.  
  573. // Reset
  574. //g_hasPlanted[id] = true
  575. //g_hasRadio[id] = true
  576. //g_CanPlant[id] = false
  577. //g_hasSatchel[id] = false
  578.  
  579. return PLUGIN_HANDLED
  580. }
  581.  
  582. // Detonate satchel
  583. public detonate_satchel(id)
  584. {
  585. // Zombie/Nemesis/Dead
  586. if (zp_get_user_zombie(id) || zp_get_user_nemesis(id) || !is_user_alive(id))
  587. return PLUGIN_CONTINUE
  588.  
  589. // Have planted
  590. if (g_hasPlanted[id])
  591. {
  592. // Find ent
  593. new ent = find_ent_by_class(id, "remote_bomb")
  594.  
  595. if (ent)
  596. {
  597. // Create explosion
  598. CreateExplosion(ent)
  599.  
  600. // Remove ent
  601. remove_entity(ent)
  602.  
  603. // Force switch to knife
  604. engclient_cmd(id, "weapon_knife")
  605.  
  606. // Reset knife model
  607. reset_user_knife(id)
  608.  
  609. // Reset vars
  610. g_hasPlanted[id] = false
  611. g_hasRadio[id] = false
  612. g_hasSatchel[id] = false
  613. g_CanPlant[id] = false
  614. }
  615. }
  616.  
  617. return PLUGIN_CONTINUE
  618. }
  619.  
  620. // Create explosion
  621. public CreateExplosion(ent)
  622. {
  623. // Invalid entity
  624. if (!pev_valid(ent))
  625. return
  626.  
  627. // Get it's origin
  628. new Float:origin[3];pev(ent, pev_origin, origin)
  629.  
  630. // Explosion
  631. message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
  632. write_byte (TE_EXPLOSION) // TE ID
  633. engfunc(EngFunc_WriteCoord, origin[0]) // Position X
  634. engfunc(EngFunc_WriteCoord, origin[1]) // Y
  635. engfunc(EngFunc_WriteCoord, origin[2] + 30.0) // Z
  636. write_short(g_exploSpr) // Sprite index
  637. write_byte(30) // Scale
  638. write_byte(15) // Framerate
  639. write_byte(0) // Explosion Flag:None
  640. message_end()
  641.  
  642. // Smoke
  643. message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
  644. write_byte (TE_SMOKE) // TE ID
  645. engfunc(EngFunc_WriteCoord, origin[0]) // Position X
  646. engfunc(EngFunc_WriteCoord, origin[1]) // Y
  647. engfunc(EngFunc_WriteCoord, origin[2] + 50.0) // Z
  648. write_short(g_smokeSpr) // Sprite index
  649. write_byte(100) // Scale
  650. write_byte(15) // Framerate
  651. message_end()
  652.  
  653. // Owner
  654. new owner = entity_get_int(ent, EV_ENT_owner)
  655.  
  656. // Make a loop
  657. for (new i = 1; i < g_maxplayers; i++)
  658. {
  659. // Classname
  660. new szClassName[32]
  661. entity_get_string(i, EV_SZ_classname, szClassName, 32)
  662.  
  663. // Player
  664. if (equal(szClassName, "player"))
  665. {
  666. // Alive/Don't have godmode
  667. if (is_user_alive(i) == 1 && get_user_godmode(i) == 0 )
  668. {
  669. // Zombie/Nemesis
  670. if (zp_get_user_zombie(i) || zp_get_user_nemesis(i))
  671. {
  672. // Get origina and distance
  673. new Float:VictimOrigin[3], Float:distance_f, distance
  674. pev(i, pev_origin, VictimOrigin)
  675. distance_f = get_distance_f(origin, VictimOrigin)
  676. distance = floatround(distance_f)
  677.  
  678. if (distance < get_pcvar_num(cvar_radius))
  679. {
  680. // Fake damage
  681. fakedamage(i, "grenade", 0.0, DMG_BLAST)
  682.  
  683. // Get health/dmg/damage ratio
  684. new Float:dratio, damage
  685. dratio = floatdiv(float(distance),float(get_pcvar_num(cvar_radius)))
  686. damage = get_pcvar_num(cvar_dmg) - floatround(floatmul(float(get_pcvar_num(cvar_dmg)), dratio))
  687. new health = get_user_health(i)
  688.  
  689. // Make some knockback
  690. new Float:knockback = get_pcvar_float(cvar_knockback)
  691. make_knockback(i, origin, knockback*damage)
  692.  
  693. if (health - damage >= 1)
  694. {
  695. // New health
  696. set_user_health(i, health - damage)
  697.  
  698. // Create blood
  699. //ShowSomeBlood(VictimOrigin)
  700.  
  701. //client_print(owner, print_chat, "===>DAMADE %d<===", damage)
  702. }
  703. else
  704. {
  705. // Log this
  706. log_kill(owner, i, "grenade", 0)
  707.  
  708. // Set ammo packs
  709. zp_set_user_ammo_packs(owner, zp_get_user_ammo_packs(owner) + 1)
  710. }
  711. }
  712. }
  713. // Remove ent
  714. set_pev(ent, pev_flags, FL_KILLME)
  715. }
  716. }
  717. }
  718. }
  719.  
  720. // Remove planted satchels
  721. public remove_planted_satchel()
  722. {
  723. // Find
  724. new ent = find_ent_by_class(-1, "remote_bomb")
  725.  
  726. // And remove
  727. if (ent)
  728. {
  729. engfunc(EngFunc_RemoveEntity, ent)
  730. }
  731. }
  732.  
  733. // Remove dropped
  734. public remove_dropped_satchel()
  735. {
  736. // Find
  737. new ent = find_ent_by_class(-1, "drop_satchel")
  738.  
  739. // And remove
  740. if (ent)
  741. {
  742. engfunc(EngFunc_RemoveEntity, ent)
  743. }
  744. }
  745.  
  746. // Drop satchel ent
  747. public drop_satchel(id)
  748. {
  749. // Get aimvec and origin
  750. static Float:flAim[3], Float:flOrigin[3]
  751. VelocityByAim(id, 64, flAim)
  752. entity_get_vector(id, EV_VEC_origin, flOrigin)
  753.  
  754. // Change them a bit
  755. flOrigin[0] += flAim[0]
  756. flOrigin[1] += flAim[1]
  757.  
  758. // New ent
  759. new iEnt = create_entity("info_target")
  760.  
  761. // Classname
  762. entity_set_string(iEnt, EV_SZ_classname, "drop_satchel")
  763.  
  764. // Origin
  765. entity_set_origin(iEnt, flOrigin)
  766.  
  767. // Model
  768. entity_set_model(iEnt, w_satchel)
  769.  
  770. // Size
  771. new Float:mins[3] = {-1.0, -1.0, -1.0}
  772. new Float:maxs[3] = {1.0, 1.0, 1.0}
  773. entity_set_vector(iEnt, EV_VEC_mins, mins)
  774. entity_set_vector(iEnt, EV_VEC_maxs, maxs)
  775.  
  776. // Interaction
  777. entity_set_int(iEnt, EV_INT_solid, SOLID_TRIGGER)
  778.  
  779. // Movetype
  780. entity_set_int(iEnt, EV_INT_movetype, MOVETYPE_TOSS)
  781.  
  782. // Strip from HE Grenade
  783. ham_strip_weapon(id, "weapon_hegrenade")
  784.  
  785. // Reset vars
  786. g_hasSatchel[id] = false
  787. g_hasPlanted[id] = false
  788. g_CanPlant[id] = false
  789. g_hasRadio[id] = false
  790. }
  791.  
  792. // Someone touched dropped satchel
  793. public satchel_touch(stchl, ent)
  794. {
  795. // Prevent invalid ent messages
  796. if (!is_valid_ent(stchl) || !is_valid_ent(ent))
  797. return PLUGIN_CONTINUE
  798.  
  799. // Not allowed to touch
  800. if (zp_get_user_zombie(ent) || zp_get_user_nemesis(ent) || g_hasSatchel[ent] || g_hasRadio[ent])
  801. return PLUGIN_CONTINUE
  802.  
  803. // Reset vars
  804. g_hasSatchel[ent] = true
  805. g_hasRadio[ent] = true
  806. g_hasPlanted[ent] = false
  807. g_CanPlant[ent] = true
  808.  
  809. // Give awp
  810. give_item(ent, "weapon_hegrenade")
  811.  
  812. // Switch to he grenade
  813. client_cmd(ent, "weapon_hegrenade")
  814.  
  815. // Change models
  816. ChangeModelsSatchel(ent)
  817.  
  818. // Remove crossbow on ground
  819. remove_entity(stchl)
  820.  
  821. return PLUGIN_CONTINUE
  822. }
  823.  
  824. // Satchel Models
  825. stock ChangeModelsSatchel(id)
  826. {
  827. set_pev(id, pev_viewmodel2, v_satchel)
  828. set_pev(id, pev_weaponmodel2, p_satchel)
  829. }
  830.  
  831. // Radio models
  832. stock ChangeModelsRadio(id)
  833. {
  834. set_pev(id, pev_viewmodel2, v_satchel_radio)
  835. set_pev(id, pev_weaponmodel2, p_satchel_radio)
  836. }
  837.  
  838. // Play animation(Arkshine)
  839. stock UTIL_PlayWeaponAnimation(const Player, const Sequence)
  840. {
  841. set_pev(Player, pev_weaponanim, Sequence);
  842.  
  843. message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player);
  844. write_byte(Sequence);
  845. write_byte(pev(Player, pev_body));
  846. message_end();
  847. }
  848.  
  849. // Log kill
  850. stock log_kill(killer, victim, weapon[],headshot)
  851. {
  852. set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
  853. ExecuteHamB(Ham_Killed, victim, killer, 2)
  854. set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)
  855.  
  856. message_begin(MSG_ALL, get_user_msgid("DeathMsg"), {0,0,0}, 0)
  857. write_byte(killer)
  858. write_byte(victim)
  859. write_byte(headshot)
  860. write_string(weapon)
  861. message_end()
  862.  
  863. new kname[32], vname[32], kauthid[32], vauthid[32], kteam[10], vteam[10]
  864.  
  865. get_user_name(killer, kname, 31)
  866. get_user_team(killer, kteam, 9)
  867. get_user_authid(killer, kauthid, 31)
  868.  
  869. get_user_name(victim, vname, 31)
  870. get_user_team(victim, vteam, 9)
  871. get_user_authid(victim, vauthid, 31)
  872.  
  873. log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"",
  874. kname, get_user_userid(killer), kauthid, kteam,
  875. vname, get_user_userid(victim), vauthid, vteam, weapon)
  876.  
  877. UpdateScore(killer, victim, 0,0, 1)
  878.  
  879. return PLUGIN_CONTINUE
  880. }
  881.  
  882. // Update score
  883. stock UpdateScore(attacker, victim, frags, deaths, scoreboard)
  884. {
  885. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + frags))
  886.  
  887. cs_set_user_deaths(victim, cs_get_user_deaths(victim) + deaths)
  888.  
  889. if (scoreboard)
  890. {
  891. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  892. write_byte(attacker) // id
  893. write_short(pev(attacker, pev_frags)) // frags
  894. write_short(cs_get_user_deaths(attacker)) // deaths
  895. write_short(0) // class?
  896. write_short(get_user_team(attacker)) // team
  897. message_end()
  898.  
  899. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  900. write_byte(victim) // id
  901. write_short(pev(victim, pev_frags)) // frags
  902. write_short(cs_get_user_deaths(victim)) // deaths
  903. write_short(0) // class?
  904. write_short(get_user_team(victim)) // team
  905. message_end()
  906. }
  907. }
  908.  
  909. // touch fix
  910. public touch_fix(id)
  911. {
  912. if (g_hasSatchel[id])
  913. {
  914. g_hasSatchel[id] = false
  915. g_hasRadio[id] = false
  916. g_hasPlanted[id] = false
  917. g_CanPlant[id] = false
  918. }
  919. }
  920.  
  921. // Ham strip weapon
  922. stock ham_strip_weapon(id, weapon[])
  923. {
  924. if(!equal(weapon,"weapon_",7))
  925. return 0
  926.  
  927. new wId = get_weaponid(weapon)
  928.  
  929. if(!wId) return 0
  930.  
  931. new wEnt
  932.  
  933. while((wEnt = find_ent_by_class(wEnt, weapon)) && entity_get_edict(wEnt, EV_ENT_owner) != id) {}
  934.  
  935. if(!wEnt) return 0
  936.  
  937. if(get_user_weapon(id) == wId)
  938. ExecuteHamB(Ham_Weapon_RetireWeapon,wEnt);
  939.  
  940. if(!ExecuteHamB(Ham_RemovePlayerItem,id,wEnt))
  941. return 0
  942.  
  943. ExecuteHamB(Ham_Item_Kill, wEnt)
  944.  
  945. entity_set_int(id, EV_INT_weapons, entity_get_int(id, EV_INT_weapons) & ~(1<<wId))
  946.  
  947. return 1
  948. }
  949. // Reset knife model
  950. stock reset_user_knife(id)
  951. {
  952. // Execute weapon Deploy
  953. if(user_has_weapon(id, CSW_KNIFE))
  954. ExecuteHamB(Ham_Item_Deploy, find_ent_by_owner(-1, "weapon_knife", id))
  955.  
  956. // Updating Model
  957. engclient_cmd(id, "weapon_knife")
  958. emessage_begin(MSG_ONE, get_user_msgid("CurWeapon"), _, id)
  959. ewrite_byte(1) // active
  960. ewrite_byte(CSW_KNIFE) // weapon
  961. ewrite_byte(-1) // clip
  962. emessage_end()
  963. }
  964.  
  965. // Make knockback
  966. stock make_knockback(victim, Float:origin[3], Float:maxspeed)
  967. {
  968. // Get and set velocity
  969. new Float:fVelocity[3];
  970. kickback(victim, origin, maxspeed, fVelocity)
  971. entity_set_vector(victim, EV_VEC_velocity, fVelocity);
  972.  
  973. return (1);
  974. }
  975.  
  976. // Extra calulation for knockback
  977. stock kickback(ent, Float:fOrigin[3], Float:fSpeed, Float:fVelocity[3])
  978. {
  979. // Find origin
  980. new Float:fEntOrigin[3];
  981. entity_get_vector( ent, EV_VEC_origin, fEntOrigin );
  982.  
  983. // Do some calculations
  984. new Float:fDistance[3];
  985. fDistance[0] = fEntOrigin[0] - fOrigin[0];
  986. fDistance[1] = fEntOrigin[1] - fOrigin[1];
  987. fDistance[2] = fEntOrigin[2] - fOrigin[2];
  988. new Float:fTime = (vector_distance( fEntOrigin,fOrigin ) / fSpeed);
  989. fVelocity[0] = fDistance[0] / fTime;
  990. fVelocity[1] = fDistance[1] / fTime;
  991. fVelocity[2] = fDistance[2] / fTime;
  992.  
  993. return (fVelocity[0] && fVelocity[1] && fVelocity[2]);
  994. }
  995.  
  996.  
  997. /* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
  998. *{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
  999. */
  1000.