Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

Баг с покупкой гранаты в bio_frostnades

Статус пользователя strelok93
сообщение 30.10.2014, 23:29
Сообщение #1


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Всем привет! Помогите исправить баг в плагине bio_frostnades.
Если купить фрост гранату, играя за зомбака, она купится, но выбрать ее нельзя, но в следующем раунде, когда я человек, граната у меня как бы куплена ( снежинка на скрине ) Но гранаты фактически нету.
Так же еще раз гранату купить не выходит - пишет что граната уже есть. Так вот, надо как то это профиксить) Например запрещать зомбакам покупать гранаты вообще.



bio_frostnades

Код:
#include <amxmodx>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <biohazard>

new const VERSION[] = "2.00-bh2.0";

#define AMMO_FLASHBANG 11
#define AMMO_HEGRENADE 12
#define AMMO_SMOKEGRENADE 13
#define OFFSET_SHIELD 510
#define HAS_SHIELD (1<<24)
#define USING_SHIELD (1<<16)
#define DMG_GRENADE (1<<24) // thanks arkshine
#define FFADE_IN 0x0000 // just here so we don't pass 0 into the function
#define BREAK_GLASS 0x01

#define FROST_RADIUS 240.0
#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 TASK_REMOVE_CHILL 100
#define TASK_REMOVE_FREEZE 200
#define TASK_NADE_EXPLODE 300



new pcv_enabled, pcv_override, pcv_nadetypes, pcv_teams, pcv_price, pcv_roundlimit, pcv_buyzone, pcv_color,
pcv_by_radius, pcv_hitself, pcv_los, pcv_maxdamage, pcv_mindamage, pcv_chill_maxchance, pcv_chill_minchance,
pcv_chill_duration, pcv_chill_variance, pcv_chill_speed, pcv_freeze_maxchance, pcv_freeze_minchance,
pcv_freeze_duration, pcv_freeze_variance;

new maxPlayers, gmsgCurWeapon, gmsgScreenFade, gmsgStatusIcon, gmsgBlinkAcct, gmsgAmmoPickup, gmsgTextMsg,
gmsgWeapPickup, glassGibs, trailSpr, smokeSpr, exploSpr, czero, bot_quota, czBotHams, fwdPPT;

new isChilled[33], isFrozen[33], frostKilled[33], novaDisplay[33], Float:oldGravity[33], hasFrostNade[33],
boughtThisRound[33];

public plugin_init() {
register_plugin("FrostNades",VERSION,"Avalanche");
register_cvar("fn_version",VERSION,FCVAR_SERVER);
is_biomod_active() ? plugin_init2() : pause("ad")
}

public plugin_init2()
{
pcv_enabled = register_cvar("fn_enabled","1");
pcv_override = register_cvar("fn_override","1");
pcv_nadetypes = register_cvar("fn_nadetypes","1"); // NT_SMOKEGRENADE
pcv_teams = register_cvar("fn_teams","3");
pcv_price = register_cvar("fn_price","300");
pcv_roundlimit = register_cvar("fn_roundlimit","0");
pcv_buyzone = register_cvar("fn_buyzone","1");
pcv_color = register_cvar("fn_color","0 206 209");

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_maxdamage = register_cvar("fn_maxdamage","20.0");
pcv_mindamage = register_cvar("fn_mindamage","1.0");
pcv_chill_maxchance = register_cvar("fn_chill_maxchance","100.0");
pcv_chill_minchance = register_cvar("fn_chill_minchance","100.0");
pcv_chill_duration = register_cvar("fn_chill_duration","7.0");
pcv_chill_variance = register_cvar("fn_chill_variance","1.0");
pcv_chill_speed = register_cvar("fn_chill_speed","60.0");
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");


new mod[6];
get_modname(mod,5);
if(equal(mod,"czero"))
{
czero = 1;
bot_quota = get_cvar_pointer("bot_quota");
}

maxPlayers = get_maxplayers();
gmsgCurWeapon = get_user_msgid("CurWeapon");
gmsgScreenFade = get_user_msgid("ScreenFade");
gmsgStatusIcon = get_user_msgid("StatusIcon");
gmsgBlinkAcct = get_user_msgid("BlinkAcct");
gmsgAmmoPickup = get_user_msgid("AmmoPickup");
gmsgWeapPickup = get_user_msgid("WeapPickup");
gmsgTextMsg = get_user_msgid("TextMsg");

register_event("HLTV","event_new_round","a","1=0","2=0"); // new round
register_logevent("event_round_end",2,"0=World triggered","1=Round_End");

register_forward(FM_SetModel,"fw_setmodel",1);
register_message(get_user_msgid("DeathMsg"),"msg_deathmsg");

register_event("CurWeapon","event_curweapon","b","1=1");
register_event("AmmoX","event_ammox","b","1=11","1=12","1=13"); // flash, HE, smoke

RegisterHam(Ham_Killed,"player","ham_player_killed",1);
RegisterHam(Ham_Think,"grenade","ham_grenade_think",0);

register_clcmd("say /fn","buy_frostnade");
register_clcmd("say_team /fn","buy_frostnade");
register_clcmd("say /frostnade","buy_frostnade");
register_clcmd("say_team /frostnade","buy_frostnade");
}

public plugin_precache()
{
precache_model("models/frostnova.mdl");
glassGibs = precache_model("models/glassgibs.mdl");

precache_sound("warcraft3/frostnova.wav"); // grenade explodes
precache_sound("warcraft3/impalehit.wav"); // player is frozen
precache_sound("warcraft3/impalelaunch1.wav"); // frozen wears off
precache_sound("player/pl_duct2.wav"); // player is chilled
precache_sound("items/gunpickup2.wav"); // player buys frostnade

trailSpr = precache_model("sprites/laserbeam.spr");
smokeSpr = precache_model("sprites/steam1.spr");
exploSpr = precache_model("sprites/shockwave.spr");
}

public client_putinserver(id)
{
isChilled[id] = 0;
isFrozen[id] = 0;
frostKilled[id] = 0;
novaDisplay[id] = 0;
oldGravity[id] = 1.0;
hasFrostNade[id] = 0;
boughtThisRound[id] = 0;

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(isChilled[id]) task_remove_chill(TASK_REMOVE_CHILL+id);
if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
}

// 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_Killed,id,"ham_player_killed",1);
czBotHams = 1;
}
}

/****************************************
* PRIMARY FUNCTIONS AND SUCH
****************************************/

public buy_frostnade(id)
{
if(!get_pcvar_num(pcv_enabled) || get_pcvar_num(pcv_override))
return PLUGIN_CONTINUE;

if(!is_user_alive(id)) return PLUGIN_HANDLED;

// Bipbip : zombie cant buy fn
if (is_user_zombie(id)) return PLUGIN_HANDLED;

if(get_pcvar_num(pcv_buyzone) && !cs_get_user_buyzone(id))
{
client_print(id,print_center,"You are not in a buy zone."); // #Cstrike_NotInBuyZone won't work
return PLUGIN_HANDLED;
}

if(!(get_pcvar_num(pcv_teams) & _:cs_get_user_team(id)))
{
// have to do it this way to format
message_begin(MSG_ONE,gmsgTextMsg,_,id);
write_byte(print_center);
write_string("#Alias_Not_Avail");
write_string("Frost Grenade");
message_end();

return PLUGIN_HANDLED;
}

if(hasFrostNade[id])
{
client_print(id,print_center,"#Cstrike_Already_Own_Weapon");
return PLUGIN_HANDLED;
}

new limit = get_pcvar_num(pcv_roundlimit);
if(limit && boughtThisRound[id] >= limit)
{
client_print(id,print_center,"#Cstrike_TitlesTXT_Cannot_Carry_Anymore");
return PLUGIN_HANDLED;
}

new money = cs_get_user_money(id), price = get_pcvar_num(pcv_price);

// need more vespene gas
if(money < price)
{
client_print(id,print_center,"#Cstrike_TitlesTXT_Not_Enough_Money");

message_begin(MSG_ONE_UNRELIABLE,gmsgBlinkAcct,_,id);
write_byte(2);
message_end();

return PLUGIN_HANDLED;
}

// try to use smokegrenade, then flashbang, then hegrenade
new wpnid = CSW_SMOKEGRENADE, ammoid = AMMO_SMOKEGRENADE, wpnName[20] = "weapon_smokegrenade", type = get_pcvar_num(pcv_nadetypes);
if(!(type & NT_SMOKEGRENADE))
{
if(type & NT_FLASHBANG)
{
wpnid = CSW_FLASHBANG;
ammoid = AMMO_FLASHBANG;
wpnName = "weapon_flashbang";
}
else if(type & NT_HEGRENADE)
{
wpnid = CSW_HEGRENADE;
ammoid = AMMO_HEGRENADE;
wpnName = "weapon_hegrenade";
}
}

hasFrostNade[id] = wpnid;
boughtThisRound[id]++;
cs_set_user_money(id,money - price);

new ammo = cs_get_user_bpammo(id,wpnid);

// give him one
if(!ammo) ham_give_weapon(id,wpnName);
else
{
cs_set_user_bpammo(id,wpnid,ammo+1);

// just so the player can see what kind it is on his HUD

message_begin(MSG_ONE,gmsgAmmoPickup,_,id);
write_byte(ammoid);
write_byte(ammo+1);
message_end();

message_begin(MSG_ONE,gmsgWeapPickup,_,id);
write_byte(wpnid);
message_end();
}

// won't play via ham_give_weapon or cs_set_user_bpammo
engfunc(EngFunc_EmitSound,id,CHAN_ITEM,"items/gunpickup2.wav",VOL_NORM,ATTN_NORM,0,PITCH_NORM);

return PLUGIN_HANDLED;
}

// new round starts
public event_new_round()
{
if(!get_pcvar_num(pcv_enabled)) return;

for(new i=1;i<=maxPlayers;i++)
{
boughtThisRound[i] = 0;

if(is_user_alive(i))
{
if(isChilled[i]) task_remove_chill(TASK_REMOVE_CHILL+i);
if(isFrozen[i]) task_remove_freeze(TASK_REMOVE_FREEZE+i);
}
}
}

// the round ends
public event_round_end()
{
if(!get_pcvar_num(pcv_enabled)) return;

for(new i=1;i<=maxPlayers;i++)
{
if(is_user_alive(i))
{
if(isChilled[i]) task_remove_chill(TASK_REMOVE_CHILL+i);
if(isFrozen[i]) task_remove_freeze(TASK_REMOVE_FREEZE+i);
}
}
}

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)))
{
hasFrostNade[owner] = 0;

set_pev(ent,pev_team,team);
set_pev(ent,pev_bInDuck,1); // flag it as a frostnade

new Float:rgb[3];
get_rgb_colors(team,rgb);

set_glowshell(ent,rgb,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

engfunc(EngFunc_SetClientMaxspeed,id,0.00001); // keep immobile

new Float:gravity;
pev(id,pev_gravity,gravity);

// 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;
}

// override grenade kill message with skull and crossbones
public msg_deathmsg(msg_id,msg_dest,msg_entity)
{
new victim = get_msg_arg_int(2);
if(!is_user_connected(victim) || !frostKilled[victim]) return PLUGIN_CONTINUE;

static weapon[8];
get_msg_arg_string(4,weapon,7);
if(equal(weapon,"grenade")) set_msg_arg_string(4,"frostgrenade");

frostKilled[victim] = 0;
return PLUGIN_CONTINUE;
}

// maintain speed on weapon changes
public event_curweapon(id)
{
if(get_pcvar_num(pcv_enabled) && is_user_connected(id))
{
manage_icon(id);
if(isChilled[id]) set_maxspeed(id);
}
}

// a player's grenade ammo changes
public event_ammox(id)
{
if(get_pcvar_num(pcv_enabled) && is_user_connected(id))
manage_icon(id);
}

// killed to death
public ham_player_killed(id)
{
hasFrostNade[id] = 0;
manage_icon(id);

if(isChilled[id]) task_remove_chill(TASK_REMOVE_CHILL+id);
if(isFrozen[id]) task_remove_freeze(TASK_REMOVE_FREEZE+id);
}

// grenade is ticking away
public ham_grenade_think(ent)
{

// not a frostnade
if(!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 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(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_SMOKE);
write_coord(floatround(nadeOrigin[0])); // x
write_coord(floatround(nadeOrigin[1])); // y
write_coord(floatround(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_BODY,"warcraft3/frostnova.wav",VOL_NORM,ATTN_NORM,0,PITCH_NORM);

// cache our cvars
new Float:by_radius = get_pcvar_float(pcv_by_radius),
hitself = get_pcvar_num(pcv_hitself), los = get_pcvar_num(pcv_los), Float:maxdamage = get_pcvar_float(pcv_maxdamage),
Float:mindamage = get_pcvar_float(pcv_mindamage), Float:chill_maxchance = get_pcvar_float(pcv_chill_maxchance),
Float:chill_minchance = get_pcvar_float(pcv_chill_minchance), 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, Float:damage, gotFrozen;
for(new target=1;target<=maxPlayers;target++)
{
// dead, invincible, or self attack that is not allowed
if(!is_user_alive(target) || !is_user_zombie(target) || pev(target,pev_takedamage) == DAMAGE_NO
|| (pev(target,pev_flags) & FL_GODMODE) ||(target == owner && !hitself))
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;
}

// damaged
if(maxdamage > 0.0)
{
damage = radius_calc(distance,FROST_RADIUS,maxdamage,mindamage);
if(ta) damage /= 2.0; // half damage for friendlyfire

if(damage > 0.0)
{
frostKilled[target] = 1;
ExecuteHamB(Ham_TakeDamage,target,ent,owner,damage,DMG_GRENADE);
if(!is_user_alive(target)) continue; // dead now
frostKilled[target] = 0;
}
}

// 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))
))
{
gotFrozen = 1;

freeze_player(target,nadeTeam);
emit_sound(target,CHAN_BODY,"warcraft3/impalehit.wav",VOL_NORM,ATTN_NORM,0,PITCH_HIGH);
}
else gotFrozen = 0;

// chilled
if(by_radius || random_num(1,100) <= floatround(radius_calc(distance,FROST_RADIUS,chill_maxchance,chill_minchance)))
{
chill_player(target,nadeTeam);
if(!gotFrozen) emit_sound(target,CHAN_BODY,"player/pl_duct2.wav",VOL_NORM,ATTN_NORM,0,PITCH_LOW);
}
}

free_tr2(tr);
set_pev(ent,pev_flags,pev(ent,pev_flags)|FL_KILLME);
}

freeze_player(id,nadeTeam)
{
isFrozen[id] = nadeTeam;
oldGravity[id] = get_class_data(get_user_class(id), DATA_GRAVITY);

// register our forward only when we need it
if(!fwdPPT) fwdPPT = register_forward(FM_PlayerPreThink,"fw_playerprethink",0);

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);

if(!pev_valid(novaDisplay[id])) create_nova(id);
}

public task_remove_freeze(taskid)
{
new id = taskid-TASK_REMOVE_FREEZE;

if(pev_valid(novaDisplay[id]))
{
new origin[3], Float:originF[3];
pev(novaDisplay[id],pev_origin,originF);
FVecIVec(originF,origin);

// add some tracers
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_IMPLOSION);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2] + 8); // z
write_byte(64); // radius
write_byte(10); // count
write_byte(3); // duration
message_end();

// add some sparks
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_SPARKS);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2]); // z
message_end();

// add the shatter
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_BREAKMODEL);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2] + 24); // z
write_coord(16); // size x
write_coord(16); // size y
write_coord(16); // size z
write_coord(random_num(-50,50)); // velocity x
write_coord(random_num(-50,50)); // velocity y
write_coord(25); // velocity z
write_byte(10); // random velocity
write_short(glassGibs); // model
write_byte(10); // count
write_byte(25); // life
write_byte(BREAK_GLASS); // flags
message_end();

emit_sound(novaDisplay[id],CHAN_BODY,"warcraft3/impalelaunch1.wav",VOL_NORM,ATTN_NORM,0,PITCH_LOW);
set_pev(novaDisplay[id],pev_flags,pev(novaDisplay[id],pev_flags)|FL_KILLME);
}

isFrozen[id] = 0;
novaDisplay[id] = 0;

// unregister forward if we are no longer using it
if(fwdPPT)
{
new i;
for(i=1;i<=maxPlayers;i++) if(isFrozen[i]) break;
if(i > maxPlayers)
{
unregister_forward(FM_PlayerPreThink,fwdPPT,0);
fwdPPT = 0;
}
}

if(!is_user_connected(id)) return;

set_maxspeed(id);
set_pev(id,pev_gravity,oldGravity[id]);

// sometimes trail fades during freeze, reapply
if(isChilled[id])
{
new Float:rgb[3];
get_rgb_colors(isChilled[id],rgb);
set_beamfollow(id,30,8,rgb,100);
}
else
{
// let other plugins change speed if they need to
new clip, weapon = get_user_weapon(id,clip);
emessage_begin(MSG_ONE,gmsgCurWeapon,_,id);
ewrite_byte(1); // is current
ewrite_byte(weapon); // weapon id
ewrite_byte(clip); // clip ammo
emessage_end();
}
}

chill_player(id,nadeTeam)
{
isChilled[id] = nadeTeam;

set_maxspeed(id);

new Float:duration = get_pcvar_float(pcv_chill_duration), Float:variance = get_pcvar_float(pcv_chill_variance);
duration += random_float(-variance,variance);

remove_task(TASK_REMOVE_CHILL+id);
set_task(duration,"task_remove_chill",TASK_REMOVE_CHILL+id);

new Float:rgb[3];
get_rgb_colors(nadeTeam,rgb);

set_glowshell(id,rgb,1.0);
set_beamfollow(id,30,8,rgb,100);

// add a blue tint to their screen
message_begin(MSG_ONE,gmsgScreenFade,_,id);
write_short(floatround(4096.0 * duration)); // duration
write_short(floatround(2867.2 * duration)); // hold time (4096.0 * 0.7)
write_short(FFADE_IN); // flags
write_byte(floatround(rgb[0])); // red
write_byte(floatround(rgb[1])); // green
write_byte(floatround(rgb[2])); // blue
write_byte(100); // alpha
message_end();
}

public task_remove_chill(taskid)
{
new id = taskid-TASK_REMOVE_CHILL;

isChilled[id] = 0;
if(!is_user_connected(id)) return;

set_maxspeed(id);

clear_glowshell(id);
clear_beamfollow(id);

// clear tint (might clear a flashbang?)
message_begin(MSG_ONE,gmsgScreenFade,_,id);
write_short(0); // duration
write_short(0); // hold time
write_short(FFADE_IN); // flags
write_byte(0); // red
write_byte(0); // green
write_byte(0); // blue
write_byte(255); // alpha
message_end();

if(!isFrozen[id])
{
// let other plugins change speed if they need to
new clip, weapon = get_user_weapon(id,clip);
emessage_begin(MSG_ONE,gmsgCurWeapon,_,id);
ewrite_byte(1); // is current
ewrite_byte(weapon); // weapon id
ewrite_byte(clip); // clip ammo
emessage_end();
}
}

// set my maxspeed to whatever it should be
set_maxspeed(id)
{
if(isFrozen[id]) return engfunc(EngFunc_SetClientMaxspeed,id,0.00001);

new Float:speed = get_class_data(get_user_class(id), DATA_SPEED);
if(isChilled[id]) speed *= (get_pcvar_float(pcv_chill_speed) / 100.0);
return engfunc(EngFunc_SetClientMaxspeed,id,speed);
}

// make a frost nova at a player's feet
create_nova(id)
{
new nova = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,"info_target"));

engfunc(EngFunc_SetSize,nova,Float:{-8.0,-8.0,-4.0},Float:{8.0,8.0,4.0});
engfunc(EngFunc_SetModel,nova,"models/frostnova.mdl");

// random orientation
new Float:angles[3];
angles[1] = random_float(0.0,360.0);
set_pev(nova,pev_angles,angles);

// put it at their feet
new Float:playerMins[3], Float:novaOrigin[3];
pev(id,pev_mins,playerMins);
pev(id,pev_origin,novaOrigin);
novaOrigin[2] += playerMins[2];
engfunc(EngFunc_SetOrigin,nova,novaOrigin);

// make it translucent
get_rgb_colors(isFrozen[id],angles); // let's just use angles
set_pev(nova,pev_rendercolor,angles); // ^
set_pev(nova,pev_rendermode,kRenderTransColor);
set_pev(nova,pev_renderamt,100.0);

novaDisplay[id] = nova;
}

// manage our snowflake (show it, hide it, flash it?)
manage_icon(id)
{
new status, team = _:cs_get_user_team(id);

// so if I have it, status = 1; if I also have it out, status = 2
if(get_pcvar_num(pcv_enabled))
{
if(hasFrostNade[id])
{
status = 1;
if(get_user_weapon(id) == hasFrostNade[id]) status = 2;
}
else if(get_pcvar_num(pcv_override) && (get_pcvar_num(pcv_teams) & team))
{
new weapon = get_user_weapon(id), types = get_pcvar_num(pcv_nadetypes);

if(types & NT_HEGRENADE)
{
if(cs_get_user_bpammo(id,CSW_HEGRENADE))
{
status = 1;
if(weapon == CSW_HEGRENADE) status = 2;
}
}
if(status != 2 && (types & NT_SMOKEGRENADE))
{
if(cs_get_user_bpammo(id,CSW_SMOKEGRENADE))
{
status = 1;
if(weapon == CSW_SMOKEGRENADE) status = 2;
}
}
if(status != 2 && (types & NT_FLASHBANG))
{
if(cs_get_user_bpammo(id,CSW_FLASHBANG))
{
status = 1;
if(weapon == CSW_FLASHBANG) status = 2;
}
}
}
}

new Float:rgb[3];
if(status) get_rgb_colors(team,rgb); // only get colors if we need to

message_begin(MSG_ONE_UNRELIABLE,gmsgStatusIcon,_,id);
write_byte(status); // status (0=hide, 1=show, 2=flash)
write_string("dmg_cold"); // sprite name
write_byte(floatround(rgb[0])); // red
write_byte(floatround(rgb[1])); // green
write_byte(floatround(rgb[2])); // blue
message_end();
}

/****************************************
* UTILITY FUNCTIONS
****************************************/

// make the explosion effects
create_blast(team,Float:originF[3])
{
new origin[3];
FVecIVec(originF,origin);

new Float:rgbF[3], rgb[3];
get_rgb_colors(team,rgbF);
FVecIVec(rgbF,rgb);

// smallest ring
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2]); // z
write_coord(origin[0]); // x axis
write_coord(origin[1]); // y axis
write_coord(origin[2] + 385); // z axis
write_short(exploSpr); // sprite
write_byte(0); // start frame
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(100); // brightness
write_byte(0); // speed
message_end();

// medium ring
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2]); // z
write_coord(origin[0]); // x axis
write_coord(origin[1]); // y axis
write_coord(origin[2] + 470); // z axis
write_short(exploSpr); // sprite
write_byte(0); // start frame
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(100); // brightness
write_byte(0); // speed
message_end();

// largest ring
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2]); // z
write_coord(origin[0]); // x axis
write_coord(origin[1]); // y axis
write_coord(origin[2] + 555); // z axis
write_short(exploSpr); // sprite
write_byte(0); // start frame
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(100); // brightness
write_byte(0); // speed
message_end();

// light effect
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_byte(TE_DLIGHT);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2]); // z
write_byte(floatround(FROST_RADIUS/5.0)); // radius
write_byte(rgb[0]); // r
write_byte(rgb[1]); // g
write_byte(rgb[2]); // b
write_byte(8); // life
write_byte(60); // decay rate
message_end();
}

// give an entity a glowshell
set_glowshell(ent,Float:rgb[3],Float:amount)
{
set_pev(ent,pev_renderfx,kRenderFxGlowShell);
set_pev(ent,pev_rendercolor,rgb);
set_pev(ent,pev_renderamt,amount);
}

// take away the glowshell
clear_glowshell(ent)
{
set_pev(ent,pev_renderfx,kRenderFxNone);
set_pev(ent,pev_rendercolor,Float:{255.0,255.0,255.0});
set_pev(ent,pev_renderamt,16.0);
}

// give an entity a beam trail
set_beamfollow(ent,life,width,Float: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(floatround(rgb[0])); // red
write_byte(floatround(rgb[1])); // green
write_byte(floatround(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 RGB colors from the cvar
get_rgb_colors(team,Float: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.0;
rgb[1] = 0.0;
rgb[2] = 0.0;
}
else
{
rgb[0] = 0.0;
rgb[1] = 0.0;
rgb[2] = 150.0;
}
}
else
{
parse(color,parts[0],3,parts[1],3,parts[2],3);
rgb[0] = floatstr(parts[0]);
rgb[1] = floatstr(parts[1]);
rgb[2] = floatstr(parts[2]);
}
}

// 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));
}

// gives a player a weapon efficiently
stock ham_give_weapon(id,weapon[])
{
if(!equal(weapon,"weapon_",7)) return 0;

new wEnt = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,weapon));
if(!pev_valid(wEnt)) return 0;

set_pev(wEnt,pev_spawnflags,SF_NORESPAWN);
dllfunc(DLLFunc_Spawn,wEnt);

if(!ExecuteHamB(Ham_AddPlayerItem,id,wEnt))
{
if(pev_valid(wEnt)) set_pev(wEnt,pev_flags,pev(wEnt,pev_flags) | FL_KILLME);
return 0;
}

ExecuteHamB(Ham_Item_AttachToPlayer,wEnt,id)
return 1;
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/



Прикрепленный файл  bio_frostnades.sma ( 28,03 килобайт ) Кол-во скачиваний: 30
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя strelok93
сообщение 31.10.2014, 8:07
Сообщение #2


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

up
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя AndrewZ
сообщение 31.10.2014, 9:38
Сообщение #3


Иконка группы

Стаж: 18 лет
Город: Санкт-Петербург


Сообщений: 4700
Благодарностей: 2452
Полезность: 1018

strelok93,
а нельзя купить гранату, если ты зомби. Там проверочка стоит.


Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя strelok93
сообщение 31.10.2014, 9:58
Сообщение #4


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Цитата(AndrewZ @ 31.10.2014, 10:38) *
strelok93,
а нельзя купить гранату, если ты зомби. Там проверочка стоит.

Она и не дается тебе) Пишу в чат /fn чтобы купить фрост гранату, деньги снимаются, звук возпроизводится как будто гранату купил, появляется снежинка а гранаты нету. И потом в след. раунде когда я человек вот такой вот баг.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя strelok93
сообщение 31.10.2014, 19:40
Сообщение #5


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Я неправильно баг описал blush2.gif
Если человек купал фрост гранату, не использовал ее и его заразили, то в следующем раунде ( если он не умрет ) будет этот баг. Снежинка есть - гранаты нету!

Отредактировал: strelok93, - 31.10.2014, 20:07
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя strelok93
сообщение 1.11.2014, 10:48
Сообщение #6


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Цитата(AndrewZ @ 31.10.2014, 10:38) *
strelok93,
а нельзя купить гранату, если ты зомби. Там проверочка стоит.

Ошибся я) Когда человеком играешь покупаешь гранату, потом тебя заражают и она так и остается у зомбака, а в следующем раунде
снежинка у тебя горит, а гранаты нету и купить ее нельзя sad.gif

Отредактировал: strelok93, - 1.11.2014, 10:48
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Stimul1
сообщение 1.11.2014, 11:01
Сообщение #7


Стаж: 13 лет

Сообщений: 227
Благодарностей: 262
Полезность: 977

strelok93, в biohazard.inc есть форвард, который вызывается при заражении?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя strelok93
сообщение 1.11.2014, 11:11
Сообщение #8


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Цитата(Stimul1 @ 1.11.2014, 12:01) *
strelok93, в biohazard.inc есть форвард, который вызывается при заражении?

Хрен его знает smile.gif
Вроде 27 строка
biohazard.inc

Код:
/* Biohazard functions
*
* by Cheap_Suit
*
* This file is provided as is (no warranties).
*/

#if defined _biohazard_included
#endinput
#endif
#define _biohazard_included

#pragma reqlib "biohazardf"

/* Returns the mods status */
stock is_biomod_active()
{
if(!cvar_exists("bh_enabled"))
{
log_amx("Cvar: ^"bh_enabled^" does not exist.")
return 0
}
return get_cvar_num("bh_enabled")
}

/* Called when a survivor is infected */
forward event_infect(victim, attacker)

/* Called when the game starts */
forward event_gamestart()

/* Returns true if the game has started */
native bool:game_started()

/* Makes a user zombie */
native infect_user(victim, attacker)

/* Makes a user human */
native cure_user(index)

/* Infect user before game starts */
native preinfect_user(index, bool:yesno)

/* Returns 1 if user is a zombie */
native is_user_zombie(index)

/* Returns 1 if the user is infected (before game)*/
native is_user_infected(index)

/* Returns user zombie class */
native get_user_class(index)

/* Returns zombie class id, -1 otherwise */
native register_class(classname[], description[])

/* Sets zombie player model */
native set_class_pmodel(classid, player_model[])

/* Sets zombie weapon model */
native set_class_wmodel(classid, weapon_model[])

/* Returns zombie class id */
native get_class_id(classname[])

#define DATA_HEALTH 0 //Health value
#define DATA_SPEED 1 //Speed value
#define DATA_GRAVITY 2 //Gravity multiplier
#define DATA_ATTACK 3 //Zombie damage multiplier
#define DATA_DEFENCE 4 //Bullet damage multiplier
#define DATA_HEDEFENCE 5 //HE damage multiplier
#define DATA_HITSPEED 6 //Pain speed multiplier
#define DATA_HITDELAY 7 //Pain speed delay value
#define DATA_REGENDLY 8 //Regeneration delay value
#define DATA_HITREGENDLY 9 //Pain regeneration delay value
#define DATA_KNOCKBACK 10 //Knockback multiplier

/* Return/set value of zombie class data */
native Float:get_class_data(classid, dataid)
native set_class_data(classid, dataid, Float:value)



Отредактировал: strelok93, - 1.11.2014, 11:12
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Stimul1
сообщение 1.11.2014, 12:16
Сообщение #9


Стаж: 13 лет

Сообщений: 227
Благодарностей: 262
Полезность: 977

strelok93, попробуй добавить в конец плагина:
Код:
public event_infect(victim, attacker)
{
if(is_user_connected(victim))
{
if(user_has_weapon(victim, CSW_HEGRENADE))
{
ham_strip_weapon(victim, "weapon_hegrenade");
hasFrostNade[victim] = 0;
manage_icon(victim);

if(isChilled[victim])
task_remove_chill(TASK_REMOVE_CHILL + victim);

if(isFrozen[victim])
task_remove_freeze(TASK_REMOVE_FREEZE + victim);
}
else if(user_has_weapon(victim, CSW_FLASHBANG))
{
ham_strip_weapon(victim, "weapon_flashbang");
hasFrostNade[victim] = 0;
manage_icon(victim);

if(isChilled[victim])
task_remove_chill(TASK_REMOVE_CHILL + victim);

if(isFrozen[victim])
task_remove_freeze(TASK_REMOVE_FREEZE + victim);
}
else if(user_has_weapon(victim, CSW_SMOKEGRENADE))
{
ham_strip_weapon(victim, "weapon_smokegrenade");
hasFrostNade[victim] = 0;
manage_icon(victim);

if(isChilled[victim])
task_remove_chill(TASK_REMOVE_CHILL + victim);

if(isFrozen[victim])
task_remove_freeze(TASK_REMOVE_FREEZE + victim);
}
}

stock ham_strip_weapon(id, weapon[])
{
if(!equal(weapon, "weapon_", 7))
return 0;

new wId = get_weaponid(weapon);

if(!wId)
return 0;

new wEnt;

while((wEnt = engfunc(EngFunc_FindEntityByString, wEnt, "classname", weapon)) && pev(wEnt,pev_owner) != id) {}

if(!wEnt)
return 0;

if(get_user_weapon(id) == wId)
ExecuteHamB(Ham_Weapon_RetireWeapon, wEnt);

if(!ExecuteHamB(Ham_RemovePlayerItem, id, wEnt))
return 0;

ExecuteHamB(Ham_Item_Kill, wEnt);

set_pev(id, pev_weapons, pev(id, pev_weapons) & ~(1<<wId))

return 1;
}


Отредактировал: Stimul1, - 1.11.2014, 12:21
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя strelok93
сообщение 1.11.2014, 12:30
Сообщение #10


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Цитата(Stimul1 @ 1.11.2014, 13:16) *
strelok93, попробуй добавить в конец плагина:
Скрытый текст

Код:
public event_infect(victim, attacker)
{
if(is_user_connected(victim))
{
if(user_has_weapon(victim, CSW_HEGRENADE))
{
ham_strip_weapon(victim, "weapon_hegrenade");
hasFrostNade[victim] = 0;
manage_icon(victim);

if(isChilled[victim])
task_remove_chill(TASK_REMOVE_CHILL + victim);

if(isFrozen[victim])
task_remove_freeze(TASK_REMOVE_FREEZE + victim);
}
else if(user_has_weapon(victim, CSW_FLASHBANG))
{
ham_strip_weapon(victim, "weapon_flashbang");
hasFrostNade[victim] = 0;
manage_icon(victim);

if(isChilled[victim])
task_remove_chill(TASK_REMOVE_CHILL + victim);

if(isFrozen[victim])
task_remove_freeze(TASK_REMOVE_FREEZE + victim);
}
else if(user_has_weapon(victim, CSW_SMOKEGRENADE))
{
ham_strip_weapon(victim, "weapon_smokegrenade");
hasFrostNade[victim] = 0;
manage_icon(victim);

if(isChilled[victim])
task_remove_chill(TASK_REMOVE_CHILL + victim);

if(isFrozen[victim])
task_remove_freeze(TASK_REMOVE_FREEZE + victim);
}
}

stock ham_strip_weapon(id, weapon[])
{
if(!equal(weapon, "weapon_", 7))
return 0;

new wId = get_weaponid(weapon);

if(!wId)
return 0;

new wEnt;

while((wEnt = engfunc(EngFunc_FindEntityByString, wEnt, "classname", weapon)) && pev(wEnt,pev_owner) != id) {}

if(!wEnt)
return 0;

if(get_user_weapon(id) == wId)
ExecuteHamB(Ham_Weapon_RetireWeapon, wEnt);

if(!ExecuteHamB(Ham_RemovePlayerItem, id, wEnt))
return 0;

ExecuteHamB(Ham_Item_Kill, wEnt);

set_pev(id, pev_weapons, pev(id, pev_weapons) & ~(1<<wId))

return 1;
}

Спасибо! Все работает thank_you2.gif
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя strelok93
сообщение 1.11.2014, 17:30
Сообщение #11


Стаж: 12 лет

Сообщений: 905
Благодарностей: 392
Полезность: 576

Чтобы не создавать новую тему, попрошу помочь еще с HE гранатами под BioHazard smile.gif
Люди получают урон от гранаты. Надо чтобы граната могла ранить/убить только зомби.
Есть квар который запрещает/разрешает наносить урон союзникам, но себе урон наносится в любом случае. sad.gif
Так же было бы круто исправить функцию покупки гранаты командой в чат: /napalm
Есть квар: napalm_override 0 // Если включено, гранаты будут автоматически становиться напамповыми
Если 0 - то при старте раунда граната которая дается бесплатно будет обычной, но написав /napalm купится напалмовая граната.
Если napalm_override 1, то купить гранату будет нельзя, но дефолтная граната будет напалмовой.
Надо чтобы дефолтная граната была напалмовой, и чтобы ее можно было купить еще раз после использования командой /napalm
bio_napalm_nades.sma

Код:
/*===============================================================================
=

--------------------------------------------
-*- Napalm Nades 1.3 (Biohazard version) -*-
--------------------------------------------

~~~~~~~~~~~~~~~
- Description -
~~~~~~~~~~~~~~~

This plugin turns one of the default grenades into a napalm bomb that
can set players on fire. Basically a CS port of the "fire grenades"
I originally developed for Zombie Plague, at the request of some people
and since there were no similiar plugins around. Have fun!

~~~~~~~~~~~~~~~~
- Requirements -
~~~~~~~~~~~~~~~~

* Mods: Counter-Strike 1.6 or Condition-Zero
* AMXX: Version 1.8.0 or later

~~~~~~~~~~~~~~~~
- Installation -
~~~~~~~~~~~~~~~~

* Extract .amxx file to your plugins folder, and add its name to plugins.ini
* Extract flame.spr to the "sprites" folder on your server
* To change models or sounds, open up the .sma with any text editor and look
for the customization section. When you're done, recompile.

~~~~~~~~~~~~
- Commands -
~~~~~~~~~~~~

* say /napalm - Buy a napalm grenade (when override is off)

~~~~~~~~~
- CVARS -
~~~~~~~~~

* napalm_on <0/1> - Enable/Disable Napalm Nades
* napalm_affect <1/2/3> - Which nades should be napalms (1-HE // 2-FB // 3-SG)
* napalm_team <0/1/2> - Determines which team can buy/use napalm nades
(0-both teams // 1-Terrorists only // 2-CTs only)
* napalm_override <0/1> - If enabled, grenades will automatically become
napalms without players having to buy them
* napalm_price <1000> - Money needed to buy a napalm (when override is off)
* napalm_buyzone <0/1> - If enabled, players need to be in a buyzone to
purchase a napalm (when override is off)
* napalm_carrylimit <1> - How many napalms can be carried at once

* napalm_radius <240> - Napalm explosion radius
* napalm_hitself <0/1> - If enabled, napalms will also affect their owner
* napalm_ff <0/1> - If enabled, napalms will also affect teammates
* napalm_spread <0/1> - If enabled, players will be able to catch fire
from others when they touch
* napalm_keepexplosion <0/1> - Wether to keep the default CS explosion

* napalm_duration <5> - How long the burning lasts in seconds
* napalm_damage <2> - How much damage the burning does (every 0.2 secs)
* napalm_cankill <0/1> - If set, burning will be able to kill the victim
* napalm_slowdown <0.5> - Burning slow down, set between: 0.1 (slower) and
0.9 (faster). Use 0 to disable.
* napalm_screamrate <20> - How often players will scream when on fire
(lower values = more screams). Use 0 to disable.

~~~~~~~~~~~~~
- Changelog -
~~~~~~~~~~~~~

* v1.0: (Jul 26, 2008)
- First release

* v1.1: (Aug 15, 2008)
- Grenades now explode based on their pev_dmgtime (means the
plugin is now compatible with Nade Modes)
- Changed method to identify napalm nades when override is off
- Fire spread feature now fully working with CZ bots

* v1.1b: (Aug 23, 2008)
- Optimized bandwidth usage for temp entity messages

* v1.1c: (Aug 26, 2008)
- Fixed possible bugs with plugins that change a player's team
after throwing a napalm nade

* v1.2: (Oct 05, 2008)
- Added a few cvars that allow more customization
- Optimized the code a bit
- Fixed a bug where buying 2 napalms too quick would sometimes
result in the second acting as a normal nade

* v1.3: (Feb 17, 2009)
- Added ability to carry multiple napalms at once (+CVAR)

* v1.3a: (Mar 16, 2009)
- Code optimized (+CVARs now cached at round start)

================================================================================
*/

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#include <biohazard>

/*===============================================================================
=
[Plugin Customization]
================================================================================
=*/

// Uncomment the following if you wish to set custom models for napalms
//#define USE_NAPALM_CUSTOM_MODELS

#if defined USE_NAPALM_CUSTOM_MODELS // Then set your custom models here
new const g_model_napalm_view[] = "models/v_hegrenade"
new const g_model_napalm_player[] = "models/p_hegrenade.mdl"
new const g_model_napalm_world[] = "models/w_hegrenade.mdl"
#endif

// Explosion sounds
new const grenade_fire[][] = { "weapons/hegrenade-1.wav" }

// Player burning sounds
new const grenade_fire_player[][] = { "biohazard/zombie_burn3.wav", "biohazard/zombie_burn4.wav", "biohazard/zombie_burn3.wav" }

// Grenade sprites
new const sprite_grenade_fire[] = "sprites/flame.spr"
new const sprite_grenade_smoke[] = "sprites/black_smoke3.spr"
new const sprite_grenade_trail[] = "sprites/laserbeam.spr"
new const sprite_grenade_ring[] = "sprites/shockwave.spr"

// Glow and trail colors (red, green, blue)
const NAPALM_R = 200
const NAPALM_G = 0
const NAPALM_B = 0

/*===============================================================================
*/

#define TEAM_ZOMBIE 1
#define TEAM_HUMAN 2

// Burning task
const TASK_BURN = 1000
#define ID_BURN (taskid - TASK_BURN)
#define BURN_DURATION args[0]
#define BURN_ATTACKER args[1]

// CS Player PData Offsets (win32)
const OFFSET_CSTEAMS = 114
const OFFSET_CSMONEY = 115
const OFFSET_MAPZONE = 235
new const AFFECTED_BPAMMO_OFFSETS[] = { 388, 387, 389 }
const OFFSET_LINUX = 5 // offsets +5 in Linux builds

// CS Player CBase Offsets (win32)
const OFFSET_ACTIVE_ITEM = 373

// CS Weapon PData Offsets (win32)
const OFFSET_WEAPONID = 43
const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux

// CS Weapon CBase Offsets (win32)
const OFFSET_WEAPONOWNER = 41

// Some constants
const PLAYER_IN_BUYZONE = (1<<0)

// pev_ field used to store custom nade types and their values
const PEV_NADE_TYPE = pev_flTimeStepSound
const NADE_TYPE_NAPALM = 681856

// pev_ field used to store napalm's custom ammo
const PEV_NAPALM_AMMO = pev_flSwimTime

// Weapons that can be napalms
new const AFFECTED_NAMES[][] = { "HE", "FB", "SG" }
new const AFFECTED_CLASSNAMES[][] = { "weapon_hegrenade", "weapon_flashbang", "weapon_smokegrenade" }
new const AFFECTED_MODELS[][] = { "w_he", "w_fl", "w_sm" }
new const AFFECTED_AMMOID[] = { 12, 11, 13 }
#if defined USE_NAPALM_CUSTOM_MODELS
new const AFFECTED_WEAPONS[] = { CSW_HEGRENADE, CSW_FLASHBANG, CSW_SMOKEGRENADE }
#endif

// CS Sounds
new const sound_buyammo[] = "items/9mmclip1.wav"

// Whether ham forwards are registered for CZ bots
new g_hamczbots

// Precached sprites indices
new g_flameSpr, g_smokeSpr, g_trailSpr, g_exploSpr

// Messages
new g_msgDamage, g_msgMoney, g_msgBlinkAcct, g_msgAmmoPickup

// CVAR pointers
new cvar_radius, cvar_price, cvar_hitself, cvar_duration, cvar_slowdown, cvar_override,
cvar_damage, cvar_on, cvar_buyzone, cvar_ff, cvar_cankill, cvar_spread, cvar_botquota,
cvar_teamrestrict, cvar_screamrate, cvar_keepexplosion, cvar_affect, cvar_carrylimit

// Cached stuff
new g_maxplayers, g_on, g_affect, g_override, g_allowedteam, g_keepexplosion, g_spread,
g_ff, g_duration, g_buyzone, g_price, g_carrylimit, g_hitself, g_screamrate, g_damage,
Float:g_slowdown, g_cankill, Float:g_radius

// Precache all custom stuff
public plugin_precache()
{
precache_sound("biohazard/zombie_burn3.wav")
precache_sound("biohazard/zombie_burn4.wav")
new i
for (i = 0; i < sizeof grenade_fire; i++)
engfunc(EngFunc_PrecacheSound, grenade_fire[i])
for (i = 0; i < sizeof grenade_fire_player; i++)
engfunc(EngFunc_PrecacheSound, grenade_fire_player[i])

g_flameSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_fire)
g_smokeSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_smoke)
g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)
g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)

// CS sounds (just in case)
engfunc(EngFunc_PrecacheSound, sound_buyammo)

#if defined USE_NAPALM_CUSTOM_MODELS
engfunc(EngFunc_PrecacheModel, g_model_napalm_view)
engfunc(EngFunc_PrecacheModel, g_model_napalm_player)
engfunc(EngFunc_PrecacheModel, g_model_napalm_world)
#endif
}

public plugin_init()
{
// Register plugin call
register_plugin("Napalm Nades for Bio", "1.3a", "MeRcyLeZZ")

// Events
register_event("HLTV", "event_round_start", "a", "1=0", "2=0")

// Forwards
register_forward(FM_SetModel, "fw_SetModel")
RegisterHam(Ham_Think, "grenade", "fw_ThinkGrenade")
RegisterHam(Ham_Touch, "player", "fw_TouchPlayer")
#if defined USE_NAPALM_CUSTOM_MODELS
for (new i = 0; i < sizeof AFFECTED_CLASSNAMES; i++)
RegisterHam(Ham_Item_Deploy, AFFECTED_CLASSNAMES[i], "fw_Item_Deploy_Post", 1)
#endif

// Client commands
register_clcmd("say napalm", "buy_napalm")
register_clcmd("say /napalm", "buy_napalm")

// CVARS
cvar_on = register_cvar("napalm_on", "1")
cvar_affect = register_cvar("napalm_affect", "1")
cvar_teamrestrict = register_cvar("napalm_team", "2")
cvar_override = register_cvar("napalm_override", "0")
cvar_price = register_cvar("napalm_price", "1000")
cvar_buyzone = register_cvar("napalm_buyzone", "1")
cvar_carrylimit = register_cvar("napalm_carrylimit", "1")

cvar_radius = register_cvar("napalm_radius", "240")
cvar_hitself = register_cvar("napalm_hitself", "1")
cvar_ff = register_cvar("napalm_ff", "0")
cvar_spread = register_cvar("napalm_spread", "1")
cvar_keepexplosion = register_cvar("napalm_keepexplosion", "0")

cvar_duration = register_cvar("napalm_duration", "5")
cvar_damage = register_cvar("napalm_damage", "2")
cvar_cankill = register_cvar("napalm_cankill", "1")
cvar_slowdown = register_cvar("napalm_slowdown", "0.5")
cvar_screamrate = register_cvar("napalm_screamrate", "20")

cvar_botquota = get_cvar_pointer("bot_quota")
g_maxplayers = get_maxplayers()

// Message ids
g_msgDamage = get_user_msgid("Damage")
g_msgMoney = get_user_msgid("Money")
g_msgBlinkAcct = get_user_msgid("BlinkAcct")
g_msgAmmoPickup = get_user_msgid("AmmoPickup")
}

public plugin_cfg()
{
// Cache CVARs after configs are loaded
set_task(0.5, "event_round_start")
}

// Round Start Event
public event_round_start()
{
// Cache CVARs
g_on = get_pcvar_num(cvar_on)
g_affect = get_pcvar_num(cvar_affect)
g_override = get_pcvar_num(cvar_override)
g_allowedteam = get_pcvar_num(cvar_teamrestrict)
g_keepexplosion = get_pcvar_num(cvar_keepexplosion)
g_spread = get_pcvar_num(cvar_spread)
g_ff = get_pcvar_num(cvar_ff)
g_duration = get_pcvar_num(cvar_duration)
g_buyzone = get_pcvar_num(cvar_buyzone)
g_price = get_pcvar_num(cvar_price)
g_carrylimit = get_pcvar_num(cvar_carrylimit)
g_hitself = get_pcvar_num(cvar_hitself)
g_screamrate = get_pcvar_num(cvar_screamrate)
g_slowdown = get_pcvar_float(cvar_slowdown)
g_damage = floatround(get_pcvar_float(cvar_damage), floatround_ceil)
g_cankill = get_pcvar_num(cvar_cankill)
g_radius = get_pcvar_float(cvar_radius)

// Stop any burning tasks on players
for (new id = 1; id <= g_maxplayers; id++)
remove_task(id+TASK_BURN);
}

// Client joins the game
public client_putinserver(id)
{
// CZ bots seem to use a different "classtype" for player entities
// (or something like that) which needs to be hooked separately
if (!g_hamczbots && cvar_botquota && is_user_bot(id))
{
// Set a task to let the private data initialize
set_task(0.1, "register_ham_czbots", id)
}
}

// Set Model Forward
public fw_SetModel(entity, const model[])
{
// Napalm grenades disabled
if (!g_on) return FMRES_IGNORED;

// Get damage time of grenade
static Float:dmgtime
pev(entity, pev_dmgtime, dmgtime)

// Grenade not yet thrown
if (dmgtime == 0.0)
return FMRES_IGNORED;

// Not an affected grenade
if (!equal(model[7], AFFECTED_MODELS[g_affect-1], 4))
return FMRES_IGNORED;

// Get owner of grenade and napalm weapon entity
static owner, napalm_weaponent
owner = pev(entity, pev_owner)
napalm_weaponent = fm_get_user_current_weapon_ent(owner)

// Not a napalm grenade (because the weapon entity of its owner doesn't have the flag set)
if (!g_override && pev(napalm_weaponent, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
return FMRES_IGNORED;

// Get owner's team
static owner_team
owner_team = fm_get_user_team(owner)

// Player is on a restricted team
if (g_allowedteam > 0 && g_allowedteam != owner_team)
return FMRES_IGNORED;

// Give it a glow
fm_set_rendering(entity, kRenderFxGlowShell, NAPALM_R, NAPALM_G, NAPALM_B, kRenderNormal, 16)

// And a colored trail
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BEAMFOLLOW) // TE id
write_short(entity) // entity
write_short(g_trailSpr) // sprite
write_byte(10) // life
write_byte(10) // width
write_byte(NAPALM_R) // r
write_byte(NAPALM_G) // g
write_byte(NAPALM_B) // b
write_byte(200) // brightness
message_end()

// Reduce napalm ammo
static napalm_ammo
napalm_ammo = pev(napalm_weaponent, PEV_NAPALM_AMMO)
set_pev(napalm_weaponent, PEV_NAPALM_AMMO, --napalm_ammo)

// Run out of napalms?
if (napalm_ammo < 1)
{
// Remove napalm flag from the owner's weapon entity
set_pev(napalm_weaponent, PEV_NADE_TYPE, 0)
}

// Set grenade type on the thrown grenade entity
set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_NAPALM)

// Set owner's team on the thrown grenade entity
set_pev(entity, pev_team, owner_team)

#if defined USE_NAPALM_CUSTOM_MODELS
// Set custom model and supercede the original forward
engfunc(EngFunc_SetModel, entity, g_model_napalm_world)
return FMRES_SUPERCEDE;
#else
return FMRES_IGNORED;
#endif
}

// Grenade Think Forward
public fw_ThinkGrenade(entity)
{
// Invalid entity
if (!pev_valid(entity)) return HAM_IGNORED;

// Get damage time of grenade
static Float:dmgtime
pev(entity, pev_dmgtime, dmgtime)

// Check if it's time to go off
if (dmgtime > get_gametime())
return HAM_IGNORED;

// Not a napalm grenade
if (pev(entity, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
return HAM_IGNORED;

// Explode event
napalm_explode(entity)

// Keep the original explosion?
if (g_keepexplosion)
{
set_pev(entity, PEV_NADE_TYPE, 0)
return HAM_IGNORED;
}

// Get rid of the grenade
engfunc(EngFunc_RemoveEntity, entity)
return HAM_SUPERCEDE;
}

// Player Touch Forward
public fw_TouchPlayer(self, other)
{
// Spread cvar disabled or not touching a player
if (!g_spread || !is_user_alive(other))
return;

// Toucher not on fire or touched player already on fire
if (!task_exists(self+TASK_BURN) || task_exists(other+TASK_BURN))
return;

// Check if friendly fire is allowed
if (!g_ff && fm_get_user_team(self) == fm_get_user_team(other))
return;

// Heat icon
message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, other)
write_byte(0) // damage save
write_byte(0) // damage take
write_long(DMG_BURN) // damage type
write_coord(0) // x
write_coord(0) // y
write_coord(0) // z
message_end()

// Our task params
static params[2]
params[0] = g_duration * 2 // duration (reduced a bit)
params[1] = self // attacker

// Set burning task on victim
set_task(0.1, "burning_flame", other+TASK_BURN, params, sizeof params)
}

#if defined USE_NAPALM_CUSTOM_MODELS
// Ham Weapon Deploy Forward
public fw_Item_Deploy_Post(entity)
{
// Napalm grenades disabled
if (!g_on) return;

// Not a napalm grenade (because the weapon entity of its owner doesn't have the flag set)
if (!g_override && pev(entity, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
return;

// Get weapon's id
static weaponid
weaponid = fm_get_weapon_ent_id(entity)

// Not an affected grenade
if (weaponid != AFFECTED_WEAPONS[g_affect-1])
return;

// Get weapon's owner
static owner
owner = fm_get_weapon_ent_owner(entity)

// Player is on a restricted team
if (g_allowedteam > 0 && g_allowedteam != fm_get_user_team(owner))
return;

// Replace models
set_pev(owner, pev_viewmodel2, g_model_napalm_view)
set_pev(owner, pev_weaponmodel2, g_model_napalm_player)
}
#endif

// Napalm purchase command
public buy_napalm(id)
{
// Napalm grenades disabled
if (!g_on) return PLUGIN_CONTINUE;

// Check if override setting is enabled instead
if (g_override)
{
client_print(id, print_center, "Just buy a %s grenade and get a napalm automatically!", AFFECTED_NAMES[g_affect-1])
return PLUGIN_HANDLED;
}

// Check if player is alive
if (!is_user_alive(id))
{
client_print(id, print_center, "You can't buy when you're dead!")
return PLUGIN_HANDLED;
}

// Check if the player is on a restricted team
if (g_allowedteam > 0 && g_allowedteam != fm_get_user_team(id))
{
client_print(id, print_center, "Your team cannot buy napalm nades!")
return PLUGIN_HANDLED;
}

// Check if player needs to be in a buyzone
if (g_buyzone && !fm_get_user_buyzone(id))
{
client_print(id, print_center, "You are not in a buyzone!")
return PLUGIN_HANDLED;
}

// Check that player has the money
if (fm_get_user_money(id) < g_price)
{
client_print(id, print_center, "#Cstrike_TitlesTXT_Not_Enough_Money")

// Blink money
message_begin(MSG_ONE_UNRELIABLE, g_msgBlinkAcct, _, id)
write_byte(2) // times
message_end()

return PLUGIN_HANDLED;
}

// Get napalm weapon entity
static napalm_weaponent
napalm_weaponent = fm_get_napalm_entity(id, g_affect)

// Does the player have a napalm already?
if (napalm_weaponent != 0)
{
// Retrieve napalm ammo
static napalm_ammo
napalm_ammo = pev(napalm_weaponent, PEV_NAPALM_AMMO)

// Check if allowed to have this many napalms
if (napalm_ammo < g_carrylimit)
{
// Increase napalm ammo
set_pev(napalm_weaponent, PEV_NAPALM_AMMO, ++napalm_ammo)

// Increase player's backpack ammo
set_pdata_int(id, AFFECTED_BPAMMO_OFFSETS[g_affect-1], get_pdata_int(id, AFFECTED_BPAMMO_OFFSETS[g_affect-1]) + 1, OFFSET_LINUX)

// Flash ammo in hud
message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
write_byte(AFFECTED_AMMOID[g_affect-1]) // ammo id
write_byte(1) // ammo amount
message_end()

// Play clip purchase sound
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)

// Set napalm flag on the weapon entity (bugfix)
set_pev(napalm_weaponent, PEV_NADE_TYPE, NADE_TYPE_NAPALM)
}
else
{
client_print(id, print_center, "You cannot carry any more napalms!")
return PLUGIN_HANDLED;
}
}
else
{
// Give napalm
fm_give_item(id, AFFECTED_CLASSNAMES[g_affect-1])

// Get napalm weapon entity now it exists
napalm_weaponent = fm_get_napalm_entity(id, g_affect)

// Set napalm flag on the weapon entity
set_pev(napalm_weaponent, PEV_NADE_TYPE, NADE_TYPE_NAPALM)

// Set napalm ammo
set_pev(napalm_weaponent, PEV_NAPALM_AMMO, 1)
}

// Calculate new money amount
static newmoney
newmoney = fm_get_user_money(id) - g_price

// Update money offset
fm_set_user_money(id, newmoney)

// Update money on HUD
message_begin(MSG_ONE, g_msgMoney, _, id)
write_long(newmoney) // amount
write_byte(1) // flash
message_end()

return PLUGIN_HANDLED;
}

// Napalm Grenade Explosion
napalm_explode(ent)
{
// Get attacker and its team
static attacker, attacker_team
attacker = pev(ent, pev_owner)
attacker_team = pev(ent, pev_team)

// Get origin
static Float:originF[3]
pev(ent, pev_origin, originF)

// Custom explosion effect
create_blast2(originF)

// Napalm explosion sound
engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_fire[random_num(0, sizeof grenade_fire - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)

// Collisions
static victim
victim = -1

while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, g_radius)) != 0)
{
// Only effect alive players
if (!is_user_alive(victim))
continue;

// Check if myself is allowed
if (!g_hitself && victim == attacker)
continue;

// Check if friendly fire is allowed
if (!g_ff && victim != attacker && attacker_team == fm_get_user_team(victim))
continue;

// Heat icon
message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
write_byte(0) // damage save
write_byte(0) // damage take
write_long(DMG_BURN) // damage type
write_coord(0) // x
write_coord(0) // y
write_coord(0) // z
message_end()

// Our task params
static params[2]
params[0] = g_duration * 5 // duration
params[1] = attacker // attacker

// Set burning task on victim
set_task(0.1, "burning_flame", victim+TASK_BURN, params, sizeof params)
}
}

// Burning Task
public burning_flame(args[2], taskid)
{
// Player died/disconnected
if (!is_user_alive(ID_BURN))
return;

// Get player origin and flags
static Float:originF[3], flags
pev(ID_BURN, pev_origin, originF)
flags = pev(ID_BURN, pev_flags)

// In water or burning stopped
if ((flags & FL_INWATER) || BURN_DURATION < 1)
{
// Smoke sprite
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_SMOKE) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]-50.0) // z
write_short(g_smokeSpr) // sprite
write_byte(random_num(15, 20)) // scale
write_byte(random_num(10, 20)) // framerate
message_end()

return;
}

// Randomly play burning sounds
if (g_screamrate > 0 && random_num(1, g_screamrate) == 1)
engfunc(EngFunc_EmitSound, ID_BURN, CHAN_VOICE, grenade_fire_player[random_num(0, sizeof grenade_fire_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)

// Fire slow down
if (g_slowdown > 0.0 && (flags & FL_ONGROUND))
{
static Float:velocity[3]
pev(ID_BURN, pev_velocity, velocity)
xs_vec_mul_scalar(velocity, g_slowdown, velocity)
set_pev(ID_BURN, pev_velocity, velocity)
}

// Get victim's health
static health
health = pev(ID_BURN, pev_health)

// Take damage from the fire
if (health - g_damage > 0)
set_pev(ID_BURN, pev_health, float(health - g_damage))
else if (g_cankill)
{
// Kill victim
ExecuteHamB(Ham_Killed, ID_BURN, BURN_ATTACKER, 0)

// Smoke sprite
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_SMOKE) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]-50.0) // z
write_short(g_smokeSpr) // sprite
write_byte(random_num(15, 20)) // scale
write_byte(random_num(10, 20)) // framerate
message_end()

return;
}

// Flame sprite
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_SPRITE) // TE id
engfunc(EngFunc_WriteCoord, originF[0]+random_float(-5.0, 5.0)) // x
engfunc(EngFunc_WriteCoord, originF[1]+random_float(-5.0, 5.0)) // y
engfunc(EngFunc_WriteCoord, originF[2]+random_float(-10.0, 10.0)) // z
write_short(g_flameSpr) // sprite
write_byte(random_num(5, 10)) // scale
write_byte(200) // brightness
message_end()

// Decrease task cycle count
BURN_DURATION -= 1;

// Keep sending flame messages
set_task(0.2, "burning_flame", taskid, args, sizeof args)
}

// Napalm Grenade: Fire Blast (originally made by Avalanche in Frostnades)
create_blast2(const Float:originF[3])
{
// Smallest 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]+385.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(200) // red
write_byte(100) // green
write_byte(0) // blue
write_byte(200) // brightness
write_byte(0) // speed
message_end()

// 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(200) // red
write_byte(50) // green
write_byte(0) // 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(200) // red
write_byte(0) // green
write_byte(0) // blue
write_byte(200) // brightness
write_byte(0) // speed
message_end()
}

// Register Ham Forwards for CZ bots
public register_ham_czbots(id)
{
// Make sure it's a CZ bot and it's still connected
if (g_hamczbots || !get_pcvar_num(cvar_botquota) || !is_user_connected(id))
return;

RegisterHamFromEntity(Ham_Touch, id, "fw_TouchPlayer")

// Ham forwards for CZ bots succesfully registered
g_hamczbots = true;
}

// Set entity's rendering type (from fakemeta_util)
stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
{
static Float:color[3]
color[0] = float®
color[1] = float(g)
color[2] = float(b)

set_pev(entity, pev_renderfx, fx)
set_pev(entity, pev_rendercolor, color)
set_pev(entity, pev_rendermode, render)
set_pev(entity, pev_renderamt, float(amount))
}

// Give an item to a player (from fakemeta_util)
stock fm_give_item(id, const item[])
{
static ent
ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item));
if (!pev_valid(ent)) return;

static Float:originF[3]
pev(id, pev_origin, originF);
set_pev(ent, pev_origin, originF);
set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
dllfunc(DLLFunc_Spawn, ent);

static save
save = pev(ent, pev_solid);
dllfunc(DLLFunc_Touch, ent, id);
if (pev(ent, pev_solid) != save)
return;

engfunc(EngFunc_RemoveEntity, ent);
}

// Find entity by its owner (from fakemeta_util)
stock fm_find_ent_by_owner(entity, const classname[], owner)
{
while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) {}

return entity;
}

// Finds napalm grenade weapon entity of a player
stock fm_get_napalm_entity(id, g_affect)
{
return fm_find_ent_by_owner(-1, AFFECTED_CLASSNAMES[g_affect-1], id);
}

// Get User Current Weapon Entity
stock fm_get_user_current_weapon_ent(id)
{
return get_pdata_cbase(id, OFFSET_ACTIVE_ITEM, OFFSET_LINUX);
}

// Get Weapon Entity's CSW_ ID
stock fm_get_weapon_ent_id(ent)
{
return get_pdata_int(ent, OFFSET_WEAPONID, OFFSET_LINUX_WEAPONS);
}

// Get Weapon Entity's Owner
stock fm_get_weapon_ent_owner(ent)
{
return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS);
}

// Get User Money
stock fm_get_user_money(id)
{
return get_pdata_int(id, OFFSET_CSMONEY, OFFSET_LINUX);
}

// Set User Money
stock fm_set_user_money(id, amount)
{
set_pdata_int(id, OFFSET_CSMONEY, amount, OFFSET_LINUX);
}

// Get User Team
stock fm_get_user_team(id)
{
return is_user_zombie(id) ? TEAM_ZOMBIE : TEAM_HUMAN;
//return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
}

// Returns whether user is in a buyzone
stock fm_get_user_buyzone(id)
{
if (get_pdata_int(id, OFFSET_MAPZONE) & PLAYER_IN_BUYZONE)
return 1;

return 0;
}



Прикрепленный файл  bio_napalm_nades.sma ( 28,18 килобайт ) Кол-во скачиваний: 14
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: