HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. /*
  2. [ZP] Extra cucc: Sokk gránát
  3.  
  4. */
  5.  
  6. #include < amxmodx >
  7. #include < fakemeta >
  8. #include < hamsandwich >
  9. #include < fun >
  10. #include < zombieplague >
  11.  
  12. // Plugin verzió
  13. #define VERSION "1.4"
  14.  
  15. // Defineok
  16. #define MAXPLAYERS 32
  17. #define FCVAR_FLAGS ( FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED )
  18. #define OFFSET_PLAYER 41
  19. #define OFFSET_ACTIVE 373
  20. #define LINUX_DIFF 5
  21. #define NADE_TYPE_CONC 7000
  22. #define FFADE_IN 0x0000
  23. #define REPEAT 0.2 // Idő mire a következő kép elhalványul
  24. #define TASK_AFFECT 666
  25. #define ID_AFFECT ( taskid - TASK_AFFECT )
  26. #define OFFSET_FLAMMO 387
  27.  
  28. // Gránát ára (ammo)
  29. #define GRENADE_COST 15
  30.  
  31. // Gránát modelljei
  32. new const grenade_model_p [ ] = "models/p_grenade_conc.mdl"
  33. new const grenade_model [ ] = "models/v_grenade_conc.mdl"
  34. new const grenade_model_w [ ] = "models/w_grenade_conc.mdl"
  35.  
  36. // Hangok
  37. new const explosion_sound [ ] = "zombie_plague/concgren_blast1.wav"
  38. new const purchase_sound [ ] = "items/gunpickup2.wav"
  39. new const purchase_sound2 [ ] = "items/9mmclip1.wav"
  40.  
  41. // Spriteok
  42. new m_iTrail, m_iRing
  43.  
  44. // Item ID
  45. new g_conc
  46.  
  47. // Játékos variácók
  48. new g_NadeCount [ MAXPLAYERS+1 ]
  49.  
  50. // ID Üzenetek
  51. new g_msgScreenFade, g_msgScreenShake, g_msgAmmoPickup
  52.  
  53. // Cvarok
  54. new cvar_nade_radius, cvar_duration
  55.  
  56. // Precache
  57. public plugin_precache ( )
  58. {
  59. // Precache gránát modellek
  60. precache_model ( grenade_model_p )
  61. precache_model ( grenade_model )
  62. precache_model ( grenade_model_w )
  63.  
  64. // Precache hangok
  65. precache_sound ( explosion_sound )
  66. precache_sound ( purchase_sound )
  67. precache_sound ( purchase_sound2 )
  68.  
  69. // Precache spriteok
  70. m_iRing = precache_model ( "sprites/shockwave.spr" )
  71. m_iTrail = precache_model ( "sprites/laserbeam.spr" )
  72. }
  73.  
  74. // Plugin telepítés
  75. public plugin_init ( )
  76. {
  77. // Új plugin
  78. register_plugin("[ZP] Extra cucc: Sokk gránát", VERSION, "NiHiLaNTh")
  79.  
  80. // Cvar
  81. register_cvar ( "zp_concgren_version", VERSION, FCVAR_FLAGS )
  82.  
  83. // Új extra item
  84. g_conc = zp_register_extra_item ( "Sokk gránát", GRENADE_COST, ZP_TEAM_ZOMBIE )
  85.  
  86. // Eventek
  87. register_event ( "HLTV", "Event_NewRound", "a", "1=0", "2=0" )
  88. register_event ( "DeathMsg", "Event_DeathMsg", "a" )
  89. register_event ( "CurWeapon", "Event_CurrentWeapon", "be", "1=1", "2=25" )
  90.  
  91. // Előljárók
  92. register_forward ( FM_SetModel, "fw_SetModel" )
  93. RegisterHam ( Ham_Think, "grenade", "fw_ThinkGrenade" )
  94. register_forward ( FM_CmdStart, "fw_CmdStart" )
  95.  
  96. // CVARok
  97. cvar_nade_radius = register_cvar ( "zp_conc_nade_radius", "500" ) //Robbanás sugara
  98. cvar_duration = register_cvar ( "zp_conc_nade_duration", "7" ) // Hallucináció idődartama
  99.  
  100. // Üzenetek
  101. g_msgScreenShake = get_user_msgid ( "ScreenShake" )
  102. g_msgScreenFade = get_user_msgid ( "ScreenFade" )
  103. g_msgAmmoPickup = get_user_msgid ( "AmmoPickup" )
  104. }
  105.  
  106. // Someone decided to buy our an extra item
  107. public zp_extra_item_selected ( Player, Item )
  108. {
  109. // This is our grenade
  110. if ( Item == g_conc )
  111. {
  112. // Player already have it
  113. if ( g_NadeCount [ Player ] >= 1 )
  114. {
  115. // Increase nade count
  116. g_NadeCount [ Player ]++
  117.  
  118. // Increase bp ammo
  119. set_pdata_int ( Player, OFFSET_FLAMMO, get_pdata_int ( Player, OFFSET_FLAMMO, LINUX_DIFF )+1, LINUX_DIFF )
  120.  
  121. // Ammo pickup
  122. message_begin ( MSG_ONE, g_msgAmmoPickup, _, Player )
  123. write_byte ( 11 ) // Ammo ID
  124. write_byte ( 1 ) // Ammo amount
  125. message_end ( )
  126.  
  127. // Emit sound
  128. emit_sound ( Player, CHAN_WEAPON, purchase_sound2, VOL_NORM, ATTN_NORM, 0, PITCH_NORM )
  129. }
  130. else // 0 grenades
  131. {
  132. // Increase nade count
  133. g_NadeCount [ Player ] = 1
  134.  
  135. // Give him flashbang
  136. give_item ( Player, "weapon_flashbang" )
  137.  
  138. // Play purchase sound
  139. client_cmd ( Player, "spk %s", purchase_sound )
  140. }
  141. }
  142. return PLUGIN_CONTINUE
  143. }
  144.  
  145. // Someone was infected
  146. public zp_user_infected_post ( Player, Infector )
  147. {
  148. // We were affected by concussion grenade
  149. if ( task_exists ( Player+TASK_AFFECT ) )
  150. remove_task ( Player+TASK_AFFECT )
  151. }
  152.  
  153. // Someone were turned back to human
  154. public zp_user_humanized_post ( Player, Survivor )
  155. {
  156. // We dont' have nade anymore
  157. if ( g_NadeCount [ Player ] )
  158. {
  159. g_NadeCount [ Player ] = 0
  160. }
  161. }
  162.  
  163. // New round started
  164. public Event_NewRound ( )
  165. {
  166. // Reset nade count
  167. arrayset ( g_NadeCount, false, 33 )
  168.  
  169. // And they aren't affected by conc.grenade
  170. remove_task ( TASK_AFFECT )
  171. }
  172.  
  173. // Someone died
  174. public Event_DeathMsg ( )
  175. {
  176. // Get victim
  177. new victim = read_data ( 2 )
  178.  
  179. // Some people had error without this check
  180. if ( !is_user_connected ( victim ) )
  181. return
  182.  
  183. // Remove hallucinations
  184. remove_task ( victim+TASK_AFFECT )
  185.  
  186. // Reset nade count
  187. g_NadeCount [ victim ] = 0
  188. }
  189.  
  190. // Current weapon player is holding
  191. public Event_CurrentWeapon ( Player )
  192. {
  193. // Dead or not zombie or don't have conc. grenade
  194. if ( !is_user_alive ( Player ) || !zp_get_user_zombie ( Player ) || g_NadeCount [ Player ] <= 0 )
  195. return PLUGIN_CONTINUE
  196.  
  197. // Replace flashbang model with our ones
  198. set_pev ( Player, pev_viewmodel2, grenade_model )
  199. set_pev ( Player, pev_weaponmodel2, grenade_model_p )
  200.  
  201. return PLUGIN_CONTINUE
  202. }
  203.  
  204. // Set model
  205. public fw_SetModel ( Entity, const Model [ ] )
  206. {
  207. // Prevent invalid ent messages
  208. if ( !pev_valid ( Entity ) )
  209. return FMRES_IGNORED
  210.  
  211. // Grenade not thrown yet
  212. if ( pev ( Entity, pev_dmgtime ) == 0.0 )
  213. return FMRES_IGNORED
  214.  
  215. // We are throwing concussion grenade
  216. if ( g_NadeCount [ pev ( Entity, pev_owner ) ] >= 1 && equal ( Model [7 ], "w_fl", 4 ) )
  217. {
  218. //Draw trail
  219. message_begin ( MSG_BROADCAST, SVC_TEMPENTITY )
  220. write_byte ( TE_BEAMFOLLOW ) // Temp entity ID
  221. write_short ( Entity ) // Entity to follow
  222. write_short ( m_iTrail ) // Sprite index
  223. write_byte ( 10 ) // Life
  224. write_byte ( 10 ) // Line width
  225. write_byte ( 255 ) // Red amount
  226. write_byte ( 255 ) // Blue amount
  227. write_byte ( 0 ) // Blue amount
  228. write_byte ( 255 ) // Alpha
  229. message_end ( )
  230.  
  231. // Set grenade entity
  232. set_pev ( Entity, pev_flTimeStepSound, NADE_TYPE_CONC )
  233.  
  234. // Decrease nade count
  235. g_NadeCount [ pev ( Entity, pev_owner ) ]--
  236.  
  237. // Set world model
  238. engfunc ( EngFunc_SetModel, Entity, grenade_model_w )
  239. return FMRES_SUPERCEDE
  240. }
  241. return FMRES_IGNORED
  242. }
  243.  
  244. // Grenade is getting to explode
  245. public fw_ThinkGrenade ( Entity )
  246. {
  247. // Prevent invalid ent messages
  248. if ( !pev_valid ( Entity ) )
  249. return HAM_IGNORED
  250.  
  251. // Get damage time
  252. static Float:dmg_time
  253. pev ( Entity, pev_dmgtime, dmg_time )
  254.  
  255. // maybe it is time to go off
  256. if ( dmg_time > get_gametime ( ) )
  257. return HAM_IGNORED
  258.  
  259. // Our grenade
  260. if ( pev ( Entity, pev_flTimeStepSound ) == NADE_TYPE_CONC )
  261. {
  262. // Force to explode
  263. concussion_explode ( Entity )
  264. return HAM_SUPERCEDE
  265. }
  266. return HAM_IGNORED
  267. }
  268.  
  269. // Command start
  270. public fw_CmdStart ( Player, UC_Handle, Seed )
  271. {
  272. // Dead, zombie or not affected
  273. if ( !is_user_alive ( Player ) || zp_get_user_zombie ( Player ) || !task_exists ( Player+TASK_AFFECT ) )
  274. return FMRES_IGNORED
  275.  
  276. // Get buttons
  277. new buttons = get_uc ( UC_Handle, UC_Buttons )
  278.  
  279. // We are firing
  280. if ( buttons & IN_ATTACK )
  281. {
  282. // We are holding an active weapon
  283. if ( get_pdata_cbase ( Player, OFFSET_ACTIVE, LINUX_DIFF ) )
  284. {
  285. // New recoil
  286. set_pev ( Player, pev_punchangle, Float:{3.0, 3.0, 4.0} )
  287. }
  288. }
  289. return FMRES_HANDLED
  290. }
  291.  
  292.  
  293. // Grenade explode
  294. public concussion_explode ( Entity )
  295. {
  296. // Invalid entity ?
  297. if ( !pev_valid ( Entity ) )
  298. return
  299.  
  300. // Get entities origin
  301. static Float:origin [ 3 ]
  302. pev ( Entity, pev_origin, origin )
  303.  
  304. // Draw ring
  305. UTIL_DrawRing (origin )
  306.  
  307. // Explosion sound
  308. emit_sound ( Entity, CHAN_WEAPON, explosion_sound, VOL_NORM, ATTN_NORM, 0, PITCH_NORM )
  309.  
  310. // Collisions
  311. static victim
  312. victim = -1
  313.  
  314. // Find radius
  315. static Float:radius
  316. radius = get_pcvar_float ( cvar_nade_radius )
  317.  
  318. // Find all players in a radius
  319. while ( ( victim = engfunc ( EngFunc_FindEntityInSphere, victim, origin, radius ) ) != 0 )
  320. {
  321. // Dead or zombie
  322. if ( !is_user_alive ( victim ) || zp_get_user_zombie ( victim ) )
  323. continue
  324.  
  325. // Victim isn't affected yet
  326. if ( !task_exists ( victim+TASK_AFFECT ) )
  327. {
  328. // Get duration
  329. new duration = get_pcvar_num ( cvar_duration )
  330.  
  331. // Calculate affect times
  332. new affect_count = floatround ( duration / REPEAT )
  333.  
  334. // Continiously affect them
  335. set_task ( REPEAT, "affect_victim", victim+TASK_AFFECT, _, _, "a", affect_count )
  336. }
  337. }
  338.  
  339. // Remove entity from ground
  340. engfunc ( EngFunc_RemoveEntity, Entity )
  341. }
  342.  
  343. // We are going to affect you
  344. public affect_victim ( taskid )
  345. {
  346. // Dead
  347. if ( !is_user_alive ( ID_AFFECT ) )
  348. return
  349.  
  350. // Make a screen fade
  351. message_begin ( MSG_ONE_UNRELIABLE, g_msgScreenFade, {0,0,0}, ID_AFFECT )
  352. write_short ( 1<<13 ) // Duration
  353. write_short ( 1<<14 ) // Hold Time
  354. write_short ( FFADE_IN ) // Fade type
  355. write_byte ( random_num ( 50, 200 ) ) // Red amount
  356. write_byte ( random_num ( 50, 200 ) ) // Green amount
  357. write_byte ( random_num ( 50, 200 ) ) // Blue amount
  358. write_byte ( random_num ( 50, 200 ) ) // Alpha
  359. message_end ( )
  360.  
  361. // Make a screen shake
  362. message_begin ( MSG_ONE_UNRELIABLE, g_msgScreenShake, {0,0,0}, ID_AFFECT )
  363. write_short ( 0xFFFF ) // Amplitude
  364. write_short ( 1<<13 ) // Duration
  365. write_short ( 0xFFFF ) // Frequency
  366. message_end ( )
  367.  
  368. // Remove task after all
  369. remove_task ( ID_AFFECT )
  370. }
  371.  
  372. // Draw explosion ring ( from zombie_plague40.sma )
  373. stock UTIL_DrawRing ( const Float:origin [ 3 ] )
  374. {
  375. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
  376. write_byte(TE_BEAMCYLINDER) // TE id
  377. engfunc(EngFunc_WriteCoord, origin[0]) // x
  378. engfunc(EngFunc_WriteCoord, origin[1]) // y
  379. engfunc(EngFunc_WriteCoord, origin[2]) // z
  380. engfunc(EngFunc_WriteCoord, origin[0]) // x axis
  381. engfunc(EngFunc_WriteCoord, origin[1]) // y axis
  382. engfunc(EngFunc_WriteCoord, origin[2]+555.0) // z axis
  383. write_short( m_iRing ) // sprite
  384. write_byte(0) // startframe
  385. write_byte(0) // framerate
  386. write_byte(4) // life
  387. write_byte(60) // width
  388. write_byte(0) // noise
  389. write_byte(200) // red
  390. write_byte(200) // green
  391. write_byte(200) // blue
  392. write_byte(200) // brightness
  393. write_byte(0) // speed
  394. message_end()
  395. }
  396. /* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
  397. *{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
  398. */
  399.