HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. /*
  2. Copyright © 2009, NiHiLaNTh
  3.  
  4. Crossbow 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 Crossbow 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. This is Crossbow from HL.It costs 9000 $.To attack press attack1
  20. button, to use zoom press attack2.If you shoot while zooming crossbow just hit enemy/
  21. wall, but if you are shooting without zoom bolt will explode and do more damage.
  22. You have 5 bolts in clip and 25 in backpack.Also, there is avaiable alternative model
  23. (see .zip file)
  24.  
  25. --- Requirements ---
  26. Counter-Strike 1.6 (Don't know about Condition-Zero, but should work)
  27. AmxModX 1.8.0 or higher
  28. Cstrike,Engine,Fakemeta,Hamsandwich modules
  29.  
  30. --- Credits ---
  31. NiHiLaNTh - Plugin
  32. VEN - Finding weapon entities
  33. Arkshine - Ham_Item_Deploy/getting fov/weapon animation
  34. meTaLiCroSS - Weapon touch/Weapon drop after death
  35. Scorpieo - Alternative crossbow model
  36. ConnorMcLeod - Maxclip plugin
  37. Nextra - Improvements
  38. crazyeffect - MultiLingual / Dutch translation
  39.  
  40. --- CVARs ---
  41. amx_crossbow 1 Enable(1) or disable(0) plugin
  42. amx_crossbow_price 9000 Price of crossbow
  43. amx_crossbow_damage 75 Damage done by explosion
  44. amx_crossbow_damage2 90 Damage done by bolt
  45. amx_crossbow_radius 175 Explosion radius
  46. amx_crossbow_one_round 1 // 1 - one round; 0 - until player got killed
  47. amx_crossbow_knockback 10 // Knockback power
  48. amx_crossbow_buyzone 1 Crossbow buying only in buyzone(1) or everywhere on the map
  49. amx_crossbow_kill_money 300 Money reward for killing enemy
  50. amx_crossbow_tk_money 500 Money for team kill
  51. amx_crossbow_admin 0 If 1 admins with spec.flag can purchase crossbow
  52. amx_crossbow_teams 0 If 0 - both teams can buy crossbow; if 1 - T's only CAN buy; 2 - CT's only CAN buy
  53.  
  54. --- Client Commands ---
  55. amx_crossbow_give <nick> - Give crossbow for specified player (ADMIN_CVAR required)
  56.  
  57. Chat commands:
  58. say /xbow
  59. say /crossbow
  60.  
  61. --- Changelog ---
  62. v1.0 - First release
  63. v1.1 - Fixed bug where ammo was not updated correctly
  64. - Optimized bolt flight
  65. - Fixed crap runtime error
  66. v1.2 - Fixed some little bugs(ammo on zooming was not updated)
  67. v1.3 - Fixed bug with drop
  68. v1.4 - Fixed bug where player could reload infinite times
  69. - Fixed bug with score info
  70. - Added knockback from explosion
  71. v1.5 - Fixed bug where player were damaged and knockbacked, even he were not in radius
  72. - Fixed bug where player with godmode still could get damage
  73. - Fixed bug where player could reload with full clip
  74. - Fixed bug where player couldn't purchase crossbow after using antidote
  75. - Added bleed stuff
  76. - Added alternative model
  77. - Fixed bug where player could shoot while reloading
  78. v1.6 - Improved damage calculation system for exploding bolt
  79. - Added CVAR for crossbow one-round-only keeping
  80. - Improved damage detection system for normal bolt
  81. - Fixed bug with crossbow drop after death
  82. - Some minor optimizations/changes
  83. v1.7 - Added knockback CVAR
  84. - Improved knockback from explosion
  85. - Fixed bug with score info
  86. - Optimized code a bit
  87. v2.0 - Rewrited for non-zp usage
  88. v2.1 - Improved code (thanks Nextra )
  89. - Added ML support ( thanks crazyeffect )
  90.  
  91. Any suggestions/improvements are welcome!!!
  92. */
  93.  
  94. #include <amxmodx>
  95. #include <amxmisc>
  96. #include <cstrike>
  97. #include <engine>
  98. #include <fakemeta>
  99. #include <fun>
  100. #include <hamsandwich>
  101.  
  102. // Uncomment following if you want to see alternative model
  103. //#define ALTERNATIVE_MODEL
  104.  
  105. // Access flag needed to buy crossbow(if admin only cvar is enabled)
  106. #define BUY_FLAG ADMIN_BAN
  107.  
  108. // Plugin info
  109. new const PLUGIN[] = "[AMXX] Crossbow"
  110. new const VERSION[] = "2.0"
  111. new const AUTHOR[] = "NiHiLaNTh"
  112.  
  113. // Crossbow/Bolt models
  114. #if defined ALTERNATIVE_MODEL
  115. new const P_MODEL[] = "models/p_crossbow_alt.mdl"
  116. new const V_MODEL[] = "models/v_crossbow_alt.mdl"
  117. new const W_MODEL[] = "models/w_crossbow_alt.mdl"
  118. #else
  119. new const P_MODEL[] = "models/p_crossbow.mdl"
  120. new const V_MODEL[] = "models/v_crossbow.mdl"
  121. new const W_MODEL[] = "models/w_crossbow.mdl"
  122. #endif
  123. new const BOLT_MODEL[] = "models/crossbow_bolt.mdl"
  124.  
  125. // Some sounds
  126. new const XBOW_SHOOT[] = "weapons/xbow_fire1.wav"
  127. new const XBOW_HITWALL[] = "weapons/xbow_hit1.wav"
  128. new const XBOW_HITSTAB[] = "weapons/xbow_hitbod1.wav"
  129. new const XBOW_RELOAD[] = "weapons/xbow_reload1.wav"
  130.  
  131. // Sprites
  132. new const EXPLO_SPRITE[] = "sprites/zerogxplode.spr"
  133. new const BLOOD_SPRITE[] = "sprites/blood.spr"
  134. new const BLOODSPRAY_SPRITE[] = "sprites/bloodspray.spr"
  135.  
  136. // Cached sprite indexes
  137. new sExplo, sBlood, sBlood2
  138.  
  139. // CVAR pointers
  140. new pDamage, pDamage2, pRadius, pOneRound, pKnockback, pPrice,
  141. pFF, pBuyzone, pKillMoney, pTKmoney, pAdmin, pTeams//, pOn
  142.  
  143. // Player variables
  144. new g_hasXbow[33] // whether player has Crossbow
  145. new Float:g_last_shot_time[33] // Last time Crossbow used
  146. new g_FullClip[33] // whether player has Full Clip
  147. new g_bInReload[33] // in reload
  148.  
  149. // Global variables
  150. new g_maxplayers, g_restarted, g_damage2, Float:g_radius, g_oneround, Float:g_knockback,
  151. g_price, g_buyzone, g_killmoney, g_tkmoney, g_damage, g_admin, g_teams//, g_on
  152.  
  153. // Message ID's
  154. new g_msgCurWeapon, g_msgAmmoX, g_msgScoreInfo, g_msgDeathMsg
  155.  
  156. // Weapon animation sequences
  157. enum
  158. {
  159. crossbow_idle1,
  160. crossbow_idle2,
  161. crossbow_fidget1,
  162. crossbow_fidget2,
  163. crossbow_fire1,
  164. crossbow_fire2,
  165. crossbow_fire3,
  166. crossbow_reload,
  167. crossbow_draw1,
  168. crossbow_draw2,
  169. crossbow_holster1,
  170. crossbow_holster2
  171. }
  172.  
  173. // CS offsets
  174. const m_pPlayer = 41
  175. const m_fKnown = 44
  176. const m_flNextPrimaryAttack = 46
  177. const m_flNextSecondaryAttack = 47
  178. const m_flTimeWeaponIdle = 48
  179. const m_iPrimaryAmmoType = 49
  180. const m_iClip = 51
  181. const m_fInReload = 54
  182. const m_fInSpecialReload = 55
  183. const m_fSilent = 74
  184. const m_flNextAttack = 83
  185. const m_rgAmmo_player_Slot0 = 376
  186.  
  187. // Precache
  188. public plugin_precache()
  189. {
  190. // Models
  191. precache_model(P_MODEL)
  192. precache_model(V_MODEL)
  193. precache_model(W_MODEL)
  194. precache_model(BOLT_MODEL)
  195.  
  196. // Sounds
  197. precache_sound(XBOW_SHOOT)
  198. precache_sound(XBOW_HITWALL)
  199. precache_sound(XBOW_HITSTAB)
  200. precache_sound(XBOW_RELOAD)
  201. precache_sound("weapons/dryfire1.wav")
  202.  
  203. // Sprites
  204. sExplo = precache_model(EXPLO_SPRITE)
  205. sBlood = precache_model(BLOOD_SPRITE)
  206. sBlood2 = precache_model(BLOODSPRAY_SPRITE)
  207. }
  208.  
  209. // Init
  210. public plugin_init()
  211. {
  212. // New plugin
  213. register_plugin(PLUGIN, VERSION, AUTHOR)
  214. register_cvar("amx_xbow_version", VERSION, FCVAR_SERVER|FCVAR_SPONLY)
  215.  
  216. // Buy clcmds
  217. register_clcmd("say /crossbow", "buy_crossbow")
  218. register_clcmd("say /xbow", "buy_crossbow")
  219.  
  220. // Console command
  221. register_concmd("amx_crossbow_give", "give_crossbow", ADMIN_CVAR, "<target> - Give crossbow")
  222.  
  223. // Events
  224. register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");
  225. register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
  226.  
  227. // Log Event
  228. register_logevent("LogEvent_RoundEnd", 2, "1=Round_End")
  229.  
  230. // Forward
  231. register_forward(FM_CmdStart, "fw_CmdStart")
  232. register_forward(FM_SetModel, "fw_SetModel")
  233. RegisterHam(Ham_Item_Deploy, "weapon_awp", "fw_CrossbowDeploy", 1)
  234. register_forward(FM_UpdateClientData, "fw_UpdateClientData_Post", 1)
  235. register_forward(FM_Touch, "fw_Touch")
  236. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
  237. RegisterHam(Ham_Weapon_Reload, "weapon_awp", "fw_WeaponReload", 1)
  238. RegisterHam(Ham_Item_PostFrame, "weapon_awp", "fw_AwpPostFrame")
  239. RegisterHam(Ham_Item_AttachToPlayer, "weapon_awp", "fw_AwpAttachToPlayer")
  240.  
  241. // ML
  242. register_dictionary("amx_crossbow.txt")
  243.  
  244. // Touches
  245. register_touch("xbow_bolt", "*", "bolt_touch")
  246. register_touch("xbow_bolt_xplode", "*", "bolt_touch2")
  247. register_touch("drop_crossbow", "player", "crossbow_touch")
  248.  
  249. // CVARs
  250. pDamage = register_cvar("amx_crossbow_damage", "75") // Damage done by expl
  251. pDamage2 = register_cvar("amx_crossbow_damage2", "90") // Damage done by bolt
  252. pRadius = register_cvar("amx_crossbow_radius", "175")
  253. pOneRound = register_cvar("amx_crossbow_one_round", "1")
  254. pKnockback = register_cvar("amx_crossbow_knockback", "10")
  255. pPrice = register_cvar("amx_crossbow_price", "9000")
  256. pFF = get_cvar_pointer("mp_friendlyfire")
  257. pBuyzone = register_cvar("amx_crossbow_buyzone", "1")
  258. pKillMoney = register_cvar("amx_crossbow_kill_money", "300")
  259. pTKmoney = register_cvar("amx_crossbow_tk_money", "500")
  260. pAdmin = register_cvar("amx_crossbow_admin", "0")
  261. pTeams = register_cvar("amx_crossbow_teams", "0")
  262. //pOn = register_cvar("amx_crossbow", "1")
  263.  
  264. // Store maxplayers in a global variable
  265. g_maxplayers = get_maxplayers()
  266.  
  267. // Messages
  268. g_msgCurWeapon = get_user_msgid("CurWeapon")
  269. g_msgAmmoX = get_user_msgid("AmmoX")
  270. g_msgScoreInfo = get_user_msgid("ScoreInfo")
  271. g_msgDeathMsg = get_user_msgid("DeathMsg")
  272. }
  273.  
  274.  
  275. // Strip from crossbow on disconnect
  276. public client_disconnect(id)
  277. {
  278. g_hasXbow[id] = false
  279. g_FullClip[id] = false
  280. g_bInReload[id] = false
  281. }
  282.  
  283. // New round started
  284. public Event_NewRound()
  285. {
  286. if (g_restarted)
  287. {
  288. // Strip from Crossnow if game have been restarted
  289. for (new i = 1; i <= g_maxplayers; i++)
  290. {
  291. if (g_hasXbow[i])
  292. {
  293. g_hasXbow[i] = false
  294. g_FullClip[i] = false
  295. g_bInReload[i] = false
  296. }
  297. }
  298. g_restarted = false
  299. }
  300.  
  301. // Cache all cvars
  302. g_damage2 = get_pcvar_num(pDamage2)
  303. g_radius = get_pcvar_float(pRadius)
  304. g_oneround = get_pcvar_num(pOneRound)
  305. g_knockback = get_pcvar_float(pKnockback)
  306. g_price = get_pcvar_num(pPrice)
  307. g_buyzone = get_pcvar_num(pBuyzone)
  308. g_killmoney = get_pcvar_num(pKillMoney)
  309. g_tkmoney = get_pcvar_num(pTKmoney)
  310. g_damage = get_pcvar_num(pDamage)
  311. g_admin = get_pcvar_num(pAdmin)
  312. g_teams = get_pcvar_num(pTeams)
  313. //g_on = get_pcvar_num(pOn)
  314. }
  315.  
  316. // Restart
  317. public Event_GameRestart()
  318. {
  319. g_restarted = true
  320. }
  321.  
  322.  
  323. // Someone want to purchase crossbow
  324. public buy_crossbow(id)
  325. {
  326. // Dead
  327. if (!is_user_alive(id))
  328. {
  329. return PLUGIN_HANDLED
  330. }
  331. // Already have crossbow
  332. else if (g_hasXbow[id])
  333. {
  334. client_print(id, print_chat, "[%L] %L", id, "TAG", id, "ALREADY")
  335. return PLUGIN_HANDLED
  336. }
  337. // Not in buyzone
  338. else if (!cs_get_user_buyzone(id) && g_buyzone == 1)
  339. {
  340. client_print(id, print_center, "[%L] %L", id, "TAG", id, "BUYZONE")
  341. return PLUGIN_HANDLED
  342. }
  343. // Don't have enough money
  344. else if (cs_get_user_money(id) < g_price)
  345. {
  346. client_print(id, print_center, "[%L] %L", id, "TAG", id, "NOT_ENOUGH")
  347. return PLUGIN_HANDLED
  348. }
  349. // Forbidden team
  350. static team; team = get_user_team(id)
  351. if (g_teams > 0 && g_teams != team)
  352. {
  353. client_print(id, print_chat, "[%L] %L", id, "TAG", id, "TEAM")
  354. return PLUGIN_HANDLED
  355. }
  356. // Don't have admin acc
  357. else if(!(get_user_flags(id) & BUY_FLAG) && g_admin == 1)
  358. {
  359. client_print(id, print_chat, "[%L] %L", id, "TAG", id, "ADMIN")
  360. return PLUGIN_HANDLED
  361. }
  362.  
  363. // Give crossbow
  364. give_xbow(id)
  365.  
  366. // Decrease money
  367. cs_set_user_money(id, cs_get_user_money(id) - g_price, 1)
  368.  
  369. // Notice
  370. client_print(id, print_chat, "[%L] %L", id, "TAG", id, "BOUGHT")
  371.  
  372. return PLUGIN_HANDLED
  373. }
  374.  
  375. // Give crossbow via console
  376. public give_crossbow(id, level, cid)
  377. {
  378. // Access level
  379. if (!cmd_access(id, level, cid, 2))
  380. return PLUGIN_HANDLED
  381.  
  382. // Retrieve arguments
  383. static arg[32], player, name[32], pname[32]
  384. read_argv(1, arg, sizeof arg - 1)
  385. get_user_name(id, name, sizeof name - 1)
  386. get_user_name(player, pname, sizeof pname - 1)
  387. player = cmd_target(id, arg, CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF)
  388.  
  389. // Invalid target
  390. if (!player)
  391. {
  392. console_print(id, "[%L] %L", id, "TAG", id, "CANNOT")
  393. return PLUGIN_HANDLED;
  394. }
  395.  
  396. // Give crossbow
  397. give_xbow(player)
  398.  
  399. // Notice
  400. client_print(0, print_chat, "[%L] %L", LANG_PLAYER, "TAG", LANG_PLAYER, "GAVE", name, pname)
  401.  
  402. return PLUGIN_HANDLED;
  403. }
  404.  
  405. // Round end
  406. public LogEvent_RoundEnd()
  407. {
  408. if (g_oneround == 1)
  409. {
  410. // Strip from crossbow
  411. for (new i = 1; i < g_maxplayers; i++)
  412. {
  413. fm_strip_user_gun(i, CSW_AWP)
  414. g_hasXbow[i] = false
  415. }
  416. }
  417.  
  418. // Find and remove all dropped crossbows
  419. new ent = find_ent_by_class(-1, "drop_crossbow")
  420. if (ent)
  421. remove_entity(ent)
  422. }
  423.  
  424. // Called when player start a command(shoot, jump etc.)
  425. public fw_CmdStart(id, uc_handle, seed)
  426. {
  427. // Ignore dead/those who haven't our weapon
  428. new ammo, clip, weapon = get_user_weapon(id, clip, ammo)
  429. if (!is_user_alive(id) || !g_hasXbow[id] || weapon != CSW_AWP)
  430. return FMRES_IGNORED
  431.  
  432. // Buttons
  433. new buttons = get_uc(uc_handle, UC_Buttons)
  434.  
  435. // Attack1 button was pressed
  436. if (buttons & IN_ATTACK)
  437. {
  438. // We have enough ammo
  439. if (clip>= 1 && !g_bInReload[id])
  440. {
  441. // Next shot time has come
  442. if (get_gametime() - g_last_shot_time[id] > 2.0)
  443. {
  444. // Get FOV(Arkshine)
  445. new fov; fov = pev(id, pev_fov)
  446.  
  447. // Default FOV
  448. if (fov == 90)
  449. {
  450. FireCrossbow(id, 0)
  451. }
  452. // Is zooming?
  453. else
  454. FireCrossbow(id, 1)
  455.  
  456. g_FullClip[id] = false
  457.  
  458. // Decrease ammo
  459. new ent = find_ent_by_owner(-1, "weapon_awp", id)
  460. cs_set_weapon_ammo(ent, cs_get_weapon_ammo(get_pdata_cbase(id, 373)) - 1)
  461.  
  462. // Update HUD
  463. UpdateHud(id)
  464.  
  465. // Remember last shot time
  466. g_last_shot_time[id] = get_gametime()
  467. }
  468. }
  469. // If out of ammo
  470. else if (clip <= 1 || ammo <= 1)
  471. {
  472. // Play empty sound
  473. emit_sound(id, CHAN_WEAPON, "weapons/357_cock1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
  474. }
  475.  
  476. // Remove attack button from their buttons mask
  477. buttons &= ~IN_ATTACK
  478. set_uc(uc_handle, UC_Buttons, buttons)
  479. }
  480.  
  481. // Attack2 button was pressed
  482. if (buttons & IN_ATTACK2)
  483. {
  484. // Update HUD(bugfix)
  485. UpdateHud(id)
  486. }
  487.  
  488. return FMRES_HANDLED
  489. }
  490.  
  491. // Called after player dropped weapons
  492. public fw_SetModel(ent, const model[])
  493. {
  494. // Prevent invalid entity messages
  495. if (!pev_valid(ent))
  496. return FMRES_IGNORED
  497.  
  498. // Not required model
  499. if(!equali(model, "models/w_awp.mdl"))
  500. return FMRES_IGNORED
  501.  
  502. // Get classname
  503. new classname[33]; pev(ent, pev_classname, classname, charsmax(classname))
  504.  
  505. // Entity classname is a weaponbox
  506. if(equal(classname, "weaponbox"))
  507. {
  508. new owner = pev(ent, pev_owner)
  509.  
  510. // The weapon owner has a crossbow
  511. if(g_hasXbow[owner])
  512. {
  513. // Strip from crossbow
  514. g_hasXbow[owner] = false
  515.  
  516. // Set world model
  517. engfunc(EngFunc_SetModel, ent, W_MODEL)
  518.  
  519. // Update HUD
  520. UpdateHud(owner)
  521.  
  522. // Touch fix
  523. set_task(0.1, "touch_fix", owner)
  524.  
  525. return FMRES_SUPERCEDE
  526. }
  527. }
  528.  
  529. return FMRES_IGNORED
  530.  
  531. }
  532.  
  533. // Called when player is holding this weapon
  534. public fw_CrossbowDeploy(iEnt)
  535. {
  536. // Get ID
  537. new id = get_pdata_cbase(iEnt, m_pPlayer, 5)
  538.  
  539. if (g_hasXbow[id])
  540. {
  541. // Cancel any reload
  542. g_bInReload[id] = false
  543.  
  544. // Change models
  545. ChangeModels(id)
  546.  
  547. // Play animation
  548. UTIL_PlayWeaponAnimation(id, crossbow_draw1)
  549.  
  550. // Update HUD
  551. UpdateHud(id)
  552. }
  553. }
  554.  
  555. // Update client data
  556. public fw_UpdateClientData_Post(id, sw, cd_handle)
  557. {
  558. // Ignore dead zombies/nemesis/those who haven't our weapons
  559. new weapon = get_user_weapon(id)
  560. if (!is_user_alive(id) || !g_hasXbow[id] || weapon != CSW_AWP)
  561. return FMRES_IGNORED
  562.  
  563. // Block default sounds/animations
  564. //set_cd(cd_handle, CD_ID, 0)
  565. set_cd(cd_handle, CD_flNextAttack, halflife_time() + 0,001)
  566. return FMRES_HANDLED
  567. }
  568.  
  569. // Called when player touch something
  570. public fw_Touch(ptr, ptd)
  571. {
  572. // Invalid ent/toucher
  573. if(!pev_valid(ptr) || !pev_valid(ptd))
  574. return FMRES_IGNORED;
  575.  
  576. // Get model, toucherclass, entityclass
  577. new toucherclass[33], entityclass[33]
  578. pev(ptr, pev_classname, entityclass, charsmax(entityclass))
  579. pev(ptd, pev_classname, toucherclass, charsmax(toucherclass))
  580.  
  581. // TOucher isn't player and entity isn't weapon
  582. if (!equali(toucherclass, "player") || !equali(entityclass, "weaponbox"))
  583. return FMRES_IGNORED
  584.  
  585. // Our world model
  586. new model[33]; pev(ptr, pev_model, model, charsmax(model))
  587. if(equali(model, W_MODEL))
  588. {
  589. // If allowed to touch
  590. if(allowed_toucher(ptd))
  591. {
  592. // Pick up weapon
  593. g_hasXbow[ptd] = true
  594. }
  595. }
  596.  
  597. return FMRES_IGNORED;
  598. }
  599.  
  600. // Called when player died
  601. public fw_PlayerKilled(victim, attacker, shouldgib)
  602. {
  603. if (g_hasXbow[victim])
  604. {
  605. g_hasXbow[victim] = false
  606.  
  607. // Drop crossbow
  608. crossbow_drop(victim)
  609. }
  610. }
  611.  
  612. // Called on reload
  613. public fw_WeaponReload(iEnt)
  614. {
  615. // Get ID
  616. new id = get_pdata_cbase(iEnt, m_pPlayer, 5)
  617.  
  618. // Has crossbow
  619. if (g_hasXbow[id] && !g_FullClip[id])
  620. {
  621. set_pdata_int(iEnt, m_fInReload, 1, 4)
  622.  
  623. // Set animation
  624. UTIL_PlayWeaponAnimation(id, crossbow_reload)
  625.  
  626. // Emit sound
  627. emit_sound(id, CHAN_WEAPON, XBOW_RELOAD, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
  628.  
  629. g_FullClip[id] = true
  630. g_bInReload[id] = true
  631.  
  632. // Update HUD
  633. UpdateHud(id)
  634.  
  635. // Remove reload task
  636. set_task(4.0, "no_reload", id)
  637. }
  638. }
  639.  
  640. // Crossbow post frame
  641. public fw_AwpPostFrame(iEnt)
  642. {
  643. // Player
  644. new id = get_pdata_cbase(iEnt, m_pPlayer, 4)
  645.  
  646. if (g_hasXbow[id])
  647. {
  648. // Reload offset
  649. new fInReload = get_pdata_int(iEnt, m_fInReload, 4)
  650.  
  651. // Next attack time
  652. new Float:flNextAttack = get_pdata_float(id, m_flNextAttack, 5)
  653.  
  654. // Old clip
  655. new iClip ; iClip = get_pdata_int(iEnt, m_iClip, 4)
  656.  
  657. // Set new clip
  658. new iMaxClip = 5
  659.  
  660. // Ammo type
  661. new iAmmoType = m_rgAmmo_player_Slot0 + get_pdata_int(iEnt, m_iPrimaryAmmoType, 4)
  662.  
  663. // BP ammo
  664. new iBpAmmo ; iBpAmmo = get_pdata_int(id, iAmmoType, 5)
  665.  
  666. // Reloading and recently attacked
  667. if( fInReload && flNextAttack <= 0.0 )
  668. {
  669. new j = min(iMaxClip - iClip, iBpAmmo)
  670.  
  671. // Set new clip
  672. set_pdata_int(iEnt, m_iClip, iClip + j, 4)
  673.  
  674. // Decrease 'x' bullets from backpack(depending on new clip)
  675. set_pdata_int(id, iAmmoType, iBpAmmo-j, 5)
  676.  
  677. // Not reloding anymore
  678. set_pdata_int(iEnt, m_fInReload, 0, 4)
  679. fInReload = 0
  680. }
  681.  
  682. // GEt buttons
  683. static iButton ; iButton = pev(id, pev_button)
  684.  
  685. // Attack/Attack2 buttons and next prim/sec attack time hasnt' come yet
  686. if( (iButton & IN_ATTACK2 && get_pdata_float(iEnt, m_flNextSecondaryAttack, 4) <= 0.0)
  687. || (iButton & IN_ATTACK && get_pdata_float(iEnt, m_flNextPrimaryAttack, 4) <= 0.0) )
  688. {
  689. return
  690. }
  691.  
  692. // Reload button / not reloading
  693. if( iButton & IN_RELOAD && !fInReload )
  694. {
  695. // Old clip is more/equal than/to new
  696. if( iClip >= iMaxClip )
  697. {
  698. // Remove reload button
  699. set_pev(id, pev_button, iButton & ~IN_RELOAD)
  700.  
  701. //Don't play reload animation
  702. UTIL_PlayWeaponAnimation(id, 0)
  703. }
  704. // Old clip
  705. else if( iClip ==10)
  706. {
  707. if( iBpAmmo )
  708. {
  709. // Firerate
  710. new Float:g_fDelay = 2.50
  711.  
  712. // Next attack time
  713. set_pdata_float(id, m_flNextAttack, g_fDelay, 5)
  714.  
  715. // Reload animation
  716. UTIL_PlayWeaponAnimation(id, crossbow_reload)
  717.  
  718. // Reload offset
  719. set_pdata_int(iEnt, m_fInReload, 1, 4)
  720.  
  721. // Idle time
  722. set_pdata_float(iEnt, m_flTimeWeaponIdle, g_fDelay + 0.5, 4)
  723. }
  724. }
  725. }
  726. }
  727. }
  728.  
  729. // Add awp to player
  730. public fw_AwpAttachToPlayer(iEnt, id)
  731. {
  732. // Get id
  733. new id = get_pdata_cbase(iEnt, m_pPlayer, 4)
  734.  
  735. // Have crossbow
  736. if (g_hasXbow[id])
  737. {
  738. if(get_pdata_int(iEnt, m_fKnown, 4))
  739. return
  740.  
  741. // Set new clip
  742. set_pdata_int(iEnt, m_iClip, 5, 4)
  743. }
  744. }
  745.  
  746. // Fire crossbow
  747. public FireCrossbow(id, type)
  748. {
  749. // Get origin, angle, and velocity
  750. new Float:fOrigin[3], Float:fAngle[3], Float:fVelocity[3]
  751. pev(id, pev_origin, fOrigin)
  752. pev(id, pev_v_angle, fAngle)
  753.  
  754. // New ent
  755. new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
  756.  
  757. // Not ent
  758. if (!ent) return PLUGIN_HANDLED
  759.  
  760. // If player shot while zooming...
  761. if (type == 1)
  762. {
  763. // Set classnames
  764. entity_set_string(ent, EV_SZ_classname, "xbow_bolt")
  765. }
  766. else
  767. {
  768. entity_set_string(ent, EV_SZ_classname, "xbow_bolt_xplode")
  769. }
  770.  
  771. // Set bolt model
  772. entity_set_model(ent, BOLT_MODEL)
  773.  
  774. // Origin
  775. entity_set_origin(ent, fOrigin)
  776.  
  777. // Angles
  778. entity_set_vector(ent, EV_VEC_angles, fAngle)
  779.  
  780. // Size
  781. new Float:MinBox[3] = {-1.0, -1.0, -1.0}
  782. new Float:MaxBox[3] = {1.0, 1.0, 1.0}
  783. entity_set_vector(ent, EV_VEC_mins, MinBox)
  784. entity_set_vector(ent, EV_VEC_maxs, MaxBox)
  785.  
  786. // Interaction
  787. entity_set_int(ent, EV_INT_solid, SOLID_SLIDEBOX)
  788.  
  789. // Movetype
  790. entity_set_int(ent, EV_INT_movetype, MOVETYPE_FLY)
  791.  
  792. // Owner
  793. entity_set_edict(ent, EV_ENT_owner, id)
  794.  
  795. // Velocity
  796. VelocityByAim(id, 2000, fVelocity)
  797. entity_set_vector(ent, EV_VEC_velocity, fVelocity)
  798.  
  799. // Play animation
  800. UTIL_PlayWeaponAnimation(id, crossbow_fire1)
  801.  
  802. // Play sound
  803. emit_sound(id, CHAN_WEAPON, XBOW_SHOOT, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
  804.  
  805. return PLUGIN_CONTINUE
  806. }
  807.  
  808. // Normal bolt touched something
  809. public bolt_touch(bolt, ent)
  810. {
  811. // Invalid ent
  812. if (!pev_valid(bolt))
  813. {
  814. //client_print(0, print_chat, "Error! Invalid entity %d", bolt)
  815. return
  816. }
  817.  
  818. // GEt classname
  819. new classname[32]; pev(ent, pev_classname, classname, 31)
  820.  
  821. // Player
  822. if (equal(classname, "player"))
  823. {
  824. new owner = pev(bolt, pev_owner);
  825.  
  826. // Get it's origin
  827. new Float:originF[3], aimvec[3], tid, body
  828. pev(bolt, pev_origin, originF)
  829.  
  830. // Get user aim vector
  831. get_user_origin(owner, aimvec, 3)
  832. get_user_aiming(owner, tid, body)
  833.  
  834. // Alive...
  835. if (is_user_alive(tid) == 1 && get_user_godmode(tid) == 0)
  836. {
  837. // Zombie/Nemesis
  838. if (cs_get_user_team(owner) != cs_get_user_team(tid) || get_pcvar_num(pFF) == 1)
  839. {
  840. // Get origina and distance
  841. new Float:VictimOrigin[3]
  842. pev(tid, pev_origin, VictimOrigin)
  843.  
  844. // We hit them
  845. emit_sound(tid, CHAN_WEAPON, XBOW_HITSTAB, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
  846.  
  847. // Do fake damage
  848. fakedamage(tid, "crossbow", 0.0, DMG_PARALYZE)
  849.  
  850. // Health/Damage
  851. new health = get_user_health(tid)
  852.  
  853. if (health - g_damage2 >= 1)
  854. {
  855. set_user_health(tid, health - g_damage2)
  856.  
  857. // Create blood
  858. ShowSomeBlood(VictimOrigin)
  859.  
  860. //client_print(owner, print_chat, "===>DAMADE %d<===", damage)
  861. }
  862. else
  863. {
  864. // Kill them
  865. //user_silentkill(tid)
  866.  
  867. // Log this
  868. log_kill(owner, tid, "crossbow", 0)
  869.  
  870. // Set new money for killing enemy
  871. if (cs_get_user_team(owner) != cs_get_user_team(tid))
  872. cs_set_user_money(owner, cs_get_user_money(owner) + g_killmoney, 1)
  873. // Team kill
  874. else
  875. cs_set_user_money(owner, cs_get_user_money(owner) - g_tkmoney, 1)
  876. }
  877.  
  878. }
  879. // Destroy ent
  880. set_pev(bolt, pev_flags, FL_KILLME)
  881. }
  882. }
  883. // Not a player(wall etc.)
  884. else
  885. {
  886. // Play sound
  887. emit_sound(bolt, CHAN_WEAPON, XBOW_HITWALL, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
  888.  
  889. // Destroy ent
  890. set_pev(bolt, pev_flags, FL_KILLME)
  891. }
  892. }
  893.  
  894. // Exploding bolt touched something
  895. public bolt_touch2(bolt2, ent)
  896. {
  897. // Invalid ent
  898. if (!pev_valid(bolt2))
  899. return
  900.  
  901. // GEt owner and classname
  902. new owner = pev(bolt2, pev_owner);
  903. new classname[32]; pev(ent, pev_classname, classname, 31)
  904.  
  905. // Get it's origin
  906. new Float:originV[3]
  907. pev(bolt2, pev_origin, originV)
  908.  
  909. // Draw explosion
  910. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  911. write_byte(TE_EXPLOSION)
  912. engfunc(EngFunc_WriteCoord, originV[0])
  913. engfunc(EngFunc_WriteCoord, originV[1])
  914. engfunc(EngFunc_WriteCoord, originV[2])
  915. write_short(sExplo)
  916. write_byte(10) // Scale
  917. write_byte(15) // Framerate
  918. write_byte(0)
  919. message_end()
  920.  
  921. // Loop through all players
  922. for(new i = 1; i < g_maxplayers; i++)
  923. {
  924. // Alive...
  925. if (is_user_alive(i) == 1 && get_user_godmode(i) == 0)
  926. {
  927. // Zombie/Nemesis
  928. if (cs_get_user_team(owner) != cs_get_user_team(i) || get_pcvar_num(pFF) == 1)
  929. {
  930. // Get origina and distance
  931. new Float:VictimOrigin[3], Float:distance_f, distance
  932. pev(i, pev_origin, VictimOrigin)
  933. distance_f = get_distance_f(originV, VictimOrigin)
  934. distance = floatround(distance_f)
  935.  
  936. if (distance <= g_radius)
  937. {
  938. // Fake damage
  939. fakedamage(i, "crossbow", 0.0, DMG_BLAST)
  940.  
  941. // Get health/dmg/damage ratio
  942. new Float:dratio, damage
  943. dratio = floatdiv(float(distance),float(get_pcvar_num(pRadius)))
  944. damage = g_damage - floatround(floatmul(float(g_damage), dratio))
  945. new health = get_user_health(i)
  946.  
  947. // Make some knockback
  948. make_knockback(i, originV, g_knockback*damage)
  949.  
  950. if (health - damage >= 1)
  951. {
  952. set_user_health(i, health - damage)
  953.  
  954. // Create blood
  955. ShowSomeBlood(VictimOrigin)
  956.  
  957. //client_print(owner, print_chat, "===>DAMADE %d<===", damage)
  958. }
  959. else
  960. {
  961. // Silently kill
  962. //user_silentkill(i)
  963.  
  964. // Log this
  965. log_kill(owner, i, "crossbow", 0)
  966.  
  967. // Set new money for killing enemy
  968. if (cs_get_user_team(owner) != cs_get_user_team(i))
  969. cs_set_user_money(owner, cs_get_user_money(owner) + g_killmoney, 1)
  970. // Team kill
  971. else
  972. cs_set_user_money(owner, cs_get_user_money(owner) - g_tkmoney, 1)
  973. }
  974. }
  975. }
  976. set_pev(bolt2, pev_flags, FL_KILLME)
  977. }
  978. }
  979. }
  980.  
  981. // Crossbow dropped
  982. public crossbow_drop(id)
  983. {
  984. // Get aimvec and origin
  985. static Float:flAim[3], Float:flOrigin[3]
  986. VelocityByAim(id, 64, flAim)
  987. entity_get_vector(id, EV_VEC_origin, flOrigin)
  988.  
  989. // Change them a bit
  990. flOrigin[0] += flAim[0]
  991. flOrigin[1] += flAim[1]
  992.  
  993. // New ent
  994. new iEnt = create_entity("info_target")
  995.  
  996. // Classname
  997. entity_set_string(iEnt, EV_SZ_classname, "drop_crossbow")
  998.  
  999. // Origin
  1000. entity_set_origin(iEnt, flOrigin)
  1001.  
  1002. // Model
  1003. entity_set_model(iEnt, W_MODEL)
  1004.  
  1005. // Size
  1006. new Float:mins[3] = {-1.0, -1.0, -1.0}
  1007. new Float:maxs[3] = {1.0, 1.0, 1.0}
  1008. entity_set_vector(iEnt, EV_VEC_mins, mins)
  1009. entity_set_vector(iEnt, EV_VEC_maxs, maxs)
  1010.  
  1011. // Interaction
  1012. entity_set_int(iEnt, EV_INT_solid, SOLID_TRIGGER)
  1013.  
  1014. // Movetype
  1015. entity_set_int(iEnt, EV_INT_movetype, MOVETYPE_TOSS)
  1016.  
  1017. // Vars
  1018. g_hasXbow[id] = false
  1019. g_FullClip[id] = false
  1020. g_bInReload[id] = false
  1021. }
  1022.  
  1023. // Touch
  1024. public crossbow_touch(xbow, id)
  1025. {
  1026. // Prevent invalid ent messages
  1027. if (!is_valid_ent(xbow) || !is_valid_ent(id))
  1028. return PLUGIN_CONTINUE
  1029.  
  1030. // Not allowed to touch
  1031. if (g_hasXbow[id] || user_has_weapon(id, CSW_AWP))
  1032. return PLUGIN_CONTINUE
  1033.  
  1034. // Give crossbow
  1035. give_xbow(id)
  1036.  
  1037. // Remove crossbow on ground
  1038. remove_entity(xbow)
  1039.  
  1040. return PLUGIN_CONTINUE
  1041. }
  1042.  
  1043. // Touch fix
  1044. public touch_fix(id)
  1045. {
  1046. if (g_hasXbow[id])
  1047. g_hasXbow[id] = false
  1048.  
  1049. UpdateHud(id)
  1050. }
  1051.  
  1052. // Change models
  1053. stock ChangeModels(id)
  1054. {
  1055. set_pev(id, pev_viewmodel2, V_MODEL);
  1056. set_pev(id, pev_weaponmodel2, P_MODEL);
  1057. }
  1058.  
  1059. // Play animation(Arkshine)
  1060. stock UTIL_PlayWeaponAnimation(const Player, const Sequence)
  1061. {
  1062. set_pev(Player, pev_weaponanim, Sequence);
  1063.  
  1064. message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player);
  1065. write_byte(Sequence);
  1066. write_byte(pev(Player, pev_body));
  1067. message_end();
  1068. }
  1069.  
  1070. // Update HUD(Arkshine)
  1071. stock UpdateHud(Player)
  1072. {
  1073. // This set clip ammo
  1074. message_begin(MSG_ONE_UNRELIABLE, g_msgCurWeapon, .player = Player);
  1075. write_byte(true);
  1076. write_byte(CSW_AWP);
  1077. write_byte(cs_get_weapon_ammo(get_pdata_cbase(Player, 373)))
  1078. message_end()
  1079.  
  1080. // This set BP ammo
  1081. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoX, .player = Player);
  1082. write_byte(CSW_AWP);
  1083. write_byte(cs_get_user_bpammo(Player, CSW_AWP));
  1084. message_end();
  1085. }
  1086.  
  1087. // Log kill
  1088. stock log_kill(killer, victim, weapon[],headshot)
  1089. {
  1090. set_msg_block(g_msgDeathMsg, BLOCK_SET)
  1091. ExecuteHamB(Ham_Killed, victim, killer, 2)
  1092. set_msg_block(g_msgDeathMsg, BLOCK_NOT)
  1093.  
  1094. message_begin(MSG_ALL, g_msgDeathMsg, {0,0,0}, 0)
  1095. write_byte(killer)
  1096. write_byte(victim)
  1097. write_byte(headshot)
  1098. write_string(weapon)
  1099. message_end()
  1100.  
  1101. new kname[32], kauthid[32], kteam[10]
  1102.  
  1103. get_user_name(killer, kname, 31)
  1104. get_user_team(killer, kteam, 9)
  1105. get_user_authid(killer, kauthid, 31)
  1106.  
  1107. if (killer != victim)
  1108. {
  1109. new vname[32] , vauthid[32], vteam[10]
  1110. get_user_name(victim, vname, 31)
  1111. get_user_team(victim, vteam, 9)
  1112. get_user_authid(victim, vauthid, 31)
  1113.  
  1114. log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"",
  1115. kname, get_user_userid(killer), kauthid, kteam,
  1116. vname, get_user_userid(victim), vauthid, vteam, weapon)
  1117. }
  1118. else
  1119. {
  1120. log_message("^"%s<%d><%s><%s>^" killed self with ^"%s^"",
  1121. kname, get_user_userid(killer), kauthid, kteam, weapon)
  1122. }
  1123.  
  1124. UpdateScore(killer, victim, 0,0, 1)
  1125.  
  1126. return PLUGIN_CONTINUE
  1127. }
  1128.  
  1129. // Allowed toucher
  1130. stock allowed_toucher(player)
  1131. {
  1132. // Already has it
  1133. if (g_hasXbow[player] || user_has_weapon(player, CSW_AWP))
  1134. return false
  1135.  
  1136. return true
  1137. }
  1138.  
  1139. // From WeaponMod
  1140. stock make_knockback(victim, Float:origin[3], Float:maxspeed)
  1141. {
  1142. // Get and set velocity
  1143. new Float:fVelocity[3];
  1144. kickback(victim, origin, maxspeed, fVelocity)
  1145. entity_set_vector(victim, EV_VEC_velocity, fVelocity);
  1146.  
  1147. return (1);
  1148. }
  1149.  
  1150. // Blood!!!
  1151. stock ShowSomeBlood(const Float:origin[3])
  1152. {
  1153. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  1154. write_byte(TE_BLOODSPRITE) // Spr ID
  1155. write_coord(floatround(origin[0]+random_num(-20,20))) // Positions X...
  1156. write_coord(floatround(origin[1]+random_num(-20,20))) // Y
  1157. write_coord(floatround(origin[2]+random_num(-20,20))) // Z
  1158. write_short(sBlood) //
  1159. write_short(sBlood2)
  1160. write_byte(248) // Color
  1161. write_byte(5) // Amount
  1162. message_end()
  1163. }
  1164.  
  1165. // Remove reloading
  1166. public no_reload(id)
  1167. {
  1168. if (g_bInReload[id])
  1169. g_bInReload[id] = false
  1170.  
  1171. }
  1172.  
  1173. // From fakemeta_util.inc(VEN)
  1174. stock bool:fm_strip_user_gun(index, wid = 0, const wname[] = "")
  1175. {
  1176. if (!is_user_alive(index) || !is_user_connected(index))
  1177. return false
  1178.  
  1179. new ent_class[32];
  1180. if (!wid && wname[0])
  1181. copy(ent_class, sizeof ent_class - 1, wname);
  1182. else
  1183. {
  1184. new weapon = wid, clip, ammo;
  1185. if (!weapon && !(weapon = get_user_weapon(index, clip, ammo)))
  1186. return false;
  1187.  
  1188. get_weaponname(weapon, ent_class, sizeof ent_class - 1);
  1189. }
  1190.  
  1191. new ent_weap = find_ent_by_owner(-1, ent_class, index);
  1192. if (!ent_weap)
  1193. return false;
  1194.  
  1195. engclient_cmd(index, "drop", ent_class);
  1196.  
  1197. new ent_box = pev(ent_weap, pev_owner);
  1198. if (!ent_box || ent_box == index)
  1199. return false;
  1200.  
  1201. dllfunc(DLLFunc_Think, ent_box);
  1202.  
  1203. return true;
  1204. }
  1205.  
  1206. // Extra calulation for knockback
  1207. stock kickback(ent, Float:fOrigin[3], Float:fSpeed, Float:fVelocity[3])
  1208. {
  1209. // Find origin
  1210. new Float:fEntOrigin[3];
  1211. entity_get_vector( ent, EV_VEC_origin, fEntOrigin );
  1212.  
  1213. // Do some calculations
  1214. new Float:fDistance[3];
  1215. fDistance[0] = fEntOrigin[0] - fOrigin[0];
  1216. fDistance[1] = fEntOrigin[1] - fOrigin[1];
  1217. fDistance[2] = fEntOrigin[2] - fOrigin[2];
  1218. new Float:fTime = (vector_distance( fEntOrigin,fOrigin ) / fSpeed);
  1219. fVelocity[0] = fDistance[0] / fTime;
  1220. fVelocity[1] = fDistance[1] / fTime;
  1221. fVelocity[2] = fDistance[2] / fTime;
  1222.  
  1223. return (fVelocity[0] && fVelocity[1] && fVelocity[2]);
  1224. }
  1225.  
  1226. // Update score (bugfix)
  1227. stock UpdateScore(attacker, victim, frags, deaths, scoreboard)
  1228. {
  1229. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + frags))
  1230.  
  1231. cs_set_user_deaths(victim, cs_get_user_deaths(victim) + deaths)
  1232.  
  1233. if (scoreboard)
  1234. {
  1235. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  1236. write_byte(attacker) // id
  1237. write_short(pev(attacker, pev_frags)) // frags
  1238. write_short(cs_get_user_deaths(attacker)) // deaths
  1239. write_short(0) // class?
  1240. write_short(get_user_team(attacker)) // team
  1241. message_end()
  1242.  
  1243. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  1244. write_byte(victim) // id
  1245. write_short(pev(victim, pev_frags)) // frags
  1246. write_short(cs_get_user_deaths(victim)) // deaths
  1247. write_short(0) // class?
  1248. write_short(get_user_team(victim)) // team
  1249. message_end()
  1250. }
  1251. }
  1252.  
  1253. // Give crossbow
  1254. stock give_xbow(id)
  1255. {
  1256. // Reset vars
  1257. g_hasXbow[id] = true
  1258. g_FullClip[id] = true
  1259. g_bInReload[id] = false
  1260.  
  1261. // Give awp
  1262. give_item(id, "weapon_awp")
  1263.  
  1264. new ent = find_ent_by_owner(-1, "weapon_awp", id)
  1265. cs_set_weapon_ammo(ent, 5)
  1266.  
  1267. // Set back pack ammo
  1268. cs_set_user_bpammo(id, CSW_AWP, 25)
  1269.  
  1270. // Change models
  1271. ChangeModels(id)
  1272.  
  1273. // Play animation
  1274. UTIL_PlayWeaponAnimation(id, crossbow_draw1)
  1275. }
  1276.  
  1277. /*stock fm_get_weapon_id(index, const weapon[])
  1278. {
  1279. new ent = -1;
  1280.  
  1281. while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", weapon)) != 0)
  1282. {
  1283. if(index == pev(ent, pev_owner))
  1284. return ent;
  1285. }
  1286. return 1;
  1287. }
  1288.  
  1289. stock give_weapon(id, wpnID, ammo, bpammo)
  1290. {
  1291. new weapon[32]
  1292. get_weaponname(wpnID, weapon, 31)
  1293.  
  1294. give_item(id, weapon)
  1295. cs_set_weapon_ammo(fm_get_weapon_id(id, weapon), ammo);
  1296. cs_set_user_bpammo(id, wpnID, cs_get_user_bpammo(id, wpnID) + bpammo)
  1297. }*/
  1298.  
  1299. /* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
  1300. *{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
  1301. */
  1302.