new laser; public plugin_precache(){ laser = precache_model("sprites/laserbeam.spr") } stock showGrenadeWay ( id , weapon ){ new Float:fGrenadeGrav = 1.0; switch( weapon) { case CSW_HEGRENADE: fGrenadeGrav = 0.55; case CSW_FLASHBANG: fGrenadeGrav = 0.5; case CSW_SMOKEGRENADE: fGrenadeGrav = 0.5; } static pGrav; if( !pGrav ) pGrav = get_cvar_pointer( "sv_gravity" ); new Float:fStartPos[ 3 ] , Float: fViewOfs[ 3 ] , Float: fVector[ 3 ] , Float: fVeloc [ 3 ] , Float: fAngles [ 3 ] , Float: fEndPos [ 3 ] , Float: fTmpVector [ 3 ] , pTr , Float: fFraction , Float: fNormal [ 3 ] , iCollision = 0 , Float: fVel; new Float:fGrav = get_pcvar_float( pGrav ) , pHit = 0; const maxCollsion = 30; const Float: fConstAliveTime = 2.0; const Float: fConstLoops = 20.0; new Float: fAliveTime = 0.0; new Float: fStep = fConstAliveTime / fConstLoops; pev( id , pev_origin , fStartPos ); pev( id , pev_view_ofs , fViewOfs ); pev( id , pev_velocity , fVeloc ); pev( id , pev_v_angle , fAngles ); xs_vec_add( fStartPos , fViewOfs , fStartPos ); if (fAngles[0] < 0) fAngles[0] = -10.0 + fAngles[0] * ((90.0 - 10.0) / 90.0); else fAngles[0] = -10.0 + fAngles[0] * ((90.0 + 10.0) / 90.0); fVel = (90.0 - fAngles[0]) * 6.0; if (fVel > 750.0) fVel = 750.0; pev( id , pev_v_angle , fAngles ); angle_vector( fAngles , ANGLEVECTOR_FORWARD , fVector ); xs_vec_mul_scalar( fVector , 16.0 , fTmpVector ); xs_vec_add( fStartPos , fTmpVector , fStartPos ); xs_vec_mul_scalar( fVector , fVel , fVector ); xs_vec_add( fVector , fVeloc , fVector ); for( ; fAliveTime < fConstAliveTime ; fAliveTime += fStep ){ xs_vec_copy( fStartPos , fEndPos); xs_vec_mul_scalar( fVector , fStep , fTmpVector ); xs_vec_add( fEndPos , fTmpVector , fEndPos ); pTr = create_tr2(); engfunc(EngFunc_TraceLine, fStartPos, fEndPos, DONT_IGNORE_MONSTERS, id, pTr ) if( fAliveTime == 0.0 ){ fStartPos [ 2 ] += 10.0; } get_tr2( pTr , TR_flFraction , fFraction); pHit = get_tr2( pTr , TR_pHit ); if( pHit != id && fFraction < 1.0 ){ get_tr2( pTr , TR_vecEndPos , fEndPos ); get_tr2( pTr , TR_vecPlaneNormal , fNormal ) if( fNormal [ 2 ] > 0.9 && fVector [ 2 ] <= 0.0 && fVector [ 2 ] >= -fGrav / 0.20 ){ return ; } new Float: fScalar = xs_vec_dot( fVector, fNormal ) * 1.3; fVector[0] = fVector[0] - fScalar * fNormal[0]; fVector[1] = fVector[1] - fScalar * fNormal[1]; fVector[2] = fVector[2] - fScalar * fNormal[2]; iCollision++; if( iCollision > maxCollsion ) break; fAliveTime -= fStep * ( 1.0 - fFraction ) ; } new iR , iG , iB; switch( weapon ) { case CSW_HEGRENADE:{ iR = 250; iG = 0; iB = 0; } case CSW_FLASHBANG:{ iR = 0; iG = 0; iB = 250; } case CSW_SMOKEGRENADE:{ iR = 0; iG = 250; iB = 0; } } message_begin( MSG_ONE_UNRELIABLE , SVC_TEMPENTITY , { 0 , 0 , 0 } , id ) write_byte(0) // TE_BEAMPOINTS engfunc( EngFunc_WriteCoord , fStartPos [ 0 ] ) engfunc( EngFunc_WriteCoord , fStartPos [ 1 ] ) engfunc( EngFunc_WriteCoord , fStartPos [ 2 ] ) engfunc( EngFunc_WriteCoord , fEndPos [ 0 ] ) engfunc( EngFunc_WriteCoord , fEndPos [ 1 ] ) engfunc( EngFunc_WriteCoord , fEndPos [ 2 ] ) write_short(laser) write_byte(1) write_byte(1) write_byte(1) write_byte(15) write_byte(0) write_byte( iR ) write_byte( iG ) write_byte( iB ) write_byte(210) write_byte(0) message_end() xs_vec_copy( fEndPos , fStartPos ); fVector[ 2 ] -= floatmul( floatmul( fGrenadeGrav , fGrav ) , floatmul( fFraction , fStep ) ); free_tr2( pTr ); } }
Efekt:
http://www.youtube.com/watch?v=RzXca9lTRBA
Wymagania:
#include <xs> #include <fakemeta>
- Pierwszy parametr to id gracza któremu pokazać drogę
- Drugi to typ granatu czyli przyjmuje on wartości CSW_HEGRENADE , CSW_FLASHBANG lub CSW_SMOKEGRENADE
Wyświetlanie ścieżki kiedy gracz trzyma granat
public client_PreThink( id ){ if( is_user_alive( id ) ){ new iWeapon = get_user_weapon( id ); if( iWeapon == CSW_HEGRENADE || iWeapon == CSW_SMOKEGRENADE || iWeapon == CSW_FLASHBANG ){ showGrenadeWay( id , iWeapon ); } } }