Raised This Month: $32 Target: $400
 8% 

Knife Distance by SchlumPF


Post New Thread Reply   
 
Thread Tools Display Modes
Plugin Info:     Modification:   ALL        Category:   Admin Commands        Approver:   Emp` (115)
SchlumPF*
Veteran Member
Join Date: Mar 2007
Old 05-11-2009 , 12:08   Knife Distance by SchlumPF
Reply With Quote #1

Knife Distance by SchlumPF

Description
This plugin will measure how far your enemy stood away when you hit it with your knife. The origins for measuring this plugin uses are the origins which are used by the engine to verifiy whether a attack hit or not which makes it as accurate as possible.
Currently this is the only 100% accurate KD-plugin which's sourcecode is public.

Difference between TraceLine-Hits and TraceHull-Hits
First of all the engine tries to draw a line (TraceLine) which has a length of 32.0 or 48.0 units, depending on the attacktype, between your gunposition, which is about the center of the players head, to where you are aiming. If this line hits anything, everything is fine: We get a hitgroup (head, chest, stomach, left arm, right arm, left leg, right leg). But if this line hits nothing on it's way, which happens if you don't aim directly at you opponent or are too far away, the engine performs a second check which is a TraceHull. The TraceHull is not a line, it's a rectangular which moves to the place your aiming, too. If this box hits anything on its way, the engine also recognizes hit with a huge difference: The hit's hitgroup is generic because the engine doesn't determine a specific hitgroup. This difference simply means, we cannot do a headshot or any special amount of damage apart the default ones with a Tracehull hit. Also, a TraceHull distance can be less than 16.0 (TraceLine limit) or even 0.0.

CVars
kd_sound_wickedsick_stab "30.0"- minimum distance for a public wickedsick announcment of stabs
kd_sound_godlike_stab "31.0"- minimum distance for a public godlike announcment of stabs
kd_sound_wickedsick_slash "46.0"- minimum distance for a public wickedsick announcment of slashes
kd_sound_godlike_slash "47.0"- minimum distance for a public godlike announcment of slashes
kd_hud_color "0 250 150"- color of the hudmessages, which is used to show stats, on screen
kd_hud_coords "-0.75 -1.0"- position of the hudmessages, which is used to show stats, on screen
kd_hud_holdtime "2.0"- duration of the hudmessages, which is used to show stats, on screen

Changelog
Code:
05/11/2009 - v0.1
!: Initial release

05/14/2009 - v0.2
c: Changed the whole detection code
c: Changed the displaying of information from a chatmessage to a hudmessage to avoid to much spam in future updates

05/15/2009 - v0.3
+: Prints the latest hit data of your killer if you died
+: Prints hitdata and plays a sound to everyone if you kill somebody with a attack within a long distance
+: Added comments, I think the plugin gets more hard to read
c: Changed the detection a bit again
c: Fully supports teamattack now
-: Removed unnecessarry code

05/17/2009 - v0.4
+: Added bot-support
+: Added CVars
c: Detection to be finally perfect and accurate
Credits
- DeepBlueSea for pointing out that the calculation which is used in Alka's plugin is wrong and sharing the right way with me
- arkshine for supporting me in this thread
- xPaw for testing this plugin with me and begging me to post it here

HLSDK (my comments beginn with ////)
PHP Code:
// crowbar.cpp

int CCrowbar::Swingint fFirst )
{
    
int fDidHit FALSE;

    
TraceResult tr;

    
UTIL_MakeVectors (m_pPlayer->pev->v_angle);
    
Vector vecSrc    m_pPlayer->GetGunPosition( ); //// not m_HackedGunPosition, origin + view_ofs
    
Vector vecEnd    vecSrc gpGlobals->v_forward 32//// 32 for stabs, 48 for slashes; basically that constant is the distance of the trace

    
UTIL_TraceLinevecSrcvecEnddont_ignore_monstersENTm_pPlayer->pev ), &tr );

    if ( 
tr.flFraction >= 1.0 )
    {
        
UTIL_TraceHullvecSrcvecEnddont_ignore_monstershead_hullENTm_pPlayer->pev ), &tr );
        if ( 
tr.flFraction 1.0 )
        {
            
// Calculate the point of intersection of the line (or hull) and the object we hit
            // This is and approximation of the "best" intersection
            
CBaseEntity *pHit CBaseEntity::Instancetr.pHit );
            if ( !
pHit || pHit->IsBSPModel() ) //// if we hit something which is not an entity (= we hit worldspawn ) the engine looks for the exact hit place
                
FindHullIntersectionvecSrctrVEC_DUCK_HULL_MINVEC_DUCK_HULL_MAXm_pPlayer->edict() );
            
vecEnd tr.vecEndPos;    // This is the point on the actual surface (the hull could have hit space)
        
}
    }

    if ( 
tr.flFraction >= 1.0 )
    {
        if (
fFirst)
        {
            
// miss
            
switch( (m_iSwing++) % )
            {
            case 
0:
                
SendWeaponAnimCROWBAR_ATTACK1MISS ); break;
            case 
1:
                
SendWeaponAnimCROWBAR_ATTACK2MISS ); break;
            case 
2:
                
SendWeaponAnimCROWBAR_ATTACK3MISS ); break;
            }
            
m_flNextPrimaryAttack gpGlobals->time 0.5;
            
// play wiff or swish sound
            
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON"weapons/cbar_miss1.wav"1ATTN_NORM094 RANDOM_LONG(0,0xF));

            
// player "shoot" animation
            
m_pPlayer->SetAnimationPLAYER_ATTACK1 );
        }
    }
    else
    {
        
// hit
        
fDidHit TRUE;

        
CBaseEntity *pEntity CBaseEntity::Instance(tr.pHit);

        switch( ((
m_iSwing++) % 2) + )
        {
        case 
0:
            
SendWeaponAnimCROWBAR_ATTACK1HIT ); break;
        case 
1:
            
SendWeaponAnimCROWBAR_ATTACK2HIT ); break;
        case 
2:
            
SendWeaponAnimCROWBAR_ATTACK3HIT ); break;
        }

        
// player "shoot" animation
        
m_pPlayer->SetAnimationPLAYER_ATTACK1 );

        
ClearMultiDamage( );

        
//// if you check the following code you will see that TraceAttack is called first but the damage which is caused is set in TakeDamage

        
if ( (m_flNextPrimaryAttack gpGlobals->time) || g_pGameRules->IsMultiplayer() )
        {
            
// first swing does full damage
            
pEntity->TraceAttack(m_pPlayer->pevgSkillData.plrDmgCrowbargpGlobals->v_forward, &trDMG_CLUB ); 
        }
        else
        {
            
// subsequent swings do half
            
pEntity->TraceAttack(m_pPlayer->pevgSkillData.plrDmgCrowbar 2gpGlobals->v_forward, &trDMG_CLUB ); 
        }    
        
ApplyMultiDamagem_pPlayer->pevm_pPlayer->pev );

        
m_flNextPrimaryAttack gpGlobals->time 0.25;

        
// play thwack, smack, or dong sound
        
float flVol 1.0;
        
int fHitWorld TRUE;

        if (
pEntity)
        {
            if (
pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE)
            {
                
// play thwack or smack sound
                
switch( RANDOM_LONG(0,2) )
                {
                case 
0:
                    
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON"weapons/cbar_hitbod1.wav"1ATTN_NORM); break;
                case 
1:
                    
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON"weapons/cbar_hitbod2.wav"1ATTN_NORM); break;
                case 
2:
                    
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON"weapons/cbar_hitbod3.wav"1ATTN_NORM); break;
                }
                
m_pPlayer->m_iWeaponVolume CROWBAR_BODYHIT_VOLUME;
                if (!
pEntity->IsAlive() )
                    return 
TRUE;
                else
                    
flVol 0.1;

                
fHitWorld FALSE;
            }
        }

        
// play texture hit sound
        // UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line

        
if (fHitWorld)
        {
            
float fvolbar TEXTURETYPE_PlaySound(&trvecSrcvecSrc + (vecEnd-vecSrc)*2BULLET_PLAYER_CROWBAR);

            if ( 
g_pGameRules->IsMultiplayer() )
            {
                
// override the volume here, cause we don't play texture sounds in multiplayer, 
                // and fvolbar is going to be 0 from the above call.

                
fvolbar 1;
            }

            
// also play crowbar strike
            
switch( RANDOM_LONG(0,1) )
            {
            case 
0:
                
//UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "weapons/cbar_hit1.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));
                
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM"weapons/cbar_hit1.wav"fvolbarATTN_NORM098 RANDOM_LONG(0,3)); 
                break;
            case 
1:
                
//UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "weapons/cbar_hit2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));
                
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM"weapons/cbar_hit2.wav"fvolbarATTN_NORM098 RANDOM_LONG(0,3)); 
                break;
            }
        }

        
// delay the decal a bit
        
m_trHit tr;
        
SetThinkSmack );
        
pev->nextthink gpGlobals->time 0.2;

        
m_pPlayer->m_iWeaponVolume flVol CROWBAR_WALLHIT_VOLUME;
    }
    return 
fDidHit;
}

void FindHullIntersection( const Vector &vecSrcTraceResult &trfloat *minsfloat *maxsedict_t *pEntity )
{
    
int            ijk;
    
float        distance;
    
float        *minmaxs[2] = {minsmaxs};
    
TraceResult tmpTrace;
    
Vector        vecHullEnd tr.vecEndPos;
    
Vector        vecEnd;

    
distance 1e6f;

    
vecHullEnd vecSrc + ((vecHullEnd vecSrc)*2);
    
UTIL_TraceLinevecSrcvecHullEnddont_ignore_monsterspEntity, &tmpTrace );
    if ( 
tmpTrace.flFraction 1.0 )
    {
        
tr tmpTrace;
        return;
    }

    for ( 
02i++ )
    {
        for ( 
02j++ )
        {
            for ( 
02k++ )
            {
                
vecEnd.vecHullEnd.minmaxs[i][0];
                
vecEnd.vecHullEnd.minmaxs[j][1];
                
vecEnd.vecHullEnd.minmaxs[k][2];

                
UTIL_TraceLinevecSrcvecEnddont_ignore_monsterspEntity, &tmpTrace );
                if ( 
tmpTrace.flFraction 1.0 )
                {
                    
float thisDistance = (tmpTrace.vecEndPos vecSrc).Length();
                    if ( 
thisDistance distance )
                    {
                        
tr tmpTrace;
                        
distance thisDistance;
                    }
                }
            }
        }
    }

Related Links
[1] Knife-Tracing explained by DeepBlueSea

Notes
DeepBlueSea and Alka confirmed the distance to be accurate.
Fell free to ask, use the code, post suggestions or w/e
Attached Thumbnails
Click image for larger version

Name:	knife_slash_dmg.jpg
Views:	3521
Size:	20.8 KB
ID:	42256   Click image for larger version

Name:	knife_stab_dmg.jpg
Views:	2006
Size:	21.2 KB
ID:	42257   Click image for larger version

Name:	knife_charge_time.jpg
Views:	1763
Size:	17.8 KB
ID:	42258  
Attached Files
File Type: zip sound.zip (149.8 KB, 3324 views)
File Type: sma Get Plugin or Get Source (knife_distance.sma - 7173 views - 8.1 KB)
__________________

Last edited by Greentryst; 09-06-2013 at 06:14. Reason: removed amxx file attachment
SchlumPF* is offline
Send a message via ICQ to SchlumPF*
xPaw
Retired AMX Mod X Moderator
Join Date: Jul 2008
Old 05-11-2009 , 12:09   Re: Knife Distance by SchlumPF
Reply With Quote #2

Well done sir

I have an idea for you - print such messages at end of each round and a cvar to toggle it
[KD] Most (biggest) slash distance in this round is 47.999999 done by Rofltard!
[KD] Most (biggest) stab distance in this round is 31.932939 done by GoogleIsShit!

// --

And print messages only when killing, and when you was killed then it will print info messages for you too( you was killed by .... ), Then if godlike print that msg to all ;) thats not all
__________________

Last edited by xPaw; 05-11-2009 at 12:16.
xPaw is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 05-11-2009 , 12:26   Re: Knife Distance by SchlumPF
Reply With Quote #3

You forget to define m_LastHitGroup.
Arkshine is offline
SchlumPF*
Veteran Member
Join Date: Mar 2007
Old 05-11-2009 , 12:30   Re: Knife Distance by SchlumPF
Reply With Quote #4

thx, had to delete a lot when i cleaned up the plugin xD
__________________
SchlumPF* is offline
Send a message via ICQ to SchlumPF*
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 05-11-2009 , 12:32   Re: Knife Distance by SchlumPF
Reply With Quote #5

Just for your information, you can get rid of most of your code using glb_trace_endpos which contain the end position of the last trace.
Arkshine is offline
SchlumPF*
Veteran Member
Join Date: Mar 2007
Old 05-11-2009 , 14:44   Re: Knife Distance by SchlumPF
Reply With Quote #6

Quote:
Originally Posted by arkshine View Post
Just for your information, you can get rid of most of your code using glb_trace_endpos which contain the end position of the last trace.
the question is whether get_global()or my calculation is faster, i cannot test it cuz my cs crashed when im using the profiling-binarys and im not sure whether your 100% right since get_global()runs a lot of c++ code.

PHP Code:
static Float:vecEnd[3];
vecEnd[0] = vecSrc[0] + vecDir[0] * range;
vecEnd[1] = vecSrc[1] + vecDir[1] * range;
vecEnd[2] = vecSrc[2] + vecDir[2] * range
__________________
SchlumPF* is offline
Send a message via ICQ to SchlumPF*
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 05-11-2009 , 15:00   Re: Knife Distance by SchlumPF
Reply With Quote #7

One native against severals natives/code. Obviously it's more faster. Why the benefit to recalculate something which is already done ?!
I'm not sure if you have understood. glb_trace_endpos will give the last end position. So you don't need to recalculate what does the original function...

Code:
new Float:EndPos[ 3 ]; global_get( glb_trace_endpos, EndPos );

Works fine for me.

Basicaly you need only that :

Code:
[...]     static Float:vecSrc[3], Float:origin[3], Float:view_ofs[3];     pev( attacker, pev_origin, origin );     pev( attacker, pev_view_ofs, view_ofs );         // Player's gun position     vecSrc[0] = origin[0] + view_ofs[0];     vecSrc[1] = origin[1] + view_ofs[1];     vecSrc[2] = origin[2] + view_ofs[2];         // End position of last trace.     static Float:vecEndPos[3];     global_get( glb_trace_endpos, vecEndPos );         static Float:distance;     distance = get_distance_f( vecSrc, vecEndPos ); [...]

You can remove FindHullIntersection() too.
It's what I was meant.

Last edited by Arkshine; 05-11-2009 at 15:10.
Arkshine is offline
SchlumPF*
Veteran Member
Join Date: Mar 2007
Old 05-11-2009 , 15:28   Re: Knife Distance by SchlumPF
Reply With Quote #8

oh, than your way is probably a lot faster xD
__________________
SchlumPF* is offline
Send a message via ICQ to SchlumPF*
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 05-11-2009 , 15:30   Re: Knife Distance by SchlumPF
Reply With Quote #9

Yeah. When you look the HLSDK, it will give you tr.vecEndPos, whatever tracehull or traceline, just the last trace, that's why you don't need to recalculate. I've checked, you get the same result.

Last edited by Arkshine; 05-11-2009 at 15:33.
Arkshine is offline
One
Veteran Member
Join Date: Oct 2008
Location: Hardstyle-eSports.de
Old 05-11-2009 , 15:54   Re: Knife Distance by SchlumPF
Reply With Quote #10

Man habe ich ja lange darauf gewartet.

N1
__________________
One is offline
Send a message via ICQ to One Send a message via AIM to One Send a message via MSN to One Send a message via Yahoo to One Send a message via Skype™ to One
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 10:49.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode