Advertisement
Guest User

Untitled

a guest
Nov 1st, 2018
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.18 KB | None | 0 0
  1. #include <amxmodx>
  2. #include <cstrike>
  3. #include <fakemeta>
  4. #include <fun>
  5. #include <hamsandwich>
  6.  
  7. new const VERSION[] = "2.14";
  8.  
  9. #define message_begin_fl(%1,%2,%3,%4) engfunc(EngFunc_MessageBegin, %1, %2, %3, %4)
  10. #define write_coord_fl(%1) engfunc(EngFunc_WriteCoord, %1)
  11.  
  12. #define m_pPlayer 41
  13. #define m_pActiveItem 373
  14. #define m_flFlashedUntil 514
  15. #define m_flFlashHoldTime 517
  16. #define OFFSET_WEAPON_CSWID 43
  17. #define Ham_Player_ResetMaxSpeed Ham_Item_PreFrame
  18.  
  19. #define MAX_WEAPONS 32
  20. #define AMMO_FLASHBANG 11
  21. #define AMMO_HEGRENADE 12
  22. #define AMMO_SMOKEGRENADE 13
  23. #define DMG_GRENADE (1<<24) // thanks arkshine
  24. #define FFADE_IN 0x0000 // just here so we don't pass 0 into the function
  25. #define BREAK_GLASS 0x01
  26. #define STATUS_HIDE 0
  27. #define STATUS_SHOW 1
  28. #define STATUS_FLASH 2
  29.  
  30. #define GLOW_AMOUNT 1.0
  31. #define FROST_RADIUS 240.0
  32.  
  33. #define NT_FLASHBANG (1<<0) // 1; CSW:25
  34. #define NT_HEGRENADE (1<<1) // 2; CSW:4
  35. #define NT_SMOKEGRENADE (1<<2) // 4; CSW:9
  36.  
  37. new const GRENADE_NAMES[][] = {
  38. "weapon_hegrenade",
  39. "weapon_flashbang",
  40. "weapon_smokegrenade"
  41. };
  42.  
  43. #define ICON_HASNADE 1
  44. #define ICON_ISCHILLED 2
  45.  
  46. #define TASK_REMOVE_CHILL 100
  47. #define TASK_REMOVE_FREEZE 200
  48.  
  49. new const MODEL_FROZEN[] = "models/pi_shrub.mdl";
  50. new const MODEL_GLASSGIBS[] = "models/glassgibs.mdl";
  51.  
  52. new const SOUND_EXPLODE[] = "x/x_shoot1.wav";
  53. new const SOUND_FROZEN[] = "debris/glass1.wav";
  54. new const SOUND_UNFROZEN[] = "debris/glass3.wav";
  55. new const SOUND_CHILLED[] = "player/pl_duct2.wav";
  56. new const SOUND_PICKUP[] = "items/gunpickup2.wav";
  57.  
  58. new const SPRITE_TRAIL[] = "sprites/laserbeam.spr";
  59. new const SPRITE_SMOKE[] = "sprites/steam1.spr";
  60. new const SPRITE_EXPLO[] = "sprites/shockwave.spr";
  61.  
  62. new pcv_enabled, pcv_override, pcv_nadetypes, pcv_teams, pcv_price, pcv_limit, pcv_buyzone, pcv_color, pcv_icon,
  63. pcv_by_radius, pcv_hitself, pcv_los, pcv_maxdamage, pcv_mindamage, pcv_chill_maxchance, pcv_chill_minchance,
  64. pcv_chill_duration, pcv_chill_variance, pcv_chill_speed, pcv_freeze_maxchance, pcv_freeze_minchance,
  65. pcv_freeze_duration, pcv_freeze_variance;
  66.  
  67. new maxPlayers, gmsgScreenFade, gmsgStatusIcon, gmsgBlinkAcct, gmsgAmmoPickup, gmsgTextMsg,
  68. gmsgWeapPickup, glassGibs, trailSpr, smokeSpr, exploSpr, mp_friendlyfire, czero, bot_quota, czBotHams, fmFwdPPT,
  69. fnFwdPlayerChilled, fnFwdPlayerFrozen, bool:roundRestarting;
  70.  
  71. new isChilled[33], isFrozen[33], frostKilled[33], novaDisplay[33], Float:glowColor[33][3], Float:oldGravity[33], oldRenderFx[33],
  72. Float:oldRenderColor[33][3], oldRenderMode[33], Float:oldRenderAmt[33], hasFrostNade[33], nadesBought[33];
  73.  
  74. public plugin_init()
  75. {
  76. register_plugin("FrostNades",VERSION,"Avalanche");
  77. register_cvar("fn_version",VERSION,FCVAR_SERVER);
  78.  
  79. pcv_enabled = register_cvar("fn_enabled","1");
  80. pcv_override = register_cvar("fn_override","1");
  81. pcv_nadetypes = register_cvar("fn_nadetypes","4"); // NT_SMOKEGRENADE
  82. pcv_teams = register_cvar("fn_teams","3");
  83. pcv_price = register_cvar("fn_price","300");
  84. pcv_icon = register_cvar("fn_icon","1");
  85. pcv_limit = register_cvar("fn_limit","0");
  86. pcv_buyzone = register_cvar("fn_buyzone","1");
  87. pcv_color = register_cvar("fn_color","0 206 209");
  88.  
  89. pcv_by_radius = register_cvar("fn_by_radius","0.0");
  90. pcv_hitself = register_cvar("fn_hitself","1");
  91. pcv_los = register_cvar("fn_los","1");
  92. pcv_maxdamage = register_cvar("fn_maxdamage","20.0");
  93. pcv_mindamage = register_cvar("fn_mindamage","1.0");
  94. pcv_chill_maxchance = register_cvar("fn_chill_maxchance","100.0");
  95. pcv_chill_minchance = register_cvar("fn_chill_minchance","100.0");
  96. pcv_chill_duration = register_cvar("fn_chill_duration","7.0");
  97. pcv_chill_variance = register_cvar("fn_chill_variance","1.0");
  98. pcv_chill_speed = register_cvar("fn_chill_speed","60.0");
  99. pcv_freeze_maxchance = register_cvar("fn_freeze_maxchance","110.0");
  100. pcv_freeze_minchance = register_cvar("fn_freeze_minchance","40.0");
  101. pcv_freeze_duration = register_cvar("fn_freeze_duration","4.0");
  102. pcv_freeze_variance = register_cvar("fn_freeze_variance","0.5");
  103.  
  104. mp_friendlyfire = get_cvar_pointer("mp_friendlyfire");
  105.  
  106. new mod[6];
  107. get_modname(mod,5);
  108. if(equal(mod,"czero"))
  109. {
  110. czero = 1;
  111. bot_quota = get_cvar_pointer("bot_quota");
  112. }
  113.  
  114. maxPlayers = get_maxplayers();
  115. gmsgScreenFade = get_user_msgid("ScreenFade");
  116. gmsgStatusIcon = get_user_msgid("StatusIcon");
  117. gmsgBlinkAcct = get_user_msgid("BlinkAcct");
  118. gmsgAmmoPickup = get_user_msgid("AmmoPickup");
  119. gmsgWeapPickup = get_user_msgid("WeapPickup");
  120. gmsgTextMsg = get_user_msgid("TextMsg");
  121.  
  122. register_forward(FM_SetModel,"fw_setmodel",1);
  123. register_message(get_user_msgid("DeathMsg"),"msg_deathmsg");
  124.  
  125. register_event("ResetHUD", "event_resethud", "b");
  126. register_event("TextMsg", "event_round_restart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
  127. register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
  128.  
  129. RegisterHam(Ham_Spawn,"player","ham_player_spawn",1);
  130. RegisterHam(Ham_Killed,"player","ham_player_killed",1);
  131. RegisterHam(Ham_Player_ResetMaxSpeed,"player","ham_player_resetmaxspeed",1);
  132. RegisterHam(Ham_Think,"grenade","ham_grenade_think",0);
  133. RegisterHam(Ham_Use, "player_weaponstrip", "ham_player_weaponstrip_use", 1);
  134.  
  135. for(new i=0; i<sizeof GRENADE_NAMES; i++)
  136. {
  137. RegisterHam(Ham_Item_Deploy, GRENADE_NAMES[i], "ham_grenade_deploy", 1);
  138. RegisterHam(Ham_Item_Holster, GRENADE_NAMES[i], "ham_grenade_holster", 1);
  139. RegisterHam(Ham_Item_AddToPlayer, GRENADE_NAMES[i], "ham_grenade_addtoplayer", 1);
  140. RegisterHam(Ham_Item_AddDuplicate, GRENADE_NAMES[i], "ham_grenade_addduplicate", 1);
  141. }
  142.  
  143. register_clcmd("say /fn","buy_frostnade");
  144. register_clcmd("say_team /fn","buy_frostnade");
  145. register_clcmd("say /frostnade","buy_frostnade");
  146. register_clcmd("say_team /frostnade","buy_frostnade");
  147.  
  148. fnFwdPlayerChilled = CreateMultiForward("frostnades_player_chilled", ET_STOP, FP_CELL, FP_CELL);
  149. fnFwdPlayerFrozen = CreateMultiForward("frostnades_player_frozen", ET_STOP, FP_CELL, FP_CELL);
  150. }
  151.  
  152. public plugin_end()
  153. {
  154. DestroyForward(fnFwdPlayerChilled);
  155. DestroyForward(fnFwdPlayerFrozen);
  156. }
  157.  
  158. public plugin_precache()
  159. {
  160. precache_model(MODEL_FROZEN);
  161. glassGibs = precache_model(MODEL_GLASSGIBS);
  162.  
  163. precache_sound(SOUND_EXPLODE); // grenade explodes
  164. precache_sound(SOUND_FROZEN); // player is frozen
  165. precache_sound(SOUND_UNFROZEN); // frozen wears off
  166. precache_sound(SOUND_CHILLED); // player is chilled
  167. precache_sound(SOUND_PICKUP); // player buys frostnade
  168.  
  169. trailSpr = precache_model(SPRITE_TRAIL);
  170. smokeSpr = precache_model(SPRITE_SMOKE);
  171. exploSpr = precache_model(SPRITE_EXPLO);
  172. }
  173.  
  174. public client_putinserver(id)
  175. {
  176. isChilled[id] = 0;
  177. isFrozen[id] = 0;
  178. frostKilled[id] = 0;
  179. novaDisplay[id] = 0;
  180. hasFrostNade[id] = 0;
  181.  
  182. if(czero && !czBotHams && is_user_bot(id) && get_pcvar_num(bot_quota) > 0)
  183. set_task(0.1,"czbot_hook_ham",id);
  184. }
  185.  
  186. public client_disconnect(id)
  187. {
  188. if(isChilled[id]) task_remove_chill(TASK_REMOVE_CHILL+id);
  189. if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
  190. }
  191.  
  192. // registering a ham hook for "player" won't register it for CZ bots,
  193. // for some reason. so we have to register it by entity.
  194. public czbot_hook_ham(id)
  195. {
  196. if(!czBotHams && is_user_connected(id) && is_user_bot(id) && get_pcvar_num(bot_quota) > 0)
  197. {
  198. RegisterHamFromEntity(Ham_Spawn,id,"ham_player_spawn",1);
  199. RegisterHamFromEntity(Ham_Killed,id,"ham_player_killed",1);
  200. RegisterHamFromEntity(Ham_Player_ResetMaxSpeed,id,"ham_player_resetmaxspeed",1);
  201. czBotHams = 1;
  202. }
  203. }
  204.  
  205. // intercept server log messages to replace grenade kills with frostgrenade kills
  206. public plugin_log()
  207. {
  208. static arg[512];
  209.  
  210. if(get_pcvar_num(pcv_enabled) && read_logargc() >= 5)
  211. {
  212. read_logargv(1, arg, 7); // "killed"
  213.  
  214. if(equal(arg, "killed"))
  215. {
  216. read_logargv(2, arg, 127); // info of player that was killed
  217.  
  218. // get ID of player that was killed
  219. new dummy[1], killedUserId;
  220. parse_loguser(arg, dummy, 0, killedUserId);
  221. new killedId = find_player("k", killedUserId);
  222.  
  223. if(killedId && frostKilled[killedId])
  224. {
  225. // override with frostgrenade message
  226. read_logdata(arg, 511);
  227. replace(arg, 511, "with ^"grenade^"", "with ^"frostgrenade^"");
  228. log_message("%s", arg);
  229.  
  230. return PLUGIN_HANDLED;
  231. }
  232. }
  233. }
  234.  
  235. return PLUGIN_CONTINUE;
  236. }
  237.  
  238. /****************************************
  239. * PRIMARY FUNCTIONS AND SUCH
  240. ****************************************/
  241.  
  242. public buy_frostnade(id)
  243. {
  244. if(!get_pcvar_num(pcv_enabled) || get_pcvar_num(pcv_override))
  245. return PLUGIN_CONTINUE;
  246.  
  247. if(!is_user_alive(id)) return PLUGIN_HANDLED;
  248.  
  249. if(get_pcvar_num(pcv_buyzone) && !cs_get_user_buyzone(id))
  250. {
  251. // #Cstrike_NotInBuyZone won't work for some reason
  252. client_print(id,print_center,"You are not in a buy zone.");
  253.  
  254. return PLUGIN_HANDLED;
  255. }
  256.  
  257. if(!(get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)))
  258. {
  259. // have to do it this way to format
  260. message_begin(MSG_ONE,gmsgTextMsg,_,id);
  261. write_byte(print_center);
  262. write_string("#Alias_Not_Avail");
  263. write_string("Frost Grenade");
  264. message_end();
  265.  
  266. return PLUGIN_HANDLED;
  267. }
  268.  
  269. if(hasFrostNade[id])
  270. {
  271. client_print(id,print_center,"#Cstrike_Already_Own_Weapon");
  272. return PLUGIN_HANDLED;
  273. }
  274.  
  275. new limit = get_pcvar_num(pcv_limit);
  276. if(limit && nadesBought[id] >= limit)
  277. {
  278. client_print(id,print_center,"#Cstrike_TitlesTXT_Cannot_Carry_Anymore");
  279. return PLUGIN_HANDLED;
  280. }
  281.  
  282. new money = cs_get_user_money(id), price = get_pcvar_num(pcv_price);
  283.  
  284. // need more vespene gas
  285. if(money < price)
  286. {
  287. client_print(id,print_center,"#Cstrike_TitlesTXT_Not_Enough_Money");
  288.  
  289. message_begin(MSG_ONE_UNRELIABLE,gmsgBlinkAcct,_,id);
  290. write_byte(2);
  291. message_end();
  292.  
  293. return PLUGIN_HANDLED;
  294. }
  295.  
  296. // try to use smokegrenade, then flashbang, then hegrenade
  297. new wpnid = CSW_SMOKEGRENADE, ammoid = AMMO_SMOKEGRENADE, wpnName[20] = "weapon_smokegrenade", type = get_pcvar_num(pcv_nadetypes);
  298. if(!(type & NT_SMOKEGRENADE))
  299. {
  300. if(type & NT_FLASHBANG)
  301. {
  302. wpnid = CSW_FLASHBANG;
  303. ammoid = AMMO_FLASHBANG;
  304. wpnName = "weapon_flashbang";
  305. }
  306. else if(type & NT_HEGRENADE)
  307. {
  308. wpnid = CSW_HEGRENADE;
  309. ammoid = AMMO_HEGRENADE;
  310. wpnName = "weapon_hegrenade";
  311. }
  312. }
  313.  
  314. hasFrostNade[id] = wpnid;
  315. nadesBought[id]++;
  316. cs_set_user_money(id,money - price);
  317.  
  318. new ammo = cs_get_user_bpammo(id,wpnid);
  319.  
  320. // give him one
  321. if(!ammo) give_item(id,wpnName);
  322. else
  323. {
  324. cs_set_user_bpammo(id,wpnid,ammo+1);
  325.  
  326. // just so the player can see what kind it is on his HUD
  327.  
  328. message_begin(MSG_ONE,gmsgAmmoPickup,_,id);
  329. write_byte(ammoid);
  330. write_byte(ammo+1);
  331. message_end();
  332.  
  333. message_begin(MSG_ONE,gmsgWeapPickup,_,id);
  334. write_byte(wpnid);
  335. message_end();
  336.  
  337. // won't play via cs_set_user_bpammo
  338. engfunc(EngFunc_EmitSound,id,CHAN_ITEM,SOUND_PICKUP,VOL_NORM,ATTN_NORM,0,PITCH_NORM);
  339.  
  340. // for icon management
  341. grenade_added(id, wpnid);
  342. }
  343.  
  344. return PLUGIN_HANDLED;
  345. }
  346.  
  347. // entity is given a model (used to detect for thrown grenades)
  348. public fw_setmodel(ent,model[])
  349. {
  350. if(!get_pcvar_num(pcv_enabled)) return FMRES_IGNORED;
  351.  
  352. new owner = pev(ent,pev_owner);
  353. if(!is_user_connected(owner)) return FMRES_IGNORED;
  354.  
  355. // this isn't going to explode
  356. new Float:dmgtime;
  357. pev(ent,pev_dmgtime,dmgtime);
  358. if(dmgtime == 0.0) return FMRES_IGNORED;
  359.  
  360. new type, csw;
  361. if(model[7] == 'w' && model[8] == '_')
  362. {
  363. switch(model[9])
  364. {
  365. case 'h': { type = NT_HEGRENADE; csw = CSW_HEGRENADE; }
  366. case 'f': { type = NT_FLASHBANG; csw = CSW_FLASHBANG; }
  367. case 's': { type = NT_SMOKEGRENADE; csw = CSW_SMOKEGRENADE; }
  368. }
  369. }
  370. if(!type) return FMRES_IGNORED;
  371.  
  372. new team = _:cs_get_user_team(owner);
  373.  
  374. // have a frostnade (override off) ;OR; override enabled, on valid team, using valid frostnade type
  375. if(hasFrostNade[owner] == csw || (get_pcvar_num(pcv_override)
  376. && (get_pcvar_num(pcv_teams) & team) && (get_pcvar_num(pcv_nadetypes) & type)))
  377. {
  378. // not using override
  379. if(hasFrostNade[owner] == csw)
  380. {
  381. hasFrostNade[owner] = 0;
  382. if(get_pcvar_num(pcv_icon) == ICON_HASNADE)
  383. {
  384. show_icon(owner, STATUS_HIDE);
  385. }
  386. }
  387.  
  388. set_pev(ent,pev_team,team);
  389. set_pev(ent,pev_bInDuck,1); // flag it as a frostnade
  390.  
  391. new rgb[3], Float:rgbF[3];
  392. get_rgb_colors(team,rgb);
  393. IVecFVec(rgb, rgbF);
  394.  
  395. // glowshell
  396. set_pev(ent,pev_rendermode,kRenderNormal);
  397. set_pev(ent,pev_renderfx,kRenderFxGlowShell);
  398. set_pev(ent,pev_rendercolor,rgbF);
  399. set_pev(ent,pev_renderamt,16.0);
  400.  
  401. set_beamfollow(ent,10,10,rgb,100);
  402. }
  403.  
  404. return FMRES_IGNORED;
  405. }
  406.  
  407. // freeze a player in place whilst he's frozen
  408. public fw_playerprethink(id)
  409. {
  410. /*if(isChilled[id])
  411. {
  412. // remember rendering changes
  413. new fx = pev(id,pev_renderfx), Float:color[3], mode = pev(id,pev_rendermode), Float:amount;
  414. pev(id,pev_rendercolor,color);
  415. pev(id,pev_renderamt,amount);
  416.  
  417. if(fx != kRenderFxGlowShell)
  418. {
  419. oldRenderFx[id] = fx;
  420. set_pev(id,pev_renderfx,kRenderFxGlowShell);
  421. }
  422. if(color[0] != glowColor[id][0] || color[1] != glowColor[id][1] || color[2] != glowColor[id][2])
  423. {
  424. oldRenderColor[id] = color;
  425. set_pev(id,pev_rendercolor,glowColor[id]);
  426. }
  427. if(mode != kRenderNormal)
  428. {
  429. oldRenderMode[id] = mode;
  430. set_pev(id,pev_rendermode,kRenderNormal);
  431. }
  432. if(amount != GLOW_AMOUNT)
  433. {
  434. oldRenderAmt[id] = amount;
  435. set_pev(id,pev_renderamt,GLOW_AMOUNT);
  436. }
  437. }*/
  438.  
  439. if(isFrozen[id])
  440. {
  441. set_pev(id,pev_velocity,Float:{0.0,0.0,0.0}); // stop motion
  442.  
  443. new Float:gravity;
  444. pev(id,pev_gravity,gravity);
  445.  
  446. // remember any gravity changes
  447. if(gravity != 0.000000001 && gravity != 999999999.9)
  448. oldGravity[id] = gravity;
  449.  
  450. // if are on the ground and about to jump, set the gravity too high to really do so
  451. if((pev(id,pev_button) & IN_JUMP) && !(pev(id,pev_oldbuttons) & IN_JUMP) && (pev(id,pev_flags) & FL_ONGROUND))
  452. set_pev(id,pev_gravity,999999999.9);
  453.  
  454. // otherwise, set the gravity so low that they don't fall
  455. else set_pev(id,pev_gravity,0.000000001);
  456. }
  457.  
  458. return FMRES_IGNORED;
  459. }
  460.  
  461. // override grenade kill message with skull and crossbones
  462. public msg_deathmsg(msg_id,msg_dest,msg_entity)
  463. {
  464. new victim = get_msg_arg_int(2);
  465. if(!is_user_connected(victim) || !frostKilled[victim]) return PLUGIN_CONTINUE;
  466.  
  467. static weapon[8];
  468. get_msg_arg_string(4,weapon,7);
  469. if(equal(weapon,"grenade")) set_msg_arg_string(4,"frostgrenade");
  470.  
  471. //frostKilled[victim] = 0;
  472. return PLUGIN_CONTINUE;
  473. }
  474.  
  475. // catch HUD reset to re-display icon if necessary
  476. public event_resethud(id)
  477. {
  478. if(!is_user_alive(id) || !get_pcvar_num(pcv_enabled)) return;
  479.  
  480. if(get_pcvar_num(pcv_icon) == ICON_HASNADE)
  481. {
  482. new status = player_has_frostnade(id);
  483. show_icon(id, status);
  484. }
  485.  
  486. return;
  487. }
  488.  
  489. // round is restarting (TAG: sv_restartround)
  490. public event_round_restart()
  491. {
  492. // just remember for event_new_round
  493. roundRestarting = true;
  494. }
  495.  
  496. // start of a new round
  497. public event_new_round()
  498. {
  499. if(roundRestarting)
  500. {
  501. roundRestarting = false;
  502.  
  503. // clear frost grenades from all players (for override mode)
  504. for(new i=1;i<=maxPlayers;i++)
  505. {
  506. hasFrostNade[i] = 0;
  507. }
  508. }
  509. }
  510.  
  511. // rezzed
  512. public ham_player_spawn(id)
  513. {
  514. nadesBought[id] = 0;
  515.  
  516. if(is_user_alive(id))
  517. {
  518. if(isChilled[id]) task_remove_chill(TASK_REMOVE_CHILL+id);
  519. if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
  520. }
  521.  
  522. return HAM_IGNORED;
  523. }
  524.  
  525. // killed to death
  526. public ham_player_killed(id)
  527. {
  528. hasFrostNade[id] = 0;
  529.  
  530. if(get_pcvar_num(pcv_enabled) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
  531. {
  532. show_icon(id, STATUS_HIDE);
  533. }
  534.  
  535. if(isChilled[id]) task_remove_chill(TASK_REMOVE_CHILL+id);
  536. if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
  537.  
  538. return HAM_IGNORED;
  539. }
  540.  
  541. // movement speed is changed
  542. public ham_player_resetmaxspeed(id)
  543. {
  544. if(get_pcvar_num(pcv_enabled))
  545. {
  546. set_user_chillfreeze_speed(id);
  547. }
  548.  
  549. return HAM_IGNORED;
  550. }
  551.  
  552. // grenade is ticking away
  553. public ham_grenade_think(ent)
  554. {
  555. // not a frostnade
  556. if(!pev_valid(ent) || !pev(ent,pev_bInDuck)) return HAM_IGNORED;
  557.  
  558. new Float:dmgtime;
  559. pev(ent,pev_dmgtime,dmgtime);
  560. if(dmgtime > get_gametime()) return HAM_IGNORED;
  561.  
  562. // and boom goes the dynamite
  563. frostnade_explode(ent);
  564.  
  565. return HAM_SUPERCEDE;
  566. }
  567.  
  568. // a player_weaponstrip is used
  569. public ham_player_weaponstrip_use(ent, idcaller, idactivator, use_type, Float:value)
  570. {
  571. if(idcaller >= 1 && idcaller <= maxPlayers)
  572. {
  573. // clear frostnade when using override
  574. hasFrostNade[idcaller] = 0;
  575.  
  576. if(is_user_alive(idcaller) && get_pcvar_num(pcv_enabled) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
  577. {
  578. new status = player_has_frostnade(idcaller);
  579. show_icon(idcaller, status);
  580. }
  581. }
  582.  
  583. return HAM_IGNORED;
  584. }
  585.  
  586. // some kind of grenade is deployed
  587. public ham_grenade_deploy(ent)
  588. {
  589. if(pev_valid(ent))
  590. {
  591. grenade_deployed(get_pdata_cbase(ent, m_pPlayer, 4),
  592. get_pdata_int(ent, OFFSET_WEAPON_CSWID, 4));
  593. }
  594.  
  595. return HAM_IGNORED;
  596. }
  597.  
  598. // some kind of grenade is holstered
  599. public ham_grenade_holster(ent)
  600. {
  601. if(pev_valid(ent))
  602. {
  603. grenade_holstered(get_pdata_cbase(ent, m_pPlayer, 4),
  604. get_pdata_int(ent, OFFSET_WEAPON_CSWID, 4));
  605. }
  606.  
  607. return HAM_IGNORED;
  608. }
  609.  
  610. // some kind of grenade is added to a player's inventory
  611. public ham_grenade_addtoplayer(ent, id)
  612. {
  613. if(pev_valid(ent))
  614. {
  615. grenade_added(id, get_pdata_int(ent, OFFSET_WEAPON_CSWID, 4));
  616. }
  617.  
  618. return HAM_IGNORED;
  619. }
  620.  
  621. // some kind of grenade is added to a player's inventory, when he already has one
  622. public ham_grenade_addduplicate(ent, orig)
  623. {
  624. if(pev_valid(orig))
  625. {
  626. grenade_added(pev(orig, pev_owner), get_pdata_int(orig, OFFSET_WEAPON_CSWID, 4));
  627. }
  628.  
  629. return HAM_IGNORED;
  630. }
  631.  
  632. // handle when player id deploys a grenade with weapon id wid
  633. grenade_deployed(id, wid)
  634. {
  635. // if we should worry about managing my icon now
  636. if(get_pcvar_num(pcv_enabled) && is_user_alive(id) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
  637. {
  638. // if I just switched to a frost grenade
  639. if( wid == hasFrostNade[id]
  640. || (get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)) && is_wid_in_nadetypes(wid)) )
  641. {
  642. show_icon(id, STATUS_FLASH);
  643. }
  644. }
  645. }
  646.  
  647. // handle when player id holsters a grenade with weapon id wid
  648. grenade_holstered(id, wid)
  649. {
  650. // if we should worry about managing my icon now
  651. if(get_pcvar_num(pcv_enabled) && is_user_alive(id) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
  652. {
  653. // if I just holstered a frost grenade
  654. if( wid == hasFrostNade[id]
  655. || (get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)) && is_wid_in_nadetypes(wid)) )
  656. {
  657. // only do STATUS_SHOW or STATUS_HIDE... during holster, current weapon
  658. // will still technically be the frost grenade, but we don't want to
  659. // mistakenly flash the icon
  660. new status = (player_has_frostnade(id) != STATUS_HIDE ? STATUS_SHOW : STATUS_HIDE);
  661. show_icon(id, status);
  662. }
  663. }
  664. }
  665.  
  666. // handle when player id gets a grenade with weapon id wid added to his inventory
  667. grenade_added(id, wid)
  668. {
  669. // if we should worry about managing my icon now
  670. if(get_pcvar_num(pcv_enabled) && is_user_alive(id) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
  671. {
  672. // if I just got a frost grenade
  673. if( wid == hasFrostNade[id]
  674. || (get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)) && is_wid_in_nadetypes(wid)) )
  675. {
  676. new status = player_has_frostnade(id);
  677. show_icon(id, status);
  678. }
  679. }
  680. }
  681.  
  682. // a frost grenade explodes
  683. public frostnade_explode(ent)
  684. {
  685. new nadeTeam = pev(ent,pev_team), owner = pev(ent,pev_owner), Float:nadeOrigin[3];
  686. pev(ent,pev_origin,nadeOrigin);
  687.  
  688. // make the smoke
  689. message_begin_fl(MSG_PVS,SVC_TEMPENTITY,nadeOrigin,0);
  690. write_byte(TE_SMOKE);
  691. write_coord_fl(nadeOrigin[0]); // x
  692. write_coord_fl(nadeOrigin[1]); // y
  693. write_coord_fl(nadeOrigin[2]); // z
  694. write_short(smokeSpr); // sprite
  695. write_byte(random_num(30,40)); // scale
  696. write_byte(5); // framerate
  697. message_end();
  698.  
  699. // explosion
  700. create_blast(nadeTeam,nadeOrigin);
  701. emit_sound(ent,CHAN_ITEM,SOUND_EXPLODE,VOL_NORM,ATTN_NORM,0,PITCH_HIGH);
  702.  
  703. // cache our cvars
  704. new ff = get_pcvar_num(mp_friendlyfire), Float:by_radius = get_pcvar_float(pcv_by_radius),
  705. hitself = get_pcvar_num(pcv_hitself), los = get_pcvar_num(pcv_los), Float:maxdamage = get_pcvar_float(pcv_maxdamage),
  706. Float:mindamage = get_pcvar_float(pcv_mindamage), Float:chill_maxchance = get_pcvar_float(pcv_chill_maxchance),
  707. Float:chill_minchance = get_pcvar_float(pcv_chill_minchance), Float:freeze_maxchance, Float:freeze_minchance;
  708.  
  709. if(!by_radius)
  710. {
  711. freeze_maxchance = get_pcvar_float(pcv_freeze_maxchance);
  712. freeze_minchance = get_pcvar_float(pcv_freeze_minchance);
  713. }
  714.  
  715. new ta, Float:targetOrigin[3], Float:distance, tr = create_tr2(), Float:fraction, Float:damage, gotFrozen = 0;
  716. for(new target=1;target<=maxPlayers;target++)
  717. {
  718. // dead, invincible, or self attack that is not allowed
  719. if(!is_user_alive(target) || pev(target,pev_takedamage) == DAMAGE_NO
  720. || (pev(target,pev_flags) & FL_GODMODE) ||(target == owner && !hitself))
  721. continue;
  722.  
  723. // prevent freezing non-terrorist players
  724. if(cs_get_user_team(target) != CS_TEAM_T)
  725. continue;
  726.  
  727. // this is a team attack with ff disabled, excluding self attack
  728. ta = (_:cs_get_user_team(target) == nadeTeam);
  729. if(ta && !ff && target != owner) continue;
  730.  
  731. pev(target,pev_origin,targetOrigin);
  732. distance = vector_distance(nadeOrigin,targetOrigin);
  733.  
  734. // too far
  735. if(distance > FROST_RADIUS) continue;
  736.  
  737. // check line of sight
  738. if(los)
  739. {
  740. nadeOrigin[2] += 2.0;
  741. engfunc(EngFunc_TraceLine,nadeOrigin,targetOrigin,DONT_IGNORE_MONSTERS,ent,tr);
  742. nadeOrigin[2] -= 2.0;
  743.  
  744. get_tr2(tr,TR_flFraction,fraction);
  745. if(fraction != 1.0 && get_tr2(tr,TR_pHit) != target) continue;
  746. }
  747.  
  748. // damaged
  749. if(maxdamage > 0.0)
  750. {
  751. damage = radius_calc(distance,FROST_RADIUS,maxdamage,mindamage);
  752. if(ta) damage /= 2.0; // half damage for friendlyfire
  753.  
  754. if(damage > 0.0)
  755. {
  756. frostKilled[target] = 1;
  757. ExecuteHamB(Ham_TakeDamage,target,ent,owner,damage,DMG_GRENADE);
  758. if(!is_user_alive(target)) continue; // dead now
  759. frostKilled[target] = 0;
  760. }
  761. }
  762.  
  763. // frozen
  764. if((by_radius && radius_calc(distance,FROST_RADIUS,100.0,0.0) >= by_radius)
  765. || (!by_radius && random_num(1,100) <= floatround(radius_calc(distance,FROST_RADIUS,freeze_maxchance,freeze_minchance))))
  766. {
  767. if(freeze_player(target,owner,nadeTeam))
  768. {
  769. gotFrozen = 1;
  770. emit_sound(target,CHAN_ITEM,SOUND_FROZEN,1.0,ATTN_NONE,0,PITCH_LOW);
  771. }
  772. }
  773.  
  774. // chilled
  775. if(by_radius || random_num(1,100) <= floatround(radius_calc(distance,FROST_RADIUS,chill_maxchance,chill_minchance)))
  776. {
  777. if(chill_player(target,owner,nadeTeam))
  778. {
  779. if(!gotFrozen) emit_sound(target,CHAN_ITEM,SOUND_CHILLED,VOL_NORM,ATTN_NORM,0,PITCH_HIGH);
  780. }
  781. }
  782. }
  783.  
  784. free_tr2(tr);
  785. set_pev(ent,pev_flags,pev(ent,pev_flags)|FL_KILLME);
  786. }
  787.  
  788. freeze_player(id,attacker,nadeTeam)
  789. {
  790. new fwdRetVal = PLUGIN_CONTINUE;
  791. ExecuteForward(fnFwdPlayerFrozen, fwdRetVal, id, attacker);
  792.  
  793. if(fwdRetVal == PLUGIN_HANDLED || fwdRetVal == PLUGIN_HANDLED_MAIN)
  794. {
  795. return 0;
  796. }
  797.  
  798. if(!isFrozen[id])
  799. {
  800. pev(id,pev_gravity,oldGravity[id]);
  801.  
  802. // register our forward only when we need it
  803. if(!fmFwdPPT)
  804. {
  805. fmFwdPPT = register_forward(FM_PlayerPreThink,"fw_playerprethink",0);
  806. }
  807. }
  808.  
  809. isFrozen[id] = nadeTeam;
  810.  
  811. set_pev(id,pev_velocity,Float:{0.0,0.0,0.0});
  812. set_user_chillfreeze_speed(id);
  813.  
  814. new Float:duration = get_pcvar_float(pcv_freeze_duration), Float:variance = get_pcvar_float(pcv_freeze_variance);
  815. duration += random_float(-variance,variance);
  816.  
  817. remove_task(TASK_REMOVE_FREEZE+id);
  818. set_task(duration,"task_remove_freeze",TASK_REMOVE_FREEZE+id);
  819.  
  820. if(!pev_valid(novaDisplay[id])) create_nova(id);
  821.  
  822. if(get_pcvar_num(pcv_icon) == ICON_ISCHILLED)
  823. {
  824. show_icon(id, STATUS_FLASH);
  825. }
  826.  
  827. return 1;
  828. }
  829.  
  830. public task_remove_freeze(taskid)
  831. {
  832. new id = taskid-TASK_REMOVE_FREEZE;
  833.  
  834. if(pev_valid(novaDisplay[id]))
  835. {
  836. new Float:origin[3];
  837. pev(novaDisplay[id],pev_origin,origin);
  838.  
  839. // add some tracers
  840. message_begin_fl(MSG_PVS,SVC_TEMPENTITY,origin,0);
  841. write_byte(TE_IMPLOSION);
  842. write_coord_fl(origin[0]); // x
  843. write_coord_fl(origin[1]); // y
  844. write_coord_fl(origin[2] + 8.0); // z
  845. write_byte(64); // radius
  846. write_byte(10); // count
  847. write_byte(3); // duration
  848. message_end();
  849.  
  850. // add some sparks
  851. message_begin_fl(MSG_PVS,SVC_TEMPENTITY,origin,0);
  852. write_byte(TE_SPARKS);
  853. write_coord_fl(origin[0]); // x
  854. write_coord_fl(origin[1]); // y
  855. write_coord_fl(origin[2]); // z
  856. message_end();
  857.  
  858. // add the shatter
  859. message_begin_fl(MSG_PAS,SVC_TEMPENTITY,origin,0);
  860. write_byte(TE_BREAKMODEL);
  861. write_coord_fl(origin[0]); // x
  862. write_coord_fl(origin[1]); // y
  863. write_coord_fl(origin[2] + 24.0); // z
  864. write_coord_fl(16.0); // size x
  865. write_coord_fl(16.0); // size y
  866. write_coord_fl(16.0); // size z
  867. write_coord(random_num(-50,50)); // velocity x
  868. write_coord(random_num(-50,50)); // velocity y
  869. write_coord_fl(25.0); // velocity z
  870. write_byte(10); // random velocity
  871. write_short(glassGibs); // model
  872. write_byte(10); // count
  873. write_byte(25); // life
  874. write_byte(BREAK_GLASS); // flags
  875. message_end();
  876.  
  877. emit_sound(novaDisplay[id],CHAN_ITEM,SOUND_UNFROZEN,VOL_NORM,ATTN_NORM,0,PITCH_LOW);
  878. set_pev(novaDisplay[id],pev_flags,pev(novaDisplay[id],pev_flags)|FL_KILLME);
  879. }
  880.  
  881. isFrozen[id] = 0;
  882. novaDisplay[id] = 0;
  883.  
  884. // unregister forward if we are no longer using it
  885. unregister_prethink();
  886.  
  887. if(!is_user_connected(id)) return;
  888.  
  889. // restore speed, but then check for chilled
  890. ExecuteHam(Ham_Player_ResetMaxSpeed, id);
  891. set_user_chillfreeze_speed(id);
  892.  
  893. set_pev(id,pev_gravity,oldGravity[id]);
  894.  
  895. new status = STATUS_HIDE;
  896.  
  897. // sometimes trail fades during freeze, reapply
  898. if(isChilled[id])
  899. {
  900. status = STATUS_SHOW;
  901.  
  902. new rgb[3];
  903. get_rgb_colors(isChilled[id],rgb);
  904. set_beamfollow(id,30,8,rgb,100);
  905. }
  906.  
  907. if(get_pcvar_num(pcv_icon) == ICON_ISCHILLED)
  908. {
  909. show_icon(id, status);
  910. }
  911. }
  912.  
  913. chill_player(id,attacker,nadeTeam)
  914. {
  915. new fwdRetVal = PLUGIN_CONTINUE;
  916. ExecuteForward(fnFwdPlayerChilled, fwdRetVal, id, attacker);
  917.  
  918. if(fwdRetVal == PLUGIN_HANDLED || fwdRetVal == PLUGIN_HANDLED_MAIN)
  919. {
  920. return 0;
  921. }
  922.  
  923. // we aren't already been chilled
  924. if(!isChilled[id])
  925. {
  926. oldRenderFx[id] = pev(id,pev_renderfx);
  927. pev(id,pev_rendercolor,oldRenderColor[id]);
  928. oldRenderMode[id] = pev(id,pev_rendermode);
  929. pev(id,pev_renderamt,oldRenderAmt[id]);
  930.  
  931. isChilled[id] = nadeTeam; // fix -- thanks Exolent
  932.  
  933. // register our forward only when we need it
  934. //if(!fmFwdPPT) fmFwdPPT = register_forward(FM_PlayerPreThink,"fw_playerprethink",0);
  935. }
  936.  
  937. isChilled[id] = nadeTeam;
  938.  
  939. set_user_chillfreeze_speed(id);
  940.  
  941. new Float:duration = get_pcvar_float(pcv_chill_duration), Float:variance = get_pcvar_float(pcv_chill_variance);
  942. duration += random_float(-variance,variance);
  943.  
  944. remove_task(TASK_REMOVE_CHILL+id);
  945. set_task(duration,"task_remove_chill",TASK_REMOVE_CHILL+id);
  946.  
  947. new rgb[3];
  948. get_rgb_colors(nadeTeam,rgb);
  949.  
  950. IVecFVec(rgb, glowColor[id]);
  951.  
  952. // glowshell
  953. set_user_rendering(id, kRenderFxGlowShell, rgb[0], rgb[1], rgb[2], kRenderNormal, floatround(GLOW_AMOUNT));
  954.  
  955. set_beamfollow(id,30,8,rgb,100);
  956.  
  957. // I decided to let the frostnade tint override a flashbang,
  958. // because if you are frozen, then you have much bigger problems.
  959.  
  960. // add a blue tint to their screen
  961. message_begin(MSG_ONE,gmsgScreenFade,_,id);
  962. write_short(floatround(4096.0 * duration)); // duration
  963. write_short(floatround(3072.0 * duration)); // hold time (4096.0 * 0.75)
  964. write_short(FFADE_IN); // flags
  965. write_byte(rgb[0]); // red
  966. write_byte(rgb[1]); // green
  967. write_byte(rgb[2]); // blue
  968. write_byte(100); // alpha
  969. message_end();
  970.  
  971. if(get_pcvar_num(pcv_icon) == ICON_ISCHILLED && !isFrozen[id])
  972. {
  973. show_icon(id, STATUS_SHOW);
  974. }
  975.  
  976. return 1;
  977. }
  978.  
  979. public task_remove_chill(taskid)
  980. {
  981. new id = taskid-TASK_REMOVE_CHILL;
  982.  
  983. isChilled[id] = 0;
  984.  
  985. // unregister forward if we are no longer using it
  986. //unregister_prethink();
  987.  
  988. if(!is_user_connected(id)) return;
  989.  
  990. // set speed to normal, then check for frozen
  991. ExecuteHam(Ham_Player_ResetMaxSpeed, id);
  992. set_user_chillfreeze_speed(id);
  993.  
  994. // reset rendering
  995. set_user_rendering(id, oldRenderFx[id], floatround(oldRenderColor[id][0]), floatround(oldRenderColor[id][1]),
  996. floatround(oldRenderColor[id][2]), oldRenderMode[id], floatround(oldRenderAmt[id]));
  997.  
  998. clear_beamfollow(id);
  999.  
  1000. // calculate end of flashbang
  1001. new Float:flashedUntil = get_pdata_float(id,m_flFlashedUntil),
  1002. Float:flashHoldTime = get_pdata_float(id,m_flFlashHoldTime),
  1003. Float:endOfFlash = flashedUntil + (flashHoldTime * 0.67);
  1004.  
  1005. // not blinded
  1006. if(get_gametime() >= endOfFlash)
  1007. {
  1008. // clear tint
  1009. message_begin(MSG_ONE,gmsgScreenFade,_,id);
  1010. write_short(0); // duration
  1011. write_short(0); // hold time
  1012. write_short(FFADE_IN); // flags
  1013. write_byte(0); // red
  1014. write_byte(0); // green
  1015. write_byte(0); // blue
  1016. write_byte(255); // alpha
  1017. message_end();
  1018. }
  1019.  
  1020. if(get_pcvar_num(pcv_icon) == ICON_ISCHILLED && !isFrozen[id])
  1021. {
  1022. show_icon(id, STATUS_HIDE);
  1023. }
  1024. }
  1025.  
  1026. // make a frost nova at a player's feet
  1027. create_nova(id)
  1028. {
  1029. new nova = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,"info_target"));
  1030.  
  1031. engfunc(EngFunc_SetSize,nova,Float:{-8.0,-8.0,-4.0},Float:{8.0,8.0,4.0});
  1032. engfunc(EngFunc_SetModel,nova,MODEL_FROZEN);
  1033.  
  1034. // random orientation
  1035. new Float:angles[3];
  1036. angles[1] = random_float(0.0,360.0);
  1037. set_pev(nova,pev_angles,angles);
  1038.  
  1039. // put it at their feet
  1040. new Float:novaOrigin[3];
  1041. pev(id,pev_origin,novaOrigin);
  1042. engfunc(EngFunc_SetOrigin,nova,novaOrigin);
  1043.  
  1044. // make it translucent
  1045. new rgb[3];
  1046. get_rgb_colors(isFrozen[id], rgb);
  1047. IVecFVec(rgb, angles); // let's just use angles
  1048.  
  1049. set_pev(nova,pev_rendercolor,angles); // see above
  1050. set_pev(nova,pev_rendermode,kRenderTransAlpha);
  1051. set_pev(nova,pev_renderfx,kRenderFxGlowShell);
  1052. set_pev(nova,pev_renderamt,128.0);
  1053.  
  1054. novaDisplay[id] = nova;
  1055. }
  1056.  
  1057. /****************************************
  1058. * UTILITY FUNCTIONS
  1059. ****************************************/
  1060.  
  1061. // check if prethink is still being used, if not, unhook it
  1062. unregister_prethink()
  1063. {
  1064. if(fmFwdPPT)
  1065. {
  1066. new i;
  1067. for(i=1;i<=maxPlayers;i++) if(/*isChilled[i] ||*/ isFrozen[i]) break;
  1068. if(i > maxPlayers)
  1069. {
  1070. unregister_forward(FM_PlayerPreThink,fmFwdPPT,0);
  1071. fmFwdPPT = 0;
  1072. }
  1073. }
  1074. }
  1075.  
  1076. // make the explosion effects
  1077. create_blast(team,Float:origin[3])
  1078. {
  1079. new rgb[3];
  1080. get_rgb_colors(team,rgb);
  1081.  
  1082. // smallest ring
  1083. message_begin_fl(MSG_PVS,SVC_TEMPENTITY,origin,0);
  1084. write_byte(TE_BEAMCYLINDER);
  1085. write_coord_fl(origin[0]); // x
  1086. write_coord_fl(origin[1]); // y
  1087. write_coord_fl(origin[2]); // z
  1088. write_coord_fl(origin[0]); // x axis
  1089. write_coord_fl(origin[1]); // y axis
  1090. write_coord_fl(origin[2] + 385.0); // z axis
  1091. write_short(exploSpr); // sprite
  1092. write_byte(0); // start frame
  1093. write_byte(0); // framerate
  1094. write_byte(4); // life
  1095. write_byte(60); // width
  1096. write_byte(0); // noise
  1097. write_byte(rgb[0]); // red
  1098. write_byte(rgb[1]); // green
  1099. write_byte(rgb[2]); // blue
  1100. write_byte(100); // brightness
  1101. write_byte(0); // speed
  1102. message_end();
  1103.  
  1104. // medium ring
  1105. message_begin_fl(MSG_PVS,SVC_TEMPENTITY,origin,0);
  1106. write_byte(TE_BEAMCYLINDER);
  1107. write_coord_fl(origin[0]); // x
  1108. write_coord_fl(origin[1]); // y
  1109. write_coord_fl(origin[2]); // z
  1110. write_coord_fl(origin[0]); // x axis
  1111. write_coord_fl(origin[1]); // y axis
  1112. write_coord_fl(origin[2] + 470.0); // z axis
  1113. write_short(exploSpr); // sprite
  1114. write_byte(0); // start frame
  1115. write_byte(0); // framerate
  1116. write_byte(4); // life
  1117. write_byte(60); // width
  1118. write_byte(0); // noise
  1119. write_byte(rgb[0]); // red
  1120. write_byte(rgb[1]); // green
  1121. write_byte(rgb[2]); // blue
  1122. write_byte(100); // brightness
  1123. write_byte(0); // speed
  1124. message_end();
  1125.  
  1126. // largest ring
  1127. message_begin_fl(MSG_PVS,SVC_TEMPENTITY,origin,0);
  1128. write_byte(TE_BEAMCYLINDER);
  1129. write_coord_fl(origin[0]); // x
  1130. write_coord_fl(origin[1]); // y
  1131. write_coord_fl(origin[2]); // z
  1132. write_coord_fl(origin[0]); // x axis
  1133. write_coord_fl(origin[1]); // y axis
  1134. write_coord_fl(origin[2] + 555.0); // z axis
  1135. write_short(exploSpr); // sprite
  1136. write_byte(0); // start frame
  1137. write_byte(0); // framerate
  1138. write_byte(4); // life
  1139. write_byte(60); // width
  1140. write_byte(0); // noise
  1141. write_byte(rgb[0]); // red
  1142. write_byte(rgb[1]); // green
  1143. write_byte(rgb[2]); // blue
  1144. write_byte(100); // brightness
  1145. write_byte(0); // speed
  1146. message_end();
  1147.  
  1148. // light effect
  1149. message_begin_fl(MSG_PAS,SVC_TEMPENTITY,origin,0);
  1150. write_byte(TE_DLIGHT);
  1151. write_coord_fl(origin[0]); // x
  1152. write_coord_fl(origin[1]); // y
  1153. write_coord_fl(origin[2]); // z
  1154. write_byte(floatround(FROST_RADIUS/5.0)); // radius
  1155. write_byte(rgb[0]); // r
  1156. write_byte(rgb[1]); // g
  1157. write_byte(rgb[2]); // b
  1158. write_byte(8); // life
  1159. write_byte(60); // decay rate
  1160. message_end();
  1161. }
  1162.  
  1163. // give an entity a beam trail
  1164. set_beamfollow(ent,life,width,rgb[3],brightness)
  1165. {
  1166. clear_beamfollow(ent);
  1167.  
  1168. message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
  1169. write_byte(TE_BEAMFOLLOW);
  1170. write_short(ent); // entity
  1171. write_short(trailSpr); // sprite
  1172. write_byte(life); // life
  1173. write_byte(width); // width
  1174. write_byte(rgb[0]); // red
  1175. write_byte(rgb[1]); // green
  1176. write_byte(rgb[2]); // blue
  1177. write_byte(brightness); // brightness
  1178. message_end();
  1179. }
  1180.  
  1181. // removes beam trails from an entity
  1182. clear_beamfollow(ent)
  1183. {
  1184. message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
  1185. write_byte(TE_KILLBEAM);
  1186. write_short(ent); // entity
  1187. message_end();
  1188. }
  1189.  
  1190. // gets the appropriate color and displays the frostnade icon to the player with the given status
  1191. show_icon(id, status)
  1192. {
  1193. static rgb[3];
  1194. if(status) get_rgb_colors(_:cs_get_user_team(id), rgb); // only get colors if we need to
  1195.  
  1196. message_begin(MSG_ONE,gmsgStatusIcon,_,id);
  1197. write_byte(status); // status (0=hide, 1=show, 2=flash)
  1198. write_string("dmg_cold"); // sprite name
  1199. write_byte(rgb[0]); // red
  1200. write_byte(rgb[1]); // green
  1201. write_byte(rgb[2]); // blue
  1202. message_end();
  1203. }
  1204.  
  1205. // checks if a weapon id is included in fn_nadetypes
  1206. is_wid_in_nadetypes(wid)
  1207. {
  1208. new types = get_pcvar_num(pcv_nadetypes);
  1209.  
  1210. return ( (wid == CSW_HEGRENADE && (types & NT_HEGRENADE))
  1211. || (wid == CSW_FLASHBANG && (types & NT_FLASHBANG))
  1212. || (wid == CSW_SMOKEGRENADE && (types & NT_SMOKEGRENADE)) );
  1213. }
  1214.  
  1215. // checks if a player has a frostnade, taking into account fn_override and such.
  1216. // returns: STATUS_HIDE = no frostnade, STATUS_SHOW = has frostnade but not deployed, STATUS_FLASH = has frostnade and deployed
  1217. player_has_frostnade(id)
  1218. {
  1219. new retVal = STATUS_HIDE, curwpn = get_user_weapon(id);
  1220.  
  1221. // no override, variable explicitly set
  1222. if(hasFrostNade[id])
  1223. {
  1224. retVal = (curwpn == hasFrostNade[id] ? STATUS_FLASH : STATUS_SHOW);
  1225. }
  1226.  
  1227. // override enabled, and I'm on the right team
  1228. else if(get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)))
  1229. {
  1230. new types = get_pcvar_num(pcv_nadetypes);
  1231.  
  1232. if((types & NT_HEGRENADE) && cs_get_user_bpammo(id, CSW_HEGRENADE) > 0)
  1233. {
  1234. retVal = (curwpn == CSW_HEGRENADE ? STATUS_FLASH : STATUS_SHOW);
  1235. }
  1236.  
  1237. if(retVal != STATUS_FLASH && (types & NT_FLASHBANG) && cs_get_user_bpammo(id, CSW_FLASHBANG) > 0)
  1238. {
  1239. retVal = (curwpn == CSW_FLASHBANG ? STATUS_FLASH : STATUS_SHOW);
  1240. }
  1241.  
  1242. if(retVal != STATUS_FLASH && (types & NT_SMOKEGRENADE) && cs_get_user_bpammo(id, NT_SMOKEGRENADE) > 0)
  1243. {
  1244. retVal = (curwpn == NT_SMOKEGRENADE ? STATUS_FLASH : STATUS_SHOW);
  1245. }
  1246. }
  1247.  
  1248. return retVal;
  1249. }
  1250.  
  1251. // gets RGB colors from the cvar
  1252. get_rgb_colors(team,rgb[3])
  1253. {
  1254. static color[12], parts[3][4];
  1255. get_pcvar_string(pcv_color,color,11);
  1256.  
  1257. // if cvar is set to "team", use colors based on the given team
  1258. if(equali(color,"team",4))
  1259. {
  1260. if(team == 1)
  1261. {
  1262. rgb[0] = 150;
  1263. rgb[1] = 0;
  1264. rgb[2] = 0;
  1265. }
  1266. else
  1267. {
  1268. rgb[0] = 0;
  1269. rgb[1] = 0;
  1270. rgb[2] = 150;
  1271. }
  1272. }
  1273. else
  1274. {
  1275. parse(color,parts[0],3,parts[1],3,parts[2],3);
  1276. rgb[0] = str_to_num(parts[0]);
  1277. rgb[1] = str_to_num(parts[1]);
  1278. rgb[2] = str_to_num(parts[2]);
  1279. }
  1280. }
  1281.  
  1282. // scale a value equally (inversely?) with the distance that something
  1283. // is from the center of another thing. that makes pretty much no sense,
  1284. // so basically, the closer we are to the center of a ring, the higher
  1285. // our value gets.
  1286. //
  1287. // EXAMPLE: distance = 60.0, radius = 240.0, maxVal = 100.0, minVal = 20.0
  1288. // we are 0.75 (1.0-(60.0/240.0)) of the way to the radius, so scaled with our
  1289. // values, it comes out to 80.0 (20.0 + (0.75 * (100.0 - 20.0)))
  1290. Float:radius_calc(Float:distance,Float:radius,Float:maxVal,Float:minVal)
  1291. {
  1292. if(maxVal <= 0.0) return 0.0;
  1293. if(minVal >= maxVal) return minVal;
  1294. return minVal + ((1.0 - (distance / radius)) * (maxVal - minVal));
  1295. }
  1296.  
  1297. // sets a user's chilled/frozen speed if applicable
  1298. // (NOTE: does NOT reset his maxspeed if he is not chilled/frozen)
  1299. set_user_chillfreeze_speed(id)
  1300. {
  1301. if(isFrozen[id])
  1302. {
  1303. set_user_maxspeed(id, 1.0);
  1304. }
  1305. else if(isChilled[id])
  1306. {
  1307. set_user_maxspeed(id, get_default_maxspeed(id)*(get_pcvar_float(pcv_chill_speed)/100.0));
  1308. }
  1309. }
  1310.  
  1311. // gets the maxspeed a user should have, given his current weapon
  1312. stock Float:get_default_maxspeed(id)
  1313. {
  1314. new wEnt = get_pdata_cbase(id, m_pActiveItem), Float:result = 250.0;
  1315.  
  1316. if(pev_valid(wEnt))
  1317. {
  1318. ExecuteHam(Ham_CS_Item_GetMaxSpeed, wEnt, result);
  1319. }
  1320.  
  1321. return result;
  1322. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement