Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reload animation doesn't always play when automatic reload occurs #3069

Open
SamVanheer opened this issue Feb 28, 2021 · 1 comment
Open

Comments

@SamVanheer
Copy link

When a weapon initiates a reload on its own the animation does not always play.

This automatic reload occurs here:
server:

halflife/dlls/weapons.cpp

Lines 707 to 712 in c7240b9

// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < ( UseDecrement() ? 0.0 : gpGlobals->time ) )
{
Reload();
return;
}

client:

// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < 0.0 )
{
Reload();
return;
}

When this occurs the client won't predict it because the server has already started it, and this condition will be false:

if ( player.m_flNextAttack <= 0 )
{
pWeapon->ItemPostFrame();
}

So only the server runs the Reload method and related functionality.

Normally when this happens the client re-syncs itself here:

// Make sure that weapon animation matches what the game .dll is telling us
// over the wire ( fixes some animation glitches )
if ( g_runfuncs && ( HUD_GetWeaponAnim() != to->client.weaponanim ) )
{
int body = 2;
//Pop the model to body 0.
if ( pWeapon == &g_Tripmine )
body = 0;
//Show laser sight/scope combo
if ( pWeapon == &g_Python && bIsMultiplayer() )
body = 1;
// Force a fixed anim down to viewmodel
HUD_SendWeaponAnim( to->client.weaponanim, body, 1 );
}

But this relies on HUD_GetWeaponAnim returning the current animation. It returns the last animation that was predicted by the client side weapons code, which means it ignores events that also change the weapon animation.

As a result weapons that don't change animations locally often can end up with the reload animation not playing. When successive reload occur HUD_GetWeaponAnim returns the reload animation so it doesn't re-sync itself. The weapon otherwise reloads as normal.

Updating the cached animation doesn't fix it, it actually results in animations playing when they shouldn't.

This can be tested easily with the Half-Life Glock since it has pretty long delays before it plays idle animations. The RPG also has this problem. Depleting its ammo and then picking up more will reload it without playing the animation.

Note that in multiplayer gamerules will auto-switch weapons when empty, so test this in singleplayer or disable the auto-switch behavior first.

Part of the problem is that events play back after a frame's prediction has run, which makes catching edge cases like these harder. Unlike the old server-only code this delays viewmodel animation changes. Predicted code that uses SendWeaponAnim changes the animation immediately, whereas events don't change it until after the re-sync check has occurred.

As such it may not be possible to fix this problem entirely without incurring the overhead that SendWeaponAnim adds.

@hashnimo
Copy link

hashnimo commented Mar 2, 2021

Just had a similar experience today, I have reloaded the gun but reload animation didn't play at all, the ammo counter also stayed the same with 0 bullets, and then I clicked once to fire, and the ammo counter went back to normal. I had almost 300 ping and thought it was some packet loss or something I couldn't understand, seems like it's not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants