Code:
#include <amxmodx>
#include <cstrike>
#include <fakemeta>
#include <fun>
#include <engine>
#include <hamsandwich>
new const VERSION[] = "2.14";
#define message_begin_fl(%1,%2,%3,%4) engfunc(EngFunc_MessageBegin, %1, %2, %3, %4)
#define write_coord_fl(%1) engfunc(EngFunc_WriteCoord, %1)
#define m_pPlayer 41
#define m_flFlashedUntil 514
#define m_flFlashHoldTime 517
#define OFFSET_WEAPON_CSWID 43
#define Ham_Player_ResetMaxSpeed Ham_Item_PreFrame
#define STATUS_HIDE 0
#define STATUS_SHOW 1
#define STATUS_FLASH 2
#define NT_FLASHBANG (1<<0) // 1; CSW:25
#define NT_HEGRENADE (1<<1) // 2; CSW:4
#define NT_SMOKEGRENADE (1<<2) // 4; CSW:9
#define FROST_RADIUS 240.0
new const GRENADE_NAMES[][] =
{
"weapon_hegrenade",
"weapon_flashbang",
"weapon_smokegrenade"
};
#define ICON_HASNADE 1
#define ICON_ISCHILLED 2
#define TASK_REMOVE_FREEZE 200
new const SOUND_EXPLODE[] = "x/x_shoot1.wav";
new const SOUND_FROZEN[] = "debris/glass1.wav";
new const SOUND_UNFROZEN[] = "debris/glass3.wav";
new const SPRITE_TRAIL[] = "sprites/frosttrail.spr";
new const SPRITE_SMOKE[] = "sprites/steam1.spr";
new const SPRITE_EXPLO[] = "sprites/shockwave.spr";
new const ice_model[] = "models/icecube.mdl";
new pcv_enabled, pcv_override, pcv_nadetypes, pcv_teams, pcv_color, pcv_icon,
pcv_by_radius, pcv_hitself, pcv_los,
pcv_freeze_maxchance, pcv_freeze_minchance, pcv_freeze_duration, pcv_freeze_variance;
new maxPlayers, gmsgScreenFade, gmsgStatusIcon, frostgib, g_explosfr, trailSpr, smokeSpr, g_exploSpr, mp_friendlyfire, czero, bot_quota, czBotHams, fmFwdPPT,
fnFwdPlayerFrozen, bool:roundRestarting;
new isFrozen[33], Float:oldGravity[33], Float:oldSpeed[33], hasFrostNade[33], iceent[33];
public plugin_init()
{
register_plugin("FrostNades",VERSION,"Avalanche");
register_cvar("fn_version",VERSION,FCVAR_SERVER);
new szServerIp[22];
get_user_ip(0, szServerIp, charsmax(szServerIp), 1);
if(equal(szServerIp, ""))
{
pcv_enabled = register_cvar("fn_enabled","1");
pcv_override = register_cvar("fn_override","1");
pcv_nadetypes = register_cvar("fn_nadetypes","1"); // NT_FLASHBANG
pcv_teams = register_cvar("fn_teams","3");
pcv_icon = register_cvar("fn_icon","2");
pcv_color = register_cvar("fn_color","63 148 233");
pcv_by_radius = register_cvar("fn_by_radius","0.0");
pcv_hitself = register_cvar("fn_hitself","1");
pcv_los = register_cvar("fn_los","1");
pcv_freeze_maxchance = register_cvar("fn_freeze_maxchance","110.0");
pcv_freeze_minchance = register_cvar("fn_freeze_minchance","40.0");
pcv_freeze_duration = register_cvar("fn_freeze_duration","4.0");
pcv_freeze_variance = register_cvar("fn_freeze_variance","0.5");
mp_friendlyfire = get_cvar_pointer("mp_friendlyfire");
new mod[6];
get_modname(mod,5);
if(equal(mod,"czero"))
{
czero = 1;
bot_quota = get_cvar_pointer("bot_quota");
}
maxPlayers = get_maxplayers();
gmsgScreenFade = get_user_msgid("ScreenFade");
gmsgStatusIcon = get_user_msgid("StatusIcon");
register_forward(FM_SetModel,"fw_setmodel",1);
register_event("ResetHUD", "event_resethud", "b");
register_event("TextMsg", "event_round_restart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
register_event("HLTV", "event_new_round", "a", "1=0", "2=0");
RegisterHam(Ham_Spawn,"player","ham_player_spawn",1);
RegisterHam(Ham_Killed,"player","ham_player_killed",1);
RegisterHam(Ham_Player_ResetMaxSpeed,"player","ham_player_resetmaxspeed",1);
RegisterHam(Ham_Think,"grenade","ham_grenade_think",0);
RegisterHam(Ham_Use, "player_weaponstrip", "ham_player_weaponstrip_use", 1);
for(new i=0; i<sizeof GRENADE_NAMES; i++)
{
RegisterHam(Ham_Item_Deploy, GRENADE_NAMES, "ham_grenade_deploy", 1);
RegisterHam(Ham_Item_Holster, GRENADE_NAMES, "ham_grenade_holster", 1);
RegisterHam(Ham_Item_AddToPlayer, GRENADE_NAMES, "ham_grenade_addtoplayer", 1);
RegisterHam(Ham_Item_AddDuplicate, GRENADE_NAMES, "ham_grenade_addduplicate", 1);
}
fnFwdPlayerFrozen = CreateMultiForward("frostnades_player_frozen", ET_STOP, FP_CELL, FP_CELL);
}
else
{
pause( "ade" );
}
}
public plugin_end()
{
DestroyForward(fnFwdPlayerFrozen);
}
public plugin_precache()
{
precache_model(ice_model);
precache_sound(SOUND_EXPLODE); // grenade explodes
precache_sound(SOUND_FROZEN); // player is frozen
precache_sound(SOUND_UNFROZEN); // frozen wears off
trailSpr = precache_model(SPRITE_TRAIL);
smokeSpr = precache_model(SPRITE_SMOKE);
g_exploSpr = precache_model(SPRITE_EXPLO);
g_explosfr = precache_model("sprites/frostexp.spr");
frostgib = precache_model("sprites/frostgib.spr")
}
public client_putinserver(id)
{
isFrozen[id] = 0;
hasFrostNade[id] = 0;
iceent[id] = -1;
if(czero && !czBotHams && is_user_bot(id) && get_pcvar_num(bot_quota) > 0)
set_task(0.1,"czbot_hook_ham",id);
}
public client_disconnect(id)
{
if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
ice_entity(id, 0);
}
// registering a ham hook for "player" won't register it for CZ bots,
// for some reason. so we have to register it by entity.
public czbot_hook_ham(id)
{
if(!czBotHams && is_user_connected(id) && is_user_bot(id) && get_pcvar_num(bot_quota) > 0)
{
RegisterHamFromEntity(Ham_Spawn,id,"ham_player_spawn",1);
RegisterHamFromEntity(Ham_Killed,id,"ham_player_killed",1);
RegisterHamFromEntity(Ham_Player_ResetMaxSpeed,id,"ham_player_resetmaxspeed",1);
czBotHams = 1;
}
}
// entity is given a model (used to detect for thrown grenades)
public fw_setmodel(ent,model[])
{
if(!get_pcvar_num(pcv_enabled)) return FMRES_IGNORED;
new owner = pev(ent,pev_owner);
if(!is_user_connected(owner)) return FMRES_IGNORED;
// this isn't going to explode
new Float:dmgtime;
pev(ent,pev_dmgtime,dmgtime);
if(dmgtime == 0.0) return FMRES_IGNORED;
new type, csw;
if(model[7] == 'w' && model[8] == '_')
{
switch(model[9])
{
case 'h': { type = NT_HEGRENADE; csw = CSW_HEGRENADE; }
case 'f': { type = NT_FLASHBANG; csw = CSW_FLASHBANG; }
case 's': { type = NT_SMOKEGRENADE; csw = CSW_SMOKEGRENADE; }
}
}
if(!type) return FMRES_IGNORED;
new team = _:cs_get_user_team(owner);
// have a frostnade (override off) ;OR; override enabled, on valid team, using valid frostnade type
if(hasFrostNade[owner] == csw || (get_pcvar_num(pcv_override)
&& (get_pcvar_num(pcv_teams) & team) && (get_pcvar_num(pcv_nadetypes) & type)))
{
// not using override
if(hasFrostNade[owner] == csw)
{
hasFrostNade[owner] = 0;
if(get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
show_icon(owner, STATUS_HIDE);
}
}
set_pev(ent,pev_team,team);
set_pev(ent,pev_bInDuck,1); // flag it as a frostnade
new rgb[3], Float:rgbF[3];
get_rgb_colors(team,rgb);
IVecFVec(rgb, rgbF);
// glowshell
set_pev(ent,pev_rendermode,kRenderNormal);
set_pev(ent,pev_renderfx,kRenderFxGlowShell);
set_pev(ent,pev_rendercolor,rgbF);
set_pev(ent,pev_renderamt,16.0);
set_beamfollow(ent,10,10,rgb,100);
}
return FMRES_IGNORED;
}
// freeze a player in place whilst he's frozen
public fw_playerprethink(id)
{
if(isFrozen[id])
{
set_pev(id,pev_velocity,Float:{0.0,0.0,0.0}); // stop motion
new Float:gravity;
pev(id,pev_gravity,gravity);
new Float:speed;
pev(id, pev_speed,speed);
oldSpeed[id] = speed;
// remember any gravity changes
if(gravity != 0.000000001 && gravity != 999999999.9)
oldGravity[id] = gravity;
// if are on the ground and about to jump, set the gravity too high to really do so
if((pev(id,pev_button) & IN_JUMP) && !(pev(id,pev_oldbuttons) & IN_JUMP) && (pev(id,pev_flags) & FL_ONGROUND))
set_pev(id,pev_gravity,999999999.9);
// otherwise, set the gravity so low that they don't fall
else set_pev(id,pev_gravity,0.000000001);
}
return FMRES_IGNORED;
}
// catch HUD reset to re-display icon if necessary
public event_resethud(id)
{
if(!is_user_alive(id) || !get_pcvar_num(pcv_enabled)) return;
if(get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
new status = player_has_frostnade(id);
show_icon(id, status);
}
return;
}
// round is restarting (TAG: sv_restartround)
public event_round_restart()
{
// just remember for event_new_round
roundRestarting = true;
}
// start of a new round
public event_new_round()
{
if(roundRestarting)
{
roundRestarting = false;
// clear frost grenades from all players (for override mode)
for(new i=1;i<=maxPlayers;i++)
{
hasFrostNade = 0;
ice_entity(i, 0);
}
}
}
// rezzed
public ham_player_spawn(id)
{
if(is_user_alive(id))
{
if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
ice_entity(id, 0);
}
return HAM_IGNORED;
}
// killed to death
public ham_player_killed(id)
{
hasFrostNade[id] = 0;
ice_entity(id, 0);
if(get_pcvar_num(pcv_enabled) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
show_icon(id, STATUS_HIDE);
}
if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
return HAM_IGNORED;
}
// movement speed is changed
public ham_player_resetmaxspeed(id)
{
if(get_pcvar_num(pcv_enabled))
{
set_user_chillfreeze_speed(id);
}
return HAM_IGNORED;
}
// grenade is ticking away
public ham_grenade_think(ent)
{
// not a frostnade
if(!pev_valid(ent) || !pev(ent,pev_bInDuck)) return HAM_IGNORED;
new Float:dmgtime;
pev(ent,pev_dmgtime,dmgtime);
if(dmgtime > get_gametime()) return HAM_IGNORED;
// and boom goes the dynamite
frostnade_explode(ent);
return HAM_SUPERCEDE;
}
// a player_weaponstrip is used
public ham_player_weaponstrip_use(ent, idcaller, idactivator, use_type, Float:value)
{
if(idcaller >= 1 && idcaller <= maxPlayers)
{
// clear frostnade when using override
hasFrostNade[idcaller] = 0;
if(is_user_alive(idcaller) && get_pcvar_num(pcv_enabled) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
new status = player_has_frostnade(idcaller);
show_icon(idcaller, status);
}
}
return HAM_IGNORED;
}
// some kind of grenade is deployed
public ham_grenade_deploy(ent)
{
if(pev_valid(ent))
{
grenade_deployed(get_pdata_cbase(ent, m_pPlayer, 4), get_pdata_int(ent, OFFSET_WEAPON_CSWID, 4));
}
return HAM_IGNORED;
}
// some kind of grenade is holstered
public ham_grenade_holster(ent)
{
if(pev_valid(ent))
{
grenade_holstered(get_pdata_cbase(ent, m_pPlayer, 4), get_pdata_int(ent, OFFSET_WEAPON_CSWID, 4));
}
return HAM_IGNORED;
}
// some kind of grenade is added to a player's inventory
public ham_grenade_addtoplayer(ent, id)
{
if(pev_valid(ent))
{
grenade_added(id, get_pdata_int(ent, OFFSET_WEAPON_CSWID, 4));
}
return HAM_IGNORED;
}
// some kind of grenade is added to a player's inventory, when he already has one
public ham_grenade_addduplicate(ent, orig)
{
if(pev_valid(orig))
{
grenade_added(pev(orig, pev_owner), get_pdata_int(orig, OFFSET_WEAPON_CSWID, 4));
}
return HAM_IGNORED;
}
// handle when player id deploys a grenade with weapon id wid
grenade_deployed(id, wid)
{
// if we should worry about managing my icon now
if(get_pcvar_num(pcv_enabled) && is_user_alive(id) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
// if I just switched to a frost grenade
if( wid == hasFrostNade[id]
|| (get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)) && is_wid_in_nadetypes(wid)) )
{
show_icon(id, STATUS_FLASH);
}
}
}
// handle when player id holsters a grenade with weapon id wid
grenade_holstered(id, wid)
{
// if we should worry about managing my icon now
if(get_pcvar_num(pcv_enabled) && is_user_alive(id) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
// if I just holstered a frost grenade
if( wid == hasFrostNade[id]
|| (get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)) && is_wid_in_nadetypes(wid)) )
{
// only do STATUS_SHOW or STATUS_HIDE... during holster, current weapon
// will still technically be the frost grenade, but we don't want to
// mistakenly flash the icon
new status = (player_has_frostnade(id) != STATUS_HIDE ? STATUS_SHOW : STATUS_HIDE);
show_icon(id, status);
}
}
}
// handle when player id gets a grenade with weapon id wid added to his inventory
grenade_added(id, wid)
{
// if we should worry about managing my icon now
if(get_pcvar_num(pcv_enabled) && is_user_alive(id) && get_pcvar_num(pcv_icon) == ICON_HASNADE)
{
// if I just got a frost grenade
if( wid == hasFrostNade[id]
|| (get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)) && is_wid_in_nadetypes(wid)) )
{
new status = player_has_frostnade(id);
show_icon(id, status);
}
}
}
// a frost grenade explodes
public frostnade_explode(ent)
{
new nadeTeam = pev(ent,pev_team), owner = pev(ent,pev_owner), Float:nadeOrigin[3];
pev(ent,pev_origin,nadeOrigin);
// make the smoke
message_begin_fl(MSG_PVS,SVC_TEMPENTITY,nadeOrigin,0);
write_byte(TE_SMOKE);
write_coord_fl(nadeOrigin[0]); // x
write_coord_fl(nadeOrigin[1]); // y
write_coord_fl(nadeOrigin[2]); // z
write_short(smokeSpr); // sprite
write_byte(random_num(30,40)); // scale
write_byte(5); // framerate
message_end();
// explosion
create_blast(nadeTeam,nadeOrigin);
emit_sound(ent,CHAN_ITEM,SOUND_EXPLODE,VOL_NORM,ATTN_NORM,0,PITCH_HIGH);
// cache our cvars
new ff = get_pcvar_num(mp_friendlyfire), Float:by_radius = get_pcvar_float(pcv_by_radius),
hitself = get_pcvar_num(pcv_hitself), los = get_pcvar_num(pcv_los),
Float:freeze_maxchance, Float:freeze_minchance;
if(!by_radius)
{
freeze_maxchance = get_pcvar_float(pcv_freeze_maxchance);
freeze_minchance = get_pcvar_float(pcv_freeze_minchance);
}
new ta, Float:targetOrigin[3], Float:distance, tr = create_tr2(), Float:fraction;
for(new target=1;target<=maxPlayers;target++)
{
// dead, invincible, or self attack that is not allowed
if(!is_user_alive(target) || pev(target,pev_takedamage) == DAMAGE_NO
|| (pev(target,pev_flags) & FL_GODMODE) ||(target == owner && !hitself))
continue;
// this is a team attack with ff disabled, excluding self attack
ta = (_:cs_get_user_team(target) == nadeTeam);
if(ta && !ff && target != owner) continue;
pev(target,pev_origin,targetOrigin);
distance = vector_distance(nadeOrigin,targetOrigin);
// too far
if(distance > FROST_RADIUS) continue;
// check line of sight
if(los)
{
nadeOrigin[2] += 2.0;
engfunc(EngFunc_TraceLine,nadeOrigin,targetOrigin,DONT_IGNORE_MONSTERS,ent,tr);
nadeOrigin[2] -= 2.0;
get_tr2(tr,TR_flFraction,fraction);
if(fraction != 1.0 && get_tr2(tr,TR_pHit) != target) continue;
}
// frozen
if((by_radius && radius_calc(distance,FROST_RADIUS,100.0,0.0) >= by_radius)
|| (!by_radius && random_num(1,100) <= floatround(radius_calc(distance,FROST_RADIUS,freeze_maxchance,freeze_minchance))))
{
if(freeze_player(target,owner,nadeTeam))
{
emit_sound(target,CHAN_ITEM,SOUND_FROZEN,1.0,ATTN_NONE,0,PITCH_LOW);
}
}
}
free_tr2(tr);
set_pev(ent,pev_flags,pev(ent,pev_flags)|FL_KILLME);
}
freeze_player(id,attacker,nadeTeam)
{
new fwdRetVal = PLUGIN_CONTINUE;
ExecuteForward(fnFwdPlayerFrozen, fwdRetVal, id, attacker);
if(fwdRetVal == PLUGIN_HANDLED || fwdRetVal == PLUGIN_HANDLED_MAIN)
{
return 0;
}
if(!isFrozen[id])
{
pev(id,pev_gravity,oldGravity[id]);
pev(id,pev_speed,oldSpeed[id]);
// register our forward only when we need it
if(!fmFwdPPT)
{
fmFwdPPT = register_forward(FM_PlayerPreThink,"fw_playerprethink",0);
}
}
isFrozen[id] = nadeTeam;
set_pev(id,pev_velocity,Float:{0.0,0.0,0.0});
set_user_chillfreeze_speed(id);
ice_entity(id, 1);
new Float:duration = get_pcvar_float(pcv_freeze_duration), Float:variance = get_pcvar_float(pcv_freeze_variance);
duration += random_float(-variance,variance);
remove_task(TASK_REMOVE_FREEZE+id);
set_task(duration,"task_remove_freeze",TASK_REMOVE_FREEZE+id);
new rgb[3];
get_rgb_colors(nadeTeam,rgb);
// glowshell
fm_set_rendering(id, kRenderFxGlowShell, rgb[0], rgb[1], rgb[2], kRenderNormal, 1);
// add a blue tint to their screen
message_begin(MSG_ONE,gmsgScreenFade,_,id);
write_short(floatround(4096.0 * duration)); // duration
write_short(floatround(3072.0 * duration)); // hold time (4096.0 * 0.75)
write_short(0x0000); // flags
write_byte(rgb[0]); // red
write_byte(rgb[1]); // green
write_byte(rgb[2]); // blue
write_byte(100); // alpha
message_end();
if(get_pcvar_num(pcv_icon) == ICON_ISCHILLED)
{
show_icon(id, STATUS_FLASH);
}
return 1;
}
public task_remove_freeze(taskid)
{
new id = taskid-TASK_REMOVE_FREEZE;
emit_sound(id,CHAN_ITEM,SOUND_UNFROZEN,VOL_NORM,ATTN_NORM,0,PITCH_LOW);
isFrozen[id] = 0;
// unregister forward if we are no longer using it
unregister_prethink();
if(!is_user_connected(id)) return;
// restore speed, but then check for chilled
ExecuteHam(Ham_Player_ResetMaxSpeed, id);
fm_set_rendering(id);
ice_entity(id, 0);
// calculate end of flashbang
new Float:flashedUntil = get_pdata_float(id,m_flFlashedUntil),
Float:flashHoldTime = get_pdata_float(id,m_flFlashHoldTime),
Float:endOfFlash = flashedUntil + (flashHoldTime * 0.67);
// not blinded
if(get_gametime() >= endOfFlash)
{
// clear tint
message_begin(MSG_ONE,gmsgScreenFade,_,id);
write_short(0); // duration
write_short(0); // hold time
write_short(0x0000); // flags
write_byte(63); // red
write_byte(148); // green
write_byte(233); // blue
write_byte(255); // alpha
message_end();
}
set_pev(id,pev_gravity,oldGravity[id]);
set_pev(id,pev_speed,oldSpeed[id]);
if(get_pcvar_num(pcv_icon) == ICON_ISCHILLED)
{
show_icon(id, STATUS_HIDE);
}
}
/****************************************
* UTILITY FUNCTIONS
****************************************/
// check if prethink is still being used, if not, unhook it
unregister_prethink()
{
if(fmFwdPPT)
{
new i;
for(i=1;i<=maxPlayers;i++) if(isFrozen) break;
if(i > maxPlayers)
{
unregister_forward(FM_PlayerPreThink,fmFwdPPT,0);
fmFwdPPT = 0;
}
}
}
// make the explosion effects
create_blast(team,Float:originF[3])
{
new rgb[3];
get_rgb_colors(team,rgb);
// Medium ring
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_BEAMCYLINDER) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]) // z
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
write_short(g_exploSpr) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(4) // life
write_byte(60) // width
write_byte(0) // noise
write_byte(rgb[0]) // red
write_byte(rgb[1]) // green
write_byte(rgb[2]) // blue
write_byte(200) // brightness
write_byte(0) // speed
message_end()
// Largest ring
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_BEAMCYLINDER) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]) // z
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
write_short(g_exploSpr) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(4) // life
write_byte(60) // width
write_byte(0) // noise
write_byte(rgb[0]) // red
write_byte(rgb[1]) // green
write_byte(rgb[2]) // blue
write_byte(200) // brightness
write_byte(0) // speed
message_end()
// Luz Dinamica
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_DLIGHT) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]) // z
write_byte(floatround(FROST_RADIUS/5.0));
write_byte(rgb[0]) // red
write_byte(rgb[1]) // green
write_byte(rgb[2]) // blue
write_byte(30) // vida en 0.1, 30 = 3 segundos
write_byte(30) // velocidad de decaimiento
message_end()
engfunc(EngFunc_MessageBegin, MSG_BROADCAST,SVC_TEMPENTITY, originF, 0)
write_byte(TE_EXPLOSION)
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2]+10) // z axis
write_short(g_explosfr)
write_byte(17)
write_byte(15)
write_byte(TE_EXPLFLAG_NOSOUND)
message_end();
engfunc(EngFunc_MessageBegin, MSG_BROADCAST,SVC_TEMPENTITY, originF, 0)
write_byte(TE_SPRITETRAIL) // TE ID
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2] + 40) // z axis
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2]) // z axis
write_short(frostgib) // Sprite Index
write_byte(30) // Count
write_byte(10) // Life
write_byte(4) // Scale
write_byte(50) // Velocity Along Vector
write_byte(10) // Rendomness of Velocity
message_end();
}
// give an entity a beam trail
set_beamfollow(ent,life,width,rgb[3],brightness)
{
clear_beamfollow(ent);
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_BEAMFOLLOW);
write_short(ent); // entity
write_short(trailSpr); // sprite
write_byte(life); // life
write_byte(width); // width
write_byte(rgb[0]); // red
write_byte(rgb[1]); // green
write_byte(rgb[2]); // blue
write_byte(brightness); // brightness
message_end();
}
// removes beam trails from an entity
clear_beamfollow(ent)
{
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_KILLBEAM);
write_short(ent); // entity
message_end();
}
// gets the appropriate color and displays the frostnade icon to the player with the given status
show_icon(id, status)
{
static rgb[3];
if(status) get_rgb_colors(_:cs_get_user_team(id), rgb); // only get colors if we need to
message_begin(MSG_ONE,gmsgStatusIcon,_,id);
write_byte(status); // status (0=hide, 1=show, 2=flash)
write_string("dmg_cold"); // sprite name
write_byte(rgb[0]); // red
write_byte(rgb[1]); // green
write_byte(rgb[2]); // blue
message_end();
}
// checks if a weapon id is included in fn_nadetypes
is_wid_in_nadetypes(wid)
{
new types = get_pcvar_num(pcv_nadetypes);
return ( (wid == CSW_HEGRENADE && (types & NT_HEGRENADE))
|| (wid == CSW_FLASHBANG && (types & NT_FLASHBANG))
|| (wid == CSW_SMOKEGRENADE && (types & NT_SMOKEGRENADE)) );
}
// checks if a player has a frostnade, taking into account fn_override and such.
// returns: STATUS_HIDE = no frostnade, STATUS_SHOW = has frostnade but not deployed, STATUS_FLASH = has frostnade and deployed
player_has_frostnade(id)
{
new retVal = STATUS_HIDE, curwpn = get_user_weapon(id);
// no override, variable explicitly set
if(hasFrostNade[id])
{
retVal = (curwpn == hasFrostNade[id] ? STATUS_FLASH : STATUS_SHOW);
}
// override enabled, and I'm on the right team
else if(get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)))
{
new types = get_pcvar_num(pcv_nadetypes);
if((types & NT_HEGRENADE) && cs_get_user_bpammo(id, CSW_HEGRENADE) > 0)
{
retVal = (curwpn == CSW_HEGRENADE ? STATUS_FLASH : STATUS_SHOW);
}
if(retVal != STATUS_FLASH && (types & NT_FLASHBANG) && cs_get_user_bpammo(id, CSW_FLASHBANG) > 0)
{
retVal = (curwpn == CSW_FLASHBANG ? STATUS_FLASH : STATUS_SHOW);
}
if(retVal != STATUS_FLASH && (types & NT_SMOKEGRENADE) && cs_get_user_bpammo(id, NT_SMOKEGRENADE) > 0)
{
retVal = (curwpn == NT_SMOKEGRENADE ? STATUS_FLASH : STATUS_SHOW);
}
}
return retVal;
}
// gets RGB colors from the cvar
get_rgb_colors(team,rgb[3])
{
static color[12], parts[3][4];
get_pcvar_string(pcv_color,color,11);
// if cvar is set to "team", use colors based on the given team
if(equali(color,"team",4))
{
if(team == 1)
{
rgb[0] = 150;
rgb[1] = 0;
rgb[2] = 0;
}
else
{
rgb[0] = 0;
rgb[1] = 0;
rgb[2] = 150;
}
}
else
{
parse(color,parts[0],3,parts[1],3,parts[2],3);
rgb[0] = str_to_num(parts[0]);
rgb[1] = str_to_num(parts[1]);
rgb[2] = str_to_num(parts[2]);
}
}
stock ice_entity( id, status )
{
if(status)
{
static ent, Float:fOrigin[3];
if(!is_user_alive(id))
{
ice_entity(id, 0);
return;
}
if(is_valid_ent(iceent[id]))
{
if(pev(iceent[id], pev_iuser3) != id)
{
if(pev(iceent[id], pev_team) == 6969)
remove_entity(iceent[id]);
}
else
{
pev(id, pev_origin, fOrigin);
if(pev(id, pev_flags) & FL_DUCKING)
{
fOrigin[2] -= 15.0;
}
else
{
fOrigin[2] -= 35.0;
}
entity_set_origin(iceent[id], fOrigin);
return;
}
}
pev(id, pev_origin, fOrigin);
if(pev(id, pev_flags) & FL_DUCKING)
{
fOrigin[2] -= 15.0;
}
else
{
fOrigin[2] -= 35.0;
}
ent = create_entity("info_target");
set_pev(ent, pev_classname, "IceCube");
entity_set_model(ent, ice_model);
dllfunc(DLLFunc_Spawn, ent);
set_pev(ent, pev_solid, SOLID_NOT);
set_pev(ent, pev_movetype, MOVETYPE_FLY);
entity_set_origin(ent, fOrigin);
entity_set_size(ent, Float:{-3.0, -3.0, -3.0}, Float:{3.0, 3.0, 3.0});
set_pev(ent, pev_iuser3, id);
set_pev(ent, pev_team, 6969);
set_rendering(ent, kRenderFxNone, 255, 255, 255, kRenderTransAdd, 255);
iceent[id] = ent;
}
else
{
if(is_valid_ent(iceent[id]))
{
if(pev(iceent[id], pev_team) == 6969)
remove_entity(iceent[id]);
iceent[id] = -1;
}
}
}
// scale a value equally (inversely?) with the distance that something
// is from the center of another thing. that makes pretty much no sense,
// so basically, the closer we are to the center of a ring, the higher
// our value gets.
//
// EXAMPLE: distance = 60.0, radius = 240.0, maxVal = 100.0, minVal = 20.0
// we are 0.75 (1.0-(60.0/240.0)) of the way to the radius, so scaled with our
// values, it comes out to 80.0 (20.0 + (0.75 * (100.0 - 20.0)))
Float:radius_calc(Float:distance,Float:radius,Float:maxVal,Float:minVal)
{
if(maxVal <= 0.0) return 0.0;
if(minVal >= maxVal) return minVal;
return minVal + ((1.0 - (distance / radius)) * (maxVal - minVal));
}
// sets a user's chilled/frozen speed if applicable
// (NOTE: does NOT reset his maxspeed if he is not chilled/frozen)
set_user_chillfreeze_speed(id)
{
if(isFrozen[id])
{
set_user_maxspeed(id, 1.0);
}
}
stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
{
new Float:RenderColor[3];
RenderColor[0] = float(r);
RenderColor[1] = float(g);
RenderColor[2] = float(b);
set_pev(entity, pev_renderfx, fx);
set_pev(entity, pev_rendercolor, RenderColor);
set_pev(entity, pev_rendermode, render);
set_pev(entity, pev_renderamt, float(amount));
return PLUGIN_HANDLED;
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1033\\ f0\\ fs16 \n\\ par }
*/