[TF2] Fix client desyncs with the Ullapool Caber and Gunslinger due to lack of prediction
Fixes client desync issues on these melee weapons with special attack mechanics by giving them proper prediction:
- Ullapool Caber - Whenever a melee hit was registered on the client, but not on the server, the viewmodel would be set to the detonated model on the client and stay that way, even though it did not actually detonate on the server. Fixed by predicting
m_iDetonatedand always instantly updating the model when a prediction error happens, so it's always in sync with the server's detonation state.
Before:
https://github.com/user-attachments/assets/76debeb1-fd3c-4041-bfca-c13114a4ed27
After:
https://github.com/user-attachments/assets/93b670b2-15ee-49bf-9355-68ffa7597945
- Gunslinger - The combo mechanic (after 2 consecutive hits, the third one is a guaranteed crit) was not properly implemented on the client at all, and when attacking with the guaranteed crit, the client would always play the non-crit swing animation for some time (depending on ping) before being corrected by the server. Fixed by networking and predicting
m_iComboCountandm_flLastComboHit, so the client now plays the crit swing animation when appropriate.
Before:
https://github.com/user-attachments/assets/3c127b0d-e253-43cf-9cd6-af91884a2db5
After:
https://github.com/user-attachments/assets/afc51282-e93f-492b-88a4-b84200a4fe72
Fixing these two bugs also required networking and predicting CTFWeaponBaseMelee::m_flSmackTime, because otherwise CTFWeaponBaseMelee::Smack() would not be properly called during prediction.
Fixes https://github.com/ValveSoftware/Source-1-Games/issues/4719, fixes https://github.com/ValveSoftware/Source-1-Games/issues/5750
Do the other breakable melee items (Neon Annihilator, maybe the bottle?) need this kind of handling as well, even if they're only cosmetic? I vaguely remember seeing patch notes that were supposed to address all 3 of these at some point, so presumably the other two would want these improvements?
Do the other breakable melee items (Neon Annihilator, maybe the bottle?) need this kind of handling as well
The Bottle's m_bBroken was already networked and predicted. With the change to make Smack() predict properly, it should also make the Bottle's prediction reliable. The bodygroups might not update quite as fast when a prediction error happens, since I didn't add an OnDataChanged() to it, but since it's a purely cosmetic effect, I guess it's not a big deal.
Neon Annihilator is a special case, crit_vs_wet_players is only checked server-side in CTFGameRules::ApplyOnDamageModifyRules() (complete with a call to the sign's SetBroken()), so I don't think there's a simple, non-hacky way to make it predictable.