I've added percantual chance ... here's the code:
PHP Code:
#include <amxmodx>
#include <cstrike>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#define PLUGIN "Ricochet"
#define AUTHOR "OT"
#define VERSION "2.01"
#define MAX_PLAYERS 32
#define BS_IGNORE_WEAPONS (1<<CSW_KNIFE)
#define HIT_SHIELD 8
#define MAX_MONEY 16000
const BS_PISTOLS = ((1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE))
const BS_SHOTGUN = ((1<<CSW_XM1014)|(1<<CSW_M3))
const BS_SUBMGS = ((1<<CSW_MAC10)|(1<<CSW_UMP45)|(1<<CSW_MP5NAVY)|(1<<CSW_TMP)|(1<<CSW_P90))
const BS_RIFLES = ((1<<CSW_AUG)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_M249)|(1<<CSW_M4A1)|(1<<CSW_SG552)|(1<<CSW_AK47))
const BS_SNIPERS = ((1<<CSW_SCOUT)|(1<<CSW_SG550)|(1<<CSW_AWP)|(1<<CSW_G3SG1))
#define floatclamp(%1, %2, %3) Float:(%2 <= %1 <= %3) ? Float:(%1) : Float:(%1 <= %2) ? Float:(%2) : Float:(%3)
#define ANGLE_RIC_MAX_COS floatcos( (90.0 - floatclamp(get_pcvar_float(pcv_angles), 0.0, 90.0) ), degrees)
/*
C : concrete
D : dirt
G : grate - metal like
M : metal
N : snow
P : computer
S : slosh - noroi
T : tile - tigla
V : ventilation
W : wood
Y : glass
*/
new const material_array[] =
{
'C', 'D', 'G', 'M', 'N', 'P', 'S', 'T', 'V', 'W', 'Y'
}
#define MATERIAL_CONCRETE (1<<0)
#define MATERIAL_DIRT (1<<1)
#define MATERIAL_GRATE (1<<2)
#define MATERIAL_METAL (1<<3)
#define MATERIAL_SNOW (1<<4)
#define MATERIAL_COMPUTER (1<<5)
#define MATERIAL_SLOSH (1<<6)
#define MATERIAL_TILE (1<<7)
#define MATERIAL_VENTS (1<<8)
#define MATERIAL_WOOD (1<<9)
#define MATERIAL_GLASS (1<<10)
new const sounds[8][] =
{
"player/headshot1.wav",
"player/headshot2.wav",
"player/headshot3.wav",
"player/bhit_flesh-1.wav",
"player/bhit_kevlar-1.wav",
"player/bhit_helmet-1.wav",
"weapons/ric_metal-1.wav",
"weapons/ric_metal-2.wav"
}
new pcv_damage_percent
new pcv_angles
new pcv_chance
new pcv_pistols
new pcv_shotgun
new pcv_smgs
new pcv_rifles
new pcv_snipers
new pcv_tracers
new pcv_materials
new pcv_extramoney
new pcv_ff
new g_maxplayers
new decal_shot1
new last_ric_shooter[MAX_PLAYERS + 1] = {0, ...}
//stock beampoint
public plugin_precache()
{
for (new i=0;i<8;i++)
{
precache_sound(sounds[i])
}
//beampoint = precache_model("sprites/laserbeam.spr")
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_cvar("ricochet_version", VERSION, FCVAR_SERVER | FCVAR_SPONLY)
pcv_damage_percent = register_cvar("ric_damage_percent", "75")
pcv_angles = register_cvar("ric_angle", "30")
pcv_chance = register_cvar("ric_chance", "10")
pcv_tracers = register_cvar("ric_tracers", "1")
pcv_pistols = register_cvar("ric_pistols", "1")
pcv_shotgun = register_cvar("ric_shotguns", "1")
pcv_smgs = register_cvar("ric_smgs", "1")
pcv_rifles = register_cvar("ric_rifles", "1")
pcv_snipers = register_cvar("ric_snipers", "1")
pcv_materials = register_cvar("ric_materials", "2047")
pcv_extramoney = register_cvar("ric_money", "100")
pcv_ff = get_cvar_pointer("mp_friendlyfire")
RegisterHam(Ham_TraceAttack, "worldspawn", "fw_traceattack")
RegisterHam(Ham_TraceAttack, "func_breakable", "fw_traceattack")
RegisterHam(Ham_Killed, "player", "fw_killed", 1)
g_maxplayers = get_maxplayers()
decal_shot1 = engfunc( EngFunc_DecalIndex, "{shot1" )
}
public fw_killed(id, killer, gib)
{
if (killer == last_ric_shooter[id])
{
cs_set_user_money(killer, clamp(cs_get_user_money(killer) + get_pcvar_num(pcv_extramoney), 0, MAX_MONEY), 1)
}
return HAM_IGNORED
}
public fw_traceattack(ent, attacker, Float:damage, Float:direction[3], thdl, bits)
{
if (random(10) <= get_pcvar_num(pcv_chance)) {
if (!(1 <= attacker <= g_maxplayers))
return HAM_IGNORED
new weapon = get_user_weapon(attacker)
if (BS_IGNORE_WEAPONS & (1<<weapon))
return HAM_IGNORED
if (BS_PISTOLS & (1<<weapon) && !get_pcvar_num(pcv_pistols))
return HAM_IGNORED
if (BS_SHOTGUN & (1<<weapon) && !get_pcvar_num(pcv_shotgun))
return HAM_IGNORED
if (BS_SUBMGS & (1<<weapon) && !get_pcvar_num(pcv_smgs))
return HAM_IGNORED
if (BS_RIFLES & (1<<weapon) && !get_pcvar_num(pcv_rifles))
return HAM_IGNORED
if (BS_SNIPERS & (1<<weapon) && !get_pcvar_num(pcv_snipers))
return HAM_IGNORED
new Float:origin[3],Float:end[3], Float:start[3], trace, Float:fraction
pev(attacker, pev_origin, origin)
pev(attacker, pev_view_ofs, start)
xs_vec_add(origin, start, start)
get_tr2(thdl, TR_vecEndPos, end)
if (point_contents(end) == CONTENTS_SKY)
return HAM_IGNORED
trace = create_tr2()
engfunc(EngFunc_TraceLine, start, end, DONT_IGNORE_MONSTERS, attacker, trace)
get_tr2(trace, TR_flFraction, fraction)
if (is_breakable(ent) == 0)
{
new Float:virtualend[3], texture_name[64], texture_type
xs_vec_sub(end, start, virtualend)
xs_vec_mul_scalar(virtualend, 16000.0, virtualend)
xs_vec_add(virtualend, start, virtualend)
engfunc(EngFunc_TraceTexture, 0, start, virtualend, texture_name, charsmax(texture_name))
texture_type = dllfunc(DLLFunc_PM_FindTextureType, texture_name)
for (new i=0;i<sizeof(material_array);i++)
{
if (material_array[i] == texture_type)
{
if ( !(clamp(get_pcvar_num(pcv_materials), 0, power(2, sizeof(material_array)) - 1) & texture_type ) )
{
free_tr2(trace)
return HAM_IGNORED
}
break
}
}
}
else
{
free_tr2(trace)
return HAM_IGNORED
}
if (fraction != 1.0)
{
if (get_tr2(trace, TR_pHit) != 0)
{
if (1 <= get_tr2(trace, TR_pHit) <= g_maxplayers)
{
last_ric_shooter[get_tr2(trace, TR_pHit)] = 0
}
free_tr2(trace)
return HAM_IGNORED
}
else
{
get_tr2(trace, TR_vecPlaneNormal, origin)
get_tr2(trace, TR_vecEndPos, end)
xs_vec_sub(start, end, start)
xs_vec_normalize(start, start)
free_tr2(trace)
return (xs_vec_dot(start, origin) <= ANGLE_RIC_MAX_COS) ? HAM_SUPERCEDE : HAM_IGNORED
}
}
get_tr2(thdl, TR_vecPlaneNormal, origin)
xs_vec_sub(start, end, start)
xs_vec_normalize(start, start)
fraction = xs_vec_dot(start, origin)
if (fraction > ANGLE_RIC_MAX_COS)
{
free_tr2(trace)
return HAM_IGNORED
}
xs_vec_mul_scalar(origin, fraction, origin)
xs_vec_sub(origin, start, start)
xs_vec_mul_scalar(start, (1-(fraction*fraction))/xs_vec_len(start), start)
xs_vec_add(origin, start, origin)
xs_vec_mul_scalar(origin, 16000.0, origin)
xs_vec_add(origin, end, origin)
msg_ricochet(end)
engfunc(EngFunc_TraceLine, end, origin, DONT_IGNORE_MONSTERS, -1, trace)
get_tr2(trace, TR_vecEndPos, origin)
if (get_pcvar_num(pcv_tracers))
msg_tracer(end, origin)
new hit = get_tr2(trace, TR_pHit)
if (hit > -1)
{
ExecuteHamB(Ham_TraceAttack, hit, attacker, (damage * (floatclamp(get_pcvar_float(pcv_damage_percent), 0.0, 100.0)) / 100.0 ), end, trace, bits)
if (1 <= hit <= g_maxplayers)
{
if (cs_get_user_team(attacker) != cs_get_user_team(hit))
{
last_ric_shooter[hit] = attacker
new CsArmorType:armor
new hitgroup = get_tr2(trace, TR_iHitgroup)
cs_get_user_armor(hit, armor)
switch (hitgroup)
{
case HIT_SHIELD:
{
emit_sound(hit, CHAN_BODY, sounds[7 - random(2)], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
case HIT_HEAD:
{
if (armor == CS_ARMOR_VESTHELM)
{
emit_sound(hit, CHAN_BODY, sounds[5], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
else
{
emit_sound(hit, CHAN_BODY, sounds[random(3)], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
case HIT_STOMACH, HIT_CHEST:
{
if (armor == CS_ARMOR_KEVLAR || armor == CS_ARMOR_VESTHELM)
{
emit_sound(hit, CHAN_BODY, sounds[4], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
else
{
emit_sound(hit, CHAN_BODY, sounds[3], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
default:
{
emit_sound(hit, CHAN_BODY, sounds[3], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
}
else
{
if (get_pcvar_num(pcv_ff))
{
last_ric_shooter[hit] = attacker
new CsArmorType:armor
new hitgroup = get_tr2(trace, TR_iHitgroup)
cs_get_user_armor(hit, armor)
switch (hitgroup)
{
case HIT_SHIELD:
{
emit_sound(hit, CHAN_BODY, sounds[7 - random(2)], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
case HIT_HEAD:
{
if (armor == CS_ARMOR_VESTHELM)
{
emit_sound(hit, CHAN_BODY, sounds[5], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
else
{
emit_sound(hit, CHAN_BODY, sounds[random(3)], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
case HIT_STOMACH, HIT_CHEST:
{
if (armor == CS_ARMOR_KEVLAR || armor == CS_ARMOR_VESTHELM)
{
emit_sound(hit, CHAN_BODY, sounds[4], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
else
{
emit_sound(hit, CHAN_BODY, sounds[3], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
default:
{
emit_sound(hit, CHAN_BODY, sounds[3], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
}
else
{
emit_sound(hit, CHAN_BODY, sounds[4], VOL_NORM, ATTN_STATIC, 0, PITCH_NORM)
}
}
}
}
else
{
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_GUNSHOTDECAL)
engfunc(EngFunc_WriteCoord, origin[0])
engfunc(EngFunc_WriteCoord, origin[1])
engfunc(EngFunc_WriteCoord, origin[2])
write_short(0)
write_byte(decal_shot1 - random(5))
message_end()
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_SPARKS)
engfunc(EngFunc_WriteCoord, origin[0])
engfunc(EngFunc_WriteCoord, origin[1])
engfunc(EngFunc_WriteCoord, origin[2])
message_end()
}
free_tr2(trace)
}
return HAM_IGNORED
}
stock msg_ricochet(Float:origin[3])
{
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0)
write_byte(TE_ARMOR_RICOCHET)
engfunc(EngFunc_WriteCoord, origin[0])
engfunc(EngFunc_WriteCoord, origin[1])
engfunc(EngFunc_WriteCoord, origin[2])
write_byte(3)
message_end()
}
/*stock draw_line(Float:start[3], Float:end[3])
{
engfunc(EngFunc_MessageBegin, MSG_ALL, SVC_TEMPENTITY, Float:{0.0,0.0,0.0}, 0)
write_byte(TE_BEAMPOINTS)
engfunc(EngFunc_WriteCoord, start[0])
engfunc(EngFunc_WriteCoord, start[1])
engfunc(EngFunc_WriteCoord, start[2])
engfunc(EngFunc_WriteCoord, end[0])
engfunc(EngFunc_WriteCoord, end[1])
engfunc(EngFunc_WriteCoord, end[2])
write_short(beampoint)
write_byte(0)
write_byte(0)
write_byte(25)
write_byte(10)
write_byte(0)
write_byte(255)
write_byte(255)
write_byte(255)
write_byte(127)
write_byte(1)
message_end()
}*/
stock msg_tracer(Float: origin[3], Float: end[3])
{
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, origin, 0) // MSG_PAS MSG_BROADCAST
write_byte(TE_TRACER)
engfunc(EngFunc_WriteCoord, origin[0])
engfunc(EngFunc_WriteCoord, origin[1])
engfunc(EngFunc_WriteCoord, origin[2])
engfunc(EngFunc_WriteCoord, end[0])
engfunc(EngFunc_WriteCoord, end[1])
engfunc(EngFunc_WriteCoord, end[2])
message_end()
}
stock is_breakable(ent)
{
if (ent == 0)
return 0
if ((((entity_get_float(ent, EV_FL_health) > 0.0) || (entity_get_int(ent, EV_INT_rendermode) == 4)) && (entity_get_float(ent, EV_FL_takedamage) > 0.0) && !(entity_get_int(ent, EV_INT_spawnflags) & SF_BREAK_TRIGGER_ONLY)))
return 1
return 0
}