Raised This Month: $51 Target: $400
 12% 

[TUT] Properly Detect Weapon Shot (Every Shot) [UPDATED]


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
WATCH_D0GS UNITED
Senior Member
Join Date: Jan 2023
Old 04-04-2023 , 00:12   [TUT] Properly Detect Weapon Shot (Every Shot) [UPDATED]
Reply With Quote #1

This is for hooking every gun shot.

It hooks the practically exact moment when a bullet is fired. Shots are detected in a extremely short time.

You do not need to check if player is pressing button.

You do not need to check if weapon has clip bullets.

Much more accurate and reliable than FM_PlaybackEvent, which counts every round start as shooting and misses the first bullet fired when using bools. (...)

This shot hook detects every of the shots which go through walls, so when you shoot with weapons which shots are capable to go through walls, ALL the crossing sections are counted as shot.

The debugger will inform you when you are shooting (TRUE),
when you are not shooting (FALSE),
and how many shots you fired (SHOTS).

*Every shot crossing walls is counted/detected as one different shot.
*Every shotgun pellet is counted/detected as one different shot.


UPDATE!
PHP Code:
Apr 092023

Now using FM_CmdEnd instead of CurWeapon to detect the shots in an even shorter period of time

DEBUG VERSION

PHP Code:
#include <amxmodx>
#include <fakemeta>

#define valid(id) (id == clamp(id,1,33))  // Checks if the player is in the range of 1 to max players
#define NOSHOT (1<<0 | 1<<4 | 1<<6 | 1<<9 | 1<<25 | 1<<29)  // (CSW_NONE | CSW_HEGRENADE | CSW_C4 | CSW_SMOKEGRENADE | CSW_FLASHBANG | CSW_KNIFE)
#define ALIVE is_user_alive
#define WEAPON get_user_weapon
#define m_flLastFired get_pdata_int(id,220)
#define GUN_FIRED (last_shot_b[id] != last_shot_a[id])

static last_shot_a[33],last_shot_b[33],bool:SHOOTING[33],shot_count;

public 
plugin_init() {
    
register_plugin("Shot Hook","1.0","WATCH_DOGS UNITED")
    
register_forward(FM_TraceLine,"fwTraceLine",1)
    
register_forward(FM_CmdEnd,"Refresh")
}

public 
Refresh(id) {
    if(!
valid(id))
        return
    
last_shot_a[id] = m_flLastFired
}

public 
fwTraceLine(const Float:start[3],Float:dest[3],HIT_PARAM,id,ptr) {
    if(!
valid(id))
        return
    
last_shot_b[id] = m_flLastFired
    
if(ALIVE(id) && !(NOSHOT & (1<<WEAPON(id))) && GUN_FIRED) {

        
// Gun fired
        
SHOOTING[id] = true
        shot_count
++
    }
    else
        
SHOOTING[id] = false

    
// REAL-TIME DEBUG

    
if(SHOOTING[id] == true)
        
client_print(id,print_chat,"TRUE")
    else
        
client_print(id,print_chat,"FALSE")
    
client_print(id,print_chat,"SHOTS: %d",shot_count)
}

/*
public Your_Stuff(id) {
    if(SHOOTING[id] == true) {
        Make something
    }
}
*/ 

SIMPLIFIED

PHP Code:
#include <amxmodx>
#include <fakemeta>

#define valid(id) (id == clamp(id,1,33))
#define NOSHOT (1<<0 | 1<<4 | 1<<6 | 1<<9 | 1<<25 | 1<<29)

static last_shot_a[33],last_shot_b[33],bool:SHOOTING[33];

public 
plugin_init() {
    
register_plugin("Shot Hook","1.0","WATCH_DOGS UNITED")
    
register_forward(FM_TraceLine,"fwTraceLine",1)
    
register_forward(FM_CmdEnd,"Refresh")
}

public 
Refresh(id) {
    if(!
valid(id))
        return
    
last_shot_a[id] = get_pdata_int(id,220)
}

public 
fwTraceLine(const Float:start[3],Float:dest[3],HIT_PARAM,id,ptr) {
    if(!
valid(id))
        return
    
last_shot_b[id] = get_pdata_int(id,220)
    if(
is_user_alive(id) && !(NOSHOT & (1<<get_user_weapon(id))) && last_shot_b[id] != last_shot_a[id]) {
        
// Gun fired
        
SHOOTING[id] = true
    
}
    else
        
SHOOTING[id] = false



We will release the new version of Aim Realism plugin soon with this shot hook.

EDIT

Aim Realism v2.3.9 released.
https://gamebanana.com/mods/311932

Last edited by WATCH_D0GS UNITED; 04-09-2023 at 20:48. Reason: Updated
WATCH_D0GS UNITED is offline
Celena Luna
Veteran Member
Join Date: Aug 2013
Location: Nagazora
Old 04-04-2023 , 13:23   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #2

Technically speaking, you only need to hook traceline. So why do you need to have last_shot and new_shot?
For your "Aim Realism" plugin, Traceline is the way to go but for "detect weapon firing" specifically, calling Ham_PrimaryAttack is the best way to detect it since it only detect that spefic weapon, that spefic moment.

More detail on traceline here: https://forums.alliedmods.net/showthread.php?t=66076
P/S: By "Ham_Weapon_PrimaryAttack which also is too slow", are you sure you used "Pre" and not "Post"?
__________________
My plugin:

Last edited by Celena Luna; 04-04-2023 at 13:24.
Celena Luna is offline
WATCH_D0GS UNITED
Senior Member
Join Date: Jan 2023
Old 04-04-2023 , 16:23   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #3

You could not understand.

This shot hook detects the exact moment when a bullet is fired, which is very very short time.

last_shot is the id of the m_flLastFired bullet.

new_shot is also the id of the m_flLastFired bullet.


As you may know, the CurWeapon event is updated every time a player shots, switches or reloads the weapon.
In this moment, last_shot id is updated.

And as you may know, the FM_TraceLine forward is updated several times in a second, sometimes it can be refreshed about 2000 times or more in just 1s.
In this moment, new_shot id is updated.


As a result, the shot id detected by FM_TraceLine (new_shot) is always updated before the CurWeapon one (last_shot)

While the m_flLastFired id of last_shot is 1000000000001 (example),
the m_flLastFired id of new_shot is already 1000000000002 (example).


The time interval between last_shot and new_shot was the moment the gun fired.

This is currently the most accurate shot detection.


As you may also know, the accuracy system of Aim Realism plugin is paused for 0.21s in order to not cause the flashbang noflash problem.

With this new shot hook, this is practically no more needed. As the accuracy system is activated in the exact moment the weapon shots,
the flash problem now occurs only < 3% of the time, because the moment the accuracy is activated is too short.

If you use Ham_Weapon_PrimaryAttack_<Pre> for detecting shot, the flashbang problem occurs in 99% of the time, which proofs it is not as accurate as this new shot hook.

As a result the cpu/ram usage is now lower than before at any time.
We will upload Aim Realism v2.3.9 soon.



------------------------------------------------------------------------------------------------------
About, Ham_Weapon_PrimaryAttack as <Pre>, in fact it fixes the first shot/delay problem. Thanks!

But as we already explained, our shot hook is obviously better than Ham_Weapon_PrimaryAttack_<Pre>, so we will keep with it.


Ham_Weapon_PrimaryAttack_<Pre> can detect when player shot, but what will you use to detect when is no more shooting?


----------

Last edited by WATCH_D0GS UNITED; 04-04-2023 at 17:15.
WATCH_D0GS UNITED is offline
JusTGo
Veteran Member
Join Date: Mar 2013
Old 04-04-2023 , 17:19   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #4

Why not just hook FireBullets?
__________________
JusTGo is offline
WATCH_D0GS UNITED
Senior Member
Join Date: Jan 2023
Old 04-04-2023 , 17:43   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #5

@ Celena Luna, here is the final proof that Ham_Weapon_PrimaryAttack_<Pre> is not better, it counts player is shooting when has no bullets.

PHP Code:
#include <amxmodx>
#include <hamsandwich>
#include <fakemeta>

#define valid(id) (id == clamp(id,1,33)) 
#define NOSHOT (1<<0 | 1<<4 | 1<<6 | 1<<9 | 1<<25 | 1<<29)

new shot_count;

public 
plugin_init() {
    
register_plugin("Shot Hook","1.0","WATCH_DOGS UNITED")

    new 
weapon_name[20]
    for(new 
CSW_P228<= CSW_P90i++) {
        if(
get_weaponname(i,weapon_name,charsmax(weapon_name)) && !(NOSHOT 1<<i))
            
RegisterHam(Ham_Weapon_PrimaryAttack,weapon_name,"Ham_Weapon_PrimaryAttack_Pre")
    }
    
register_forward(FM_TraceLine,"Real_Time_Debug",1)
}

public 
Ham_Weapon_PrimaryAttack_Pre()
    
shot_count++

public 
Real_Time_Debug(const Float:start[3],Float:dest[3],HIT_PARAM,id,ptr) {
    if(
valid(id))
        
client_print(id,print_chat,"SHOTS: %d",shot_count)

@JusTGo, we will take a look. Thanks!

EDIT:

Could you provide a link?

Last edited by WATCH_D0GS UNITED; 04-04-2023 at 17:46.
WATCH_D0GS UNITED is offline
SVC
Junior Member
Join Date: Mar 2021
Old 04-04-2023 , 20:16   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #6

I'm from phone now.

But, his is not enough?
PHP Code:

new g_iShots[33]


public 
plugin_init()
{
    
RegisterHam(Ham_Weapon_PrimaryAttack"weapon_x","OnWeapon_PrimaryAttack_Post"true)
    
    
register_clcmd("shoots_count""OnClientCommand_ShootsCount")
}

public 
OnWeapon_PrimaryAttack_Post(const iWeapon)
{
    new 
iOwner //get weapon owner...
    
    // get m_fFireOnEmpty offset value
    
if (!m_fFireOnEmpty)
       
g_iShots[iOwner]++
}

public 
OnClientCommand_ShootsCount(const iPlayer)
{
    print(
"shoots count: %d"g_iShots[iPlayer])

Of course, is a concept, because I'm writting from phone now, and I dont remember the natives to get entity's CBase offets values. But I thinks code is understandable.

Reference: clickme

Sorry for my english

Last edited by SVC; 04-04-2023 at 20:21.
SVC is offline
WATCH_D0GS UNITED
Senior Member
Join Date: Jan 2023
Old 04-04-2023 , 21:30   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #7

@SVC, thanks for dedicating your time.


Ham_Weapon_PrimaryAttack (Pre) can be really considered enough for detecting weapon attack.
But we do not want to detect weapon attack, we want to accurately detect the weapon shot moment.

The less time the functions are active, the less CPU/RAM usage and the higher the fps rate.

Below is a theoretical comparison based on our tests of how much time a function is active every time it is executed with Ham_Weapon_PrimaryAttack(Pre) and with the new shot detection method:

Ham_Weapon_PrimaryAttack_Pre: 0.099s
New Shot Detector: 0.003s
WATCH_D0GS UNITED is offline
SVC
Junior Member
Join Date: Mar 2021
Old 04-04-2023 , 23:13   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #8

Quote:
Originally Posted by WATCH_D0GS UNITED View Post
@SVC, thanks for dedicating your time.
No problem, I like help when i can.
Also, can you tell me what is offset 220? I dont remember in this moment.
On the other hand:

Quote:
Originally Posted by WATCH_D0GS UNITED View Post
...we want to accurately detect the weapon shot moment.

The less time the functions are active, the less CPU/RAM usage and the higher the fps rate.
Completely agree with you, always trying to keep the less CPU usage rather than RAM. But there are some things I can see using this way:

1) I can't test rigth now (maybe tomorrow, i hope), but reading a bit, can see that not only from weapons shots is called TraceLine but from other places/conditions.

2) In the above example (as you see, and other places), TraceLine will be called continually on each StatusBar update, and this is only for 1 player. Now imagine a 25+ players scenario ----> you will make an extra lot of checks unnecessary.

3) Honestly speaking of CPU usage, this din't use a 10~20% of all CPU using by engine-routine in just 1 frame. Of course, everyone programs like want.

4) I supposed the only thing that makes the "filter" to detect the shoot is the "220 offets" check (of course, with weaponid, but is not as many important than the first).

There is one bad thing, I forget to made in my code and it wast a pistol-check (since like how is coded, I'm almost sure if you keep +attack press with pistol it will do a fake shoot-detect).

Last edited by SVC; 04-04-2023 at 23:17.
SVC is offline
WATCH_D0GS UNITED
Senior Member
Join Date: Jan 2023
Old 04-04-2023 , 23:52   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #9

Quote:
Originally Posted by SVC View Post
No problem, I like help when i can.
Also, can you tell me what is offset 220? I dont remember in this moment.
On the other hand:



Completely agree with you, always trying to keep the less CPU usage rather than RAM. But there are some things I can see using this way:

1) I can't test rigth now (maybe tomorrow, i hope), but reading a bit, can see that not only from weapons shots is called TraceLine but from other places/conditions.

2) In the above example (as you see, and other places), TraceLine will be called continually on each StatusBar update, and this is only for 1 player. Now imagine a 25+ players scenario ----> you will make an extra lot of checks unnecessary.

3) Honestly speaking of CPU usage, this din't use a 10~20% of all CPU using by engine-routine in just 1 frame. Of course, everyone programs like want.

4) I supposed the only thing that makes the "filter" to detect the shoot is the "220 offets" check (of course, with weaponid, but is not as many important than the first).

There is one bad thing, I forget to made in my code and it wast a pistol-check (since like how is coded, I'm almost sure if you keep +attack press with pistol it will do a fake shoot-detect).
Offset 220 = m_flLastFired

Just to make clear, FM_TraceLine is currently the forward used to refresh weapon shot id (m_flLastFired) in the shortest time period. It will be replaced if we find other way to refresh m_flLastFired id in an even short period of time.

Yeah, fake shots were a problem with any other methods we have used before this.

This shot detector does not get fake shots, as m_flLastFired id is only changed when the player really shoot when using weapons.

Last edited by WATCH_D0GS UNITED; 04-04-2023 at 23:56.
WATCH_D0GS UNITED is offline
WATCH_D0GS UNITED
Senior Member
Join Date: Jan 2023
Old 04-09-2023 , 20:30   Re: [TUT] Properly Detect Weapon Shot (Every Shot)
Reply With Quote #10

UPDATE!

Apr 09, 2023

Use FM_CmdEnd instead of CurWeapon if you want to detect the shots in an even shorter period of time.

We have used it in our Aim Realism plugin and now the m_flLastFired id is refreshed in a too short period of time that the plugin finally will not cause interference in the flashbang explosion effect.

You can download Aim Realism and check how well the shot hook is performing on it.
https://gamebanana.com/mods/311932
WATCH_D0GS UNITED is offline
Reply



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 20:33.


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