PHP Code:
/* Copyright © 2011, Gabe Newell
Grenade Tracing is free software;
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grenade Tracing; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
This plugin was made by request.
Credits: Revolution. http://www.gamedeception.net/threads/12759-Grenade-Tracing
*/
#include < amxmodx >
#include < fakemeta >
#include < xs >
#define NUMBLOOPS 20.0
#define TIMEALIVE 2.0
#define OLDDAMPER 1.75
#define NEWDAMPER 0.75
#define SVGRAVITY 3.75
#define FLOORSTOP 0.20
new spr_beam;
public plugin_init( )
{
register_plugin( "Grenade Tracing", "0.0.2", "Juice" );
register_concmd( "trace_grenade", "TraceGrenade" );
}
public plugin_precache()
{
spr_beam = precache_model( "sprites/laserbeam.spr" );
}
public TraceGrenade( id )
{
//new Float:dest[3];
new pmtrace = 0;
new Float:gravity = get_cvar_float("sv_gravity") / SVGRAVITY;
new Float:angThrow[ 3 ], Float:throwvector[ 3 ], Float:startpos[ 3 ], Float:endpos[ 3 ], Float:punchangle[ 3 ];
new Float:origin[ 3 ], Float:view_ofs[ 3 ];
new Float:pmEyePos[ 3 ], Float:pmVelocity[ 3 ];
pev( id, pev_velocity, pmVelocity );
pev( id, pev_punchangle, punchangle );
pev( id, pev_v_angle, angThrow );
pev( id ,pev_origin, origin );
pev( id, pev_view_ofs, view_ofs );
xs_vec_add( angThrow, punchangle, angThrow );
xs_vec_add( origin, view_ofs, pmEyePos );
if (angThrow[0] < 0)
angThrow[0] = -10 + angThrow[0] * ((90 - 10) / 90.0);
else
angThrow[0] = -10 + angThrow[0] * ((90 + 10) / 90.0);
new Float:flVel = (90 - angThrow[0]) * 6;
if (flVel > 500)
flVel = 500.0;
angle_vector( angThrow, ANGLEVECTOR_FORWARD, throwvector );
startpos[0] = pmEyePos[0] + throwvector[0] * 16;
startpos[1] = pmEyePos[1] + throwvector[1] * 16;
startpos[2] = pmEyePos[2] + throwvector[2] * 16;
throwvector[0] = throwvector[0] * flVel + pmVelocity[0];
throwvector[1] = throwvector[1] * flVel + pmVelocity[1];
throwvector[2] = throwvector[2] * flVel + pmVelocity[2];
new collisions = 0;
new Float:timelive;
new Float:step = (TIMEALIVE / NUMBLOOPS);
new ent;
new Float:plane_normal[3];
new Float:fraction;
for ( timelive = 0.0; timelive < TIMEALIVE; timelive += step )
{
endpos[0] = startpos[0] + throwvector[0] * step;
endpos[1] = startpos[1] + throwvector[1] * step;
endpos[2] = startpos[2] + throwvector[2] * step; //move
engfunc( EngFunc_TraceLine, startpos, endpos, DONT_IGNORE_MONSTERS, 0, pmtrace );
ent = get_tr2( pmtrace, TR_pHit )
get_tr2( pmtrace, TR_vecPlaneNormal, plane_normal );
get_tr2( pmtrace, TR_flFraction, fraction );
if( ent != id && fraction < 1.0 )
{
endpos[0] = startpos[0] + throwvector[0] * fraction * step;
endpos[1] = startpos[1] + throwvector[1] * fraction * step;
endpos[2] = startpos[2] + throwvector[2] * fraction * step;
/*
if ( plane_normal[2] > 0.9 && throwvector[2] <= 0 && throwvector[2] >= -gravity*FLOORSTOP )
{
dest[0] = endpos[0];
dest[1] = endpos[1];
dest[2] = endpos[2];
}
*/
message_begin( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, id );
write_byte( TE_SPARKS );
engfunc( EngFunc_WriteCoord, endpos[0] );
engfunc( EngFunc_WriteCoord, endpos[1] );
engfunc( EngFunc_WriteCoord, endpos[2] );
message_end();
new Float:proj = xs_vec_dot( throwvector, plane_normal );
throwvector[0] = (throwvector[0]*OLDDAMPER - proj*2*plane_normal[0]) * NEWDAMPER; //reflection off the wall
throwvector[1] = (throwvector[1]*OLDDAMPER - proj*2*plane_normal[1]) * NEWDAMPER;
throwvector[2] = (throwvector[2]*OLDDAMPER - proj*2*plane_normal[2]) * NEWDAMPER;
collisions++;
if (collisions > 30) break;
timelive -= (step * (1 - fraction));
}
BeamPoints( id, startpos, endpos );
startpos[0] = endpos[0];
startpos[1] = endpos[1];
startpos[2] = endpos[2];
throwvector[2] -= gravity * fraction * step; //gravity
}
//dest[0] = startpos[0];
//dest[1] = startpos[1];
//dest[2] = startpos[2];
return PLUGIN_HANDLED;
}
BeamPoints( id, Float:startpos[3], Float:endpos[3] )
{
message_begin( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, id );
write_byte( TE_BEAMPOINTS ) // type
engfunc( EngFunc_WriteCoord, startpos[0] ); // origin[1]
engfunc( EngFunc_WriteCoord, startpos[1] ); // origin[2]
engfunc( EngFunc_WriteCoord, startpos[2] ); // origin[3]
engfunc( EngFunc_WriteCoord, endpos[0] ); // origin2[1]
engfunc( EngFunc_WriteCoord, endpos[1] ); // origin2[2]
engfunc( EngFunc_WriteCoord, endpos[2] ); // origin2[3]
write_short( spr_beam ); // sprite index
write_byte( 0 ); // start frame
write_byte( 0 ); // framerate
write_byte( 30 ); // life in 0.1 sec
write_byte( 20 ); // width
write_byte( 0 ); // noise
write_byte( 0 ); // red
write_byte( 255 ); // green
write_byte( 0 ); // blue
write_byte( 255 ); // brightness
write_byte( 0 ); // speed
message_end()
}