I've got sma of kz_stats.amxx.
Code:
#include <amxmodx>
#include <fakemeta>
#define PLUGIN "KZ Stats"
#define VERSION "___"
#define AUTHOR "SchlumPF"
// maxspeed manchmal anders als bei rat
// add consoleprint in menu
//#pragma semicolon 1
//#define DONT_SHOW_COMMANDS_IN_CHAT // Comment this if you don't want to see any nasty commands in chat :)
new bool:g_bBeam[33];
new bool:g_bStrafeStats[33];
new g_iJumpStats[33];
new g_iOutput[33];
new bool:g_bFirstFrame[33];
new bool:g_bInAir[33];
new bool:g_bInBhop[33];
new bool:g_bInCountJump[33];
new bool:g_bInDuck[33];
new g_pSvGravity;
new g_pMinDistance;
new g_pMaxDistance;
new g_pHudMessageCoords;
new g_pHudMessageColors;
new g_pHudMessageFailedColors;
new g_flBeam;
public plugin_init( )
{
register_plugin( PLUGIN, VERSION, AUTHOR );
g_pSvGravity = get_cvar_pointer( "sv_gravity" );
g_pMinDistance = register_cvar( "kz_stats_min_distance", "200" );
g_pMaxDistance = register_cvar( "kz_stats_max_distance", "280" );
g_pHudMessageCoords = register_cvar( "kz_stats_coords", "-1.0 -0.2" );
g_pHudMessageColors = register_cvar( "kz_stats_color", "0 250 180" );
g_pHudMessageFailedColors = register_cvar( "kz_stats_failedcolor", "180 0 250" );
register_clcmd( "say /ljstats", "menuDisplay" );
register_clcmd( "say /kzstats", "menuDisplay" );
register_forward( FM_PlayerPreThink, "fwdPlayerPreThink_Pre", 0 );
register_menucmd( register_menuid( "\rKZ Stats - SchlumPF^n^n" ), 1023, "menuAction" );
}
public plugin_precache( )
{
g_flBeam = engfunc( EngFunc_PrecacheModel, "sprites/zbeam1.spr" );
}
public menuDisplay( plr )
{
static menu[511];
new len = formatex( menu, 511, "\rKZ Stats - SchlumPF^n^n" );
len += formatex( menu[len], 511 - len, "\r01.\w Jump-Stats: \d%s^n", g_iJumpStats[plr] > 1 ? ( g_iJumpStats[plr] == 2 ? "failed stats" : "height difference stats" ) : ( g_iJumpStats[plr] == 0 ? "disabled" : "normal stats" ) );
len += formatex( menu[len], 511 - len, "\r02.\w Strafe-Stats: \d%s^n^n", g_bStrafeStats[plr] ? "enabled" : "disabled" );
len += formatex( menu[len], 511 - len, "\r03.\w Output: \d%s^n^n", g_iOutput[plr] == 0 ? "hudmessage" : ( g_iOutput[plr] == 1 ? "text" : "hudmessage & text" ) );
len += formatex( menu[len], 511 - len, "\r04.\w Beam: \d%s^n^n", g_bBeam[plr] ? "enabled" : "disabled" );
len += formatex( menu[len], 511 - len, "\r00.\w Exit" );
show_menu( plr, ( 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<9 ), menu, -1 );
#if defined DONT_SHOW_COMMANDS_IN_CHAT
return PLUGIN_HANDLED_MAIN;
#endif
}
public menuAction( plr, key )
{
switch( key )
{
case 0:
{
g_iJumpStats[plr] == 3 ? ( g_iJumpStats[plr] = 0 ) : g_iJumpStats[plr]++;
menuDisplay( plr );
}
case 1:
{
g_bStrafeStats[plr] = !g_bStrafeStats[plr];
menuDisplay( plr );
}
case 2:
{
g_iOutput[plr] == 2 ? ( g_iOutput[plr] = 0 ) : g_iOutput[plr]++;
menuDisplay( plr );
}
case 3:
{
g_bBeam[plr] = !g_bBeam[plr];
menuDisplay( plr );
}
case 9:
{
// 'x' is just a delimiter, another character can be used as well but make sure that str_to_int() stops reading the integer on that new delimiter
client_cmd( plr, "setinfo ^"kz_stats^" ^"%ix%ix%ix%i^"", g_iJumpStats[plr], g_bStrafeStats[plr], g_iOutput[plr], g_bBeam[plr] );
show_menu( plr, 0, "" );
}
}
}
public fwdPlayerPreThink_Pre( plr )
{
if( !is_user_alive( plr ) || !g_iJumpStats[plr] )
{
return FMRES_IGNORED;
}
static frames[33], frames_gained_speed[33];
static Float:maxspeed[33], Float:prestrafe[33];
static Float:frame_origin[33][2][3], Float:frame_velocity[33][2][3];
static Float:jumpoff_time[33];
static Float:jumpoff_origin[33][3];
static cvar_string[32], x_coord[9], y_coord[9], red[4], green[4], blue[4];
static button, oldbuttons, flags;
button = pev( plr, pev_button );
flags = pev( plr, pev_flags );
oldbuttons = pev( plr, pev_oldbuttons );
static Float:current_origin[3], Float:current_velocity[3], Float:current_speed;
pev( plr, pev_origin, current_origin );
pev( plr, pev_velocity, current_velocity );
current_speed = floatsqroot( floatpower( current_velocity[0], 2.0 ) + floatpower( current_velocity[1], 2.0 ) ); // this is the same as vector_length for cur_vel without [2]
if( g_bInAir[plr] && !( flags & FL_ONGROUND ) )
{
if( g_iJumpStats[plr] == 3 || ( is_user_ducking( plr ) ? current_origin[2] + 18.0 : current_origin[2] ) - jumpoff_origin[plr][2] > 0.0 )
{
static Float:speed_last_frame[33];
if( g_bFirstFrame[plr] )
{
g_bFirstFrame[plr] = false;
frame_origin[plr][0] = current_origin;
frame_velocity[plr][0] = current_velocity;
frames[plr] = 0;
frames_gained_speed[plr] = 0;
speed_last_frame[plr] = prestrafe[plr];
}
else
{
frame_origin[plr][1] = current_origin;
frame_velocity[plr][1] = current_velocity;
}
if( current_speed > speed_last_frame[plr] )
{
frames_gained_speed[plr]++;
}
frames[plr]++;
speed_last_frame[plr] = current_speed;
if( current_speed > maxspeed[plr] )
{
maxspeed[plr] = current_speed;
}
}
}
if( flags & FL_ONGROUND && button & IN_JUMP && !( oldbuttons & IN_JUMP ) && !g_bInAir[plr] )
{
jumpoff_time[plr] = get_gametime( );
jumpoff_origin[plr] = current_origin;
g_bInAir[plr] = true;
g_bFirstFrame[plr] = true;
prestrafe[plr] = current_speed;
maxspeed[plr] = current_speed;
}
else if( flags & FL_ONGROUND && g_bInAir[plr] )
{
static bool:ducking, Float:height_difference;
ducking = is_user_ducking( plr );
height_difference = ( is_user_ducking( plr ) ? current_origin[2] + 18.0 : current_origin[2] ) - jumpoff_origin[plr][2];
static Float:sync, Float:gain;
sync = float( frames_gained_speed[plr] * 100 ) / float( frames[plr] );
gain = maxspeed[plr] - prestrafe[plr];
static Float:gravity;
gravity = pev( plr, pev_gravity ) * get_pcvar_float( g_pSvGravity );
get_pcvar_string( g_pHudMessageCoords, cvar_string, 31 );
parse( cvar_string, x_coord, 9, y_coord, 9 );
static Float:distance;
if( g_iJumpStats[plr] == 2 )
{
if( height_difference < 0.0 )
{
distance = calculate_failed_distance( ducking, gravity, jumpoff_origin[plr], current_velocity, frame_origin[plr][1], frame_velocity[plr][1] );
if( !( get_pcvar_float( g_pMinDistance ) <= distance <= get_pcvar_float( g_pMaxDistance ) ) )
{
reset( plr );
return FMRES_IGNORED;
}
if( g_iOutput[plr] != 1 )
{
get_pcvar_string( g_pHudMessageFailedColors, cvar_string, 31 );
parse( cvar_string, red, 3, green, 3, blue, 3 );
set_hudmessage( str_to_num( red ), str_to_num( green ), str_to_num( blue ), str_to_float( x_coord ), str_to_float( y_coord ), 0, 6.0, 2.5, 0.0, 0.0, 1 );
show_hudmessage( plr, "Distance: %f^nMaxspeed: %f (%.3f)^nPrestrafe: %f^nSync: %f%%^nStrafecounter: todo", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
if( g_iOutput[plr] != 0 )
{
chat_print( plr, "FailedDistance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
client_print( plr, print_console, "FailedDistance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
else if( height_difference == 0.0 )
{
distance = calculate_real_distance( ducking, gravity, jumpoff_origin[plr], current_origin, frame_origin[plr], frame_velocity[plr] );
if( !( get_pcvar_float( g_pMinDistance ) <= distance <= get_pcvar_float( g_pMaxDistance ) ) )
{
reset( plr );
return FMRES_IGNORED;
}
if( g_iOutput[plr] != 1 )
{
get_pcvar_string( g_pHudMessageColors, cvar_string, 31 );
parse( cvar_string, red, 3, green, 3, blue, 3 );
set_hudmessage( str_to_num( red ), str_to_num( green ), str_to_num( blue ), str_to_float( x_coord ), str_to_float( y_coord ), 0, 6.0, 2.5, 0.0, 0.0, 1 );
show_hudmessage( plr, "Distance: %f^nMaxspeed: %f (%.3f)^nPrestrafe: %f^nSync: %f%%^nStrafecounter: todo", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
if( g_iOutput[plr] != 0 )
{
chat_print( plr, "Distance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
client_print( plr, print_console, "Distance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
else
{
reset( plr );
return FMRES_IGNORED;
}
}
else if( g_iJumpStats[plr] == 3 )
{
distance = calculate_real_distance( ducking, gravity, jumpoff_origin[plr], current_origin, frame_origin[plr], frame_velocity[plr] );
if( !( get_pcvar_float( g_pMinDistance ) <= distance <= get_pcvar_float( g_pMaxDistance ) ) )
{
reset( plr );
return FMRES_IGNORED;
}
if( g_iOutput[plr] != 1 )
{
get_pcvar_string( g_pHudMessageColors, cvar_string, 31 );
parse( cvar_string, red, 3, green, 3, blue, 3 );
set_hudmessage( str_to_num( red ), str_to_num( green ), str_to_num( blue ), str_to_float( x_coord ), str_to_float( y_coord ), 0, 6.0, 2.5, 0.0, 0.0, 1 );
show_hudmessage( plr, "Distance: %f^nMaxspeed: %f (%.3f)^nPrestrafe: %f^nSync: %f%%^nStrafecounter: todo^nHeight difference: %s%f", distance, maxspeed[plr], gain, prestrafe[plr], sync, height_difference > 0.0 ? "+" : "", height_difference );
}
if( g_iOutput[plr] != 0 )
{
chat_print( plr, "Distance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%% HeightDifference %s%.3f", distance, maxspeed[plr], gain, prestrafe[plr], sync, height_difference > 0.0 ? "+" : "", height_difference );
}
client_print( plr, print_console, "Distance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%% HeightDifference %s%.3f", distance, maxspeed[plr], gain, prestrafe[plr], sync, height_difference > 0.0 ? "+" : "", height_difference );
}
else if( g_iJumpStats[plr] == 1 && !height_difference )
{
distance = calculate_real_distance( ducking, gravity, jumpoff_origin[plr], current_origin, frame_origin[plr], frame_velocity[plr] );
if( !( get_pcvar_float( g_pMinDistance ) <= distance <= get_pcvar_float( g_pMaxDistance ) ) )
{
reset( plr );
return FMRES_IGNORED;
}
if( g_iOutput[plr] != 1 )
{
get_pcvar_string( g_pHudMessageColors, cvar_string, 31 );
parse( cvar_string, red, 3, green, 3, blue, 3 );
set_hudmessage( str_to_num( red ), str_to_num( green ), str_to_num( blue ), str_to_float( x_coord ), str_to_float( y_coord ), 0, 6.0, 2.5, 0.0, 0.0, 1 );
show_hudmessage( plr, "Distance: %f^nMaxspeed: %f (%.3f)^nPrestrafe: %f^nSync: %f%%^nStrafecounter: todo", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
if( g_iOutput[plr] != 0 )
{
chat_print( plr, "Distance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
client_print( plr, print_console, "Distance %.3f Maxspeed %.3f (%.3f) Prestrafe %.3f Sync %.3f%", distance, maxspeed[plr], gain, prestrafe[plr], sync );
}
reset( plr );
}
return FMRES_IGNORED;
}
public reset( plr )
{
g_bInAir[plr] = false;
g_bInBhop[plr] = false;
g_bInCountJump[plr] = false;
g_bInDuck[plr] = false;
}
public client_command( plr )
{
static command[32];
read_argv( 0, command, 31 );
static const forbidden[][] =
{
"tele", "tp", "gocheck", "gc", "stuck", "unstuck", "start", "reset", "restart",
"spawn", "respawn", "finish", "ct", "spec", "spectator"
};
if( equal( command, "say" ) )
{
read_args( command, 31 );
remove_quotes( command );
if( ( command[0] == '+' || command[0] == '-' ) && ( equal( command[1], "hook", 4 ) || equal( command[1], "rope", 4 ) ) )
{
reset( plr );
}
}
else if( command[0] == '/' || command[0] == '.' )
{
copy( command, 31, command[1] );
for( new i ; i < sizeof( forbidden ) ; i++ )
{
if( equal( command, forbidden[i] ) )
{
reset( plr );
}
}
}
}
public client_putinserver( plr )
{
// Usually I reset variables which store player data in plugin_connect() but I cannot use get_user_info() before client_putinserver()
static info[5][16]; info[4][0] = '^0';
get_user_info( plr, "kz_stats", info[4], 15 );
if( info[4][0] )
{
explode( info, 4, 16, info[4], 'x' );
// clamp() to avoid bugs through manually setting the setinfo to too huge or small values
g_iJumpStats[plr] = clamp( str_to_num( info[0] ), 0, 3 );
g_bStrafeStats[plr] = clamp( str_to_num( info[1] ), 0, 1 ) ? true : false;
g_iOutput[plr] = clamp( str_to_num( info[2] ), 0, 2 );
g_bBeam[plr] = clamp( str_to_num( info[3] ), 0, 1 ) ? true : false;
}
else
{
g_iJumpStats[plr] = 0;
g_bStrafeStats[plr] = false;
g_iOutput[plr] = 0;
g_bBeam[plr] = false;
}
reset( plr );
}
Float:calculate_real_distance( bool:ducking, Float:gravity, Float:jumpoff_origin[3], Float:origin[3], Float:frame_origin[2][3], Float:frame_velocity[2][3] )
{
static Float:distance1;
distance1 = get_distance_f( jumpoff_origin, origin ) + 32.0;
static Float:_time;
_time = floatdiv( -floatsqroot( floatpower( frame_velocity[0][2], 2.0 ) + ( 2 * gravity * ( frame_origin[0][2] - origin[2] ) ) ) - frame_velocity[1][2], -gravity );
static Float:land_origin[3];
land_origin[0] = frame_origin[1][0] < origin[0] ? frame_origin[1][0] + _time * floatabs( frame_velocity[1][0] ) : frame_origin[1][0] - _time * floatabs( frame_velocity[1][0] );
land_origin[1] = frame_origin[1][1] < origin[1] ? frame_origin[1][1] + _time * floatabs( frame_velocity[1][1] ) : frame_origin[1][1] - _time * floatabs( frame_velocity[1][1] );
land_origin[2] = ducking ? origin[2] + 18.0 : origin[2];
static Float:distance2;
distance2 = get_distance_f( jumpoff_origin, land_origin ) + 32.0;
return distance1 > distance2 ? distance2 : distance1;
}
Float:calculate_failed_distance( bool:ducking, Float:gravity, Float:jumpoff_origin[3], Float:velocity[3], Float:failed_origin[3], Float:failed_velocity[3] )
{
gravity = -gravity;
if( ducking ) jumpoff_origin[2] -= 18.0;
static Float:_time;
_time = ( -failed_velocity[2] - floatsqroot( floatpower( failed_velocity[2], 2.0 ) - 2.0 * gravity * ( failed_origin[2] - jumpoff_origin[2] ) ) ) / gravity;
static Float:distance_x, Float:distance_y;
distance_x = floatabs( failed_origin[0] - jumpoff_origin[0] ) + floatabs( velocity[0] * _time );
distance_y = floatabs( failed_origin[1] - jumpoff_origin[1] ) + floatabs( velocity[1] * _time );
return floatsqroot( floatpower( distance_x, 2.0 ) + floatpower( distance_y, 2.0 ) ) + 32.0;
}
bool:is_user_ducking( plr )
{
if( !pev_valid( plr ) )
{
return false;
}
new Float:abs_min[3], Float:abs_max[3];
pev( plr, pev_absmin, abs_min );
pev( plr, pev_absmax, abs_max );
abs_min[2] += 64.0;
if( abs_min[2] < abs_max[2] )
{
return false;
}
return true;
}
chat_print( plr, const message[], { Float, Sql, Result, _ }:... )
{
static msg[192], len;
msg[0] = 0x04;
len = format( msg[1], sizeof msg - 2, "[XJ] " ) + 1;
msg[len] = 0x01;
vformat( msg[7], sizeof msg - 8, message, 3 );
static maxplayers, message_saytext;
if( !maxplayers || !message_saytext )
{
maxplayers = get_maxplayers( )
message_saytext = get_user_msgid( "SayText" )
}
if( plr <= maxplayers && plr )
{
message_begin( MSG_ONE, message_saytext, { 0, 0, 0 }, plr );
write_byte( plr );
write_string( msg );
message_end( );
}
else if( !plr )
{
for( new i = 1; i <= maxplayers ; i++ )
{
if( !is_user_connected( i ) )
{
continue;
}
message_begin( MSG_ONE, message_saytext, { 0, 0, 0 }, i );
write_byte( i );
write_string( msg );
message_end( );
}
}
return 1;
}
explode( output[][], _max, size, input[], delimiter )
{
new index, l = strlen( input ), len;
do len += ( 1 + copyc( output[index], size, input[len], delimiter ) );
while( ( len < l ) && ( ++index < _max ) );
return index;
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1031\\ f0\\ fs16 \n\\ par }*/
And What About noblock?? I didn't find working plugin....