Advertisement
Rejack

Frostnades + Anti-Frost Code

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