Code:
#include <amxmodx>
#include <fakemeta>
#include <xs>
new SpriteIndex;
public plugin_init()
{
register_clcmd( "test", "test" );
SpriteIndex = engfunc( EngFunc_PrecacheModel, "sprites/laserbeam.spr" );
}
public test( id )
{
new Float:value = getWallThickness( id );
server_print( "Wall thickness = %f", value );
}
Float:getWallThickness( const player )
{
/* TRACELINE #1 : Player's eyes to wall. */
server_print( "START TRACELINE #1" );
new Float:source[3], Float:direction[3], Float:end[3], Float:endOrig[3];
new Float:fraction;
// Get eyes position
pev( player, pev_origin, source );
pev( player, pev_view_ofs, direction );
xs_vec_add( source, direction, source );
// Get eyes direction
pev( player, pev_v_angle, direction );
engfunc( EngFunc_MakeVectors, direction );
global_get( glb_v_forward, direction );
// Get the end direction from eyes
xs_vec_mul_scalar( direction, 9999.0, end );
xs_vec_add( source, end, end );
engfunc( EngFunc_TraceLine, source, end, IGNORE_MONSTERS, player, 0 );
// Get the fraction of the trace
get_tr2( 0, TR_flFraction, fraction );
// No hit
if( fraction == 1.0 )
{
return 0.0;
}
/* TRACELINE #2 : Inside wall to behind wall to check if there is free space*/
server_print( "START TRACELINE #2" );
// Get the end position the trace hits.
get_tr2( 0, TR_vecEndPos, end );
//get_tr2( 0, TR_vecPlaneNormal, direction );
drawBeam( source, end, 200, 50, 50 );
// Save this position so we can calculate the thickness later.
endOrig = end;
// Get new start position by moving inside the wall a bit.
xs_vec_mul_scalar( direction, 2.0, direction );
xs_vec_add( end, direction, source );
// Get the end position from inside the wall to far behind.
xs_vec_mul_scalar( direction, 9999.0, direction );
xs_vec_add( source, direction, end );
engfunc( EngFunc_TraceLine, source, end, IGNORE_MONSTERS | IGNORE_GLASS, player, 0 );
// Get the fraction of the trace
get_tr2( 0, TR_flFraction, fraction );
// No hit or no free space
if( fraction == 1.0 || get_tr2( 0, TR_AllSolid ) )
{
return 0.0;
}
/* TRACELINE #3 : From behind the wall to back inside the wall to know the */
server_print( "START TRACELINE #3" );
// The end position of the next trace is the start position of the previous trace.
// Get the end position the trace hits which is the start position of next trace.
end = source;
get_tr2( 0, TR_vecEndPos, source );
drawBeam( source, end, 50, 200, 50 );
engfunc( EngFunc_TraceLine, source, end, IGNORE_MONSTERS | IGNORE_GLASS, player, 0 );
// Get the end position just behind the wall.
get_tr2( 0, TR_vecEndPos, end );
drawBeam( source, end, 50, 50, 200 );
// Get the thickness of the wall.
return vector_distance( end, endOrig );
}
drawBeam( const Float:start[3], const Float:end[3], r, g, b )
{
#define write_coord_f(%0) ( engfunc( EngFunc_WriteCoord, %0 ) )
message_begin( MSG_BROADCAST, SVC_TEMPENTITY );
write_byte( TE_BEAMPOINTS );
write_coord_f( start[0] );
write_coord_f( start[1] );
write_coord_f( start[2] );
write_coord_f( end[0] );
write_coord_f( end[1] );
write_coord_f( end[2] );
write_short( SpriteIndex );
write_byte( 0 );
write_byte( 0 );
write_byte( 255 );
write_byte( 20 );
write_byte( 0 );
write_byte( r );
write_byte( g );
write_byte( b );
write_byte( 150 );
write_byte( 0 );
message_end();
}