From 3cbdb97b40b6098ae2d42c020c385338f37a79d5 Mon Sep 17 00:00:00 2001 From: nullsystem <15316579+nullsystem@users.noreply.github.com> Date: Sun, 12 Jul 2026 18:35:40 +0100 Subject: [PATCH] Fix local player's players killed report not resetting each round Two fixes: First m_bFirstAliveTick never gets updated when the player respawns past the first respawn since not dying on a round will not turn this to true and the respawn resets through m_bFirstAliveTick for local player in PreThink doesn't get utilized. This may also be the cause of other non-reset issues people seen before, but this has affected the killed players report especially. Second, move the array from C_NEO_Player into its own global array as really it's only a single instance (for the local player) and pointless for every single C_NEO_Player to hold it. For sanity check, change from it being entity index array based to UserID based to be sure which is which when its displayed and not affected by entity index changes. Killer info/scoreboard: - Checking for pre-round freeze in killer_info no longer needed - Now the c_neo_player first tick alive got fixed, can just do it there. - Use MAX_PLAYERS_ARRAY_SAFE - Move local player check * fixes #1874 --- src/game/client/CMakeLists.txt | 1 + src/game/client/hl2mp/c_hl2mp_player.cpp | 8 +++++++ src/game/client/neo/c_neo_killer_infos.cpp | 10 +++++++++ src/game/client/neo/c_neo_killer_infos.h | 9 +++++++- src/game/client/neo/c_neo_player.cpp | 7 ++++-- src/game/client/neo/c_neo_player.h | 5 ++--- .../client/neo/ui/neo_hud_deathnotice.cpp | 22 ++++++++++++++++--- .../client/neo/ui/neo_hud_killer_info.cpp | 14 +++++------- src/game/client/neo/ui/neo_hud_killer_info.h | 1 - src/game/client/neo/ui/neo_scoreboard.cpp | 10 ++++++++- src/game/client/neo/ui/neo_scoreboard.h | 2 +- 11 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 src/game/client/neo/c_neo_killer_infos.cpp diff --git a/src/game/client/CMakeLists.txt b/src/game/client/CMakeLists.txt index 18d20326f5..b5c6c90023 100644 --- a/src/game/client/CMakeLists.txt +++ b/src/game/client/CMakeLists.txt @@ -1575,6 +1575,7 @@ set(UNITY_SOURCE_NEO_SRC_CLIENT neo/neo_fixup_glshaders.cpp neo/c_neo_bloom_controller.cpp neo/neo_killer_damage_info.cpp + neo/c_neo_killer_infos.cpp ) set_source_files_properties( diff --git a/src/game/client/hl2mp/c_hl2mp_player.cpp b/src/game/client/hl2mp/c_hl2mp_player.cpp index d32b049531..0b267d9fb0 100644 --- a/src/game/client/hl2mp/c_hl2mp_player.cpp +++ b/src/game/client/hl2mp/c_hl2mp_player.cpp @@ -872,6 +872,14 @@ void C_HL2MP_Player::PostDataUpdate( DataUpdateType_t updateType ) { MoveToLastReceivedPosition( true ); ResetLatched(); +#ifdef NEO + // NEO NOTE (nullsystem): Respawning doesn't trigger + // C_NEO_Player::Spawn/m_bFirstAliveTick without this + if (IsLocalPlayer()) + { + static_cast(this)->m_bFirstAliveTick = true; + } +#endif m_iSpawnInterpCounterCache = m_iSpawnInterpCounter; } diff --git a/src/game/client/neo/c_neo_killer_infos.cpp b/src/game/client/neo/c_neo_killer_infos.cpp new file mode 100644 index 0000000000..08ef6e39a7 --- /dev/null +++ b/src/game/client/neo/c_neo_killer_infos.cpp @@ -0,0 +1,10 @@ +#include "c_neo_killer_infos.h" + +#include "strtools.h" + +void NeoUserIDsLocalKilledClear() +{ + g_neoUserIDsLocalKilledSize = 0; + V_memset(g_neoUserIDsLocalKilled, 0, sizeof(g_neoUserIDsLocalKilled)); +} + diff --git a/src/game/client/neo/c_neo_killer_infos.h b/src/game/client/neo/c_neo_killer_infos.h index e1d4876db8..a017b2a494 100644 --- a/src/game/client/neo/c_neo_killer_infos.h +++ b/src/game/client/neo/c_neo_killer_infos.h @@ -1,5 +1,7 @@ #pragma once +#include "shareddefs.h" + static constexpr const int WEP_NAME_MAXSTRLEN = 32; struct CNEOKillerInfos @@ -13,5 +15,10 @@ struct CNEOKillerInfos wchar_t wszKilledWith[WEP_NAME_MAXSTRLEN]; }; -// Global instance of CNEOKillerInfos +void NeoUserIDsLocalKilledClear(); + +// Global instance of CNEOKillerInfos and local-player's kill record inline CNEOKillerInfos g_neoKillerInfos; +inline int g_neoUserIDsLocalKilledSize; +inline int g_neoUserIDsLocalKilled[MAX_PLAYERS_ARRAY_SAFE]; + diff --git a/src/game/client/neo/c_neo_player.cpp b/src/game/client/neo/c_neo_player.cpp index b15b3adbe3..9c34034fff 100644 --- a/src/game/client/neo/c_neo_player.cpp +++ b/src/game/client/neo/c_neo_player.cpp @@ -479,6 +479,7 @@ C_NEO_Player::C_NEO_Player() m_flTocFactor = 0.15f; memset(m_szNeoNameWDupeIdx, 0, sizeof(m_szNeoNameWDupeIdx)); + if (IsLocalPlayer()) NeoUserIDsLocalKilledClear(); m_szNameDupePos = 0; } @@ -1207,6 +1208,9 @@ void C_NEO_Player::PreThink( void ) CLocalPlayerFilter filter; enginesound->SetPlayerDSP(filter, 0, true); + NeoUserIDsLocalKilledClear(); + V_memset(&g_neoKillerInfos, 0, sizeof(CNEOKillerInfos)); + // Reset the cache of other players crosshair data on spawning in if (CHudCrosshair *crosshair = GET_HUDELEMENT(CHudCrosshair)) { @@ -1625,11 +1629,10 @@ void C_NEO_Player::Spawn( void ) m_rfAttackersAccumlator.GetForModify(i) = 0.0f; m_rfAttackersHits.GetForModify(i) = 0; } - V_memset(m_rfNeoPlayerIdxsKilledByLocal, 0, sizeof(m_rfNeoPlayerIdxsKilledByLocal)); + if (IsLocalPlayer()) NeoUserIDsLocalKilledClear(); Weapon_SetZoom(false); - SetViewOffset(VEC_VIEW_NEOSCALE(this)); auto *localPlayer = C_NEO_Player::GetLocalNEOPlayer(); diff --git a/src/game/client/neo/c_neo_player.h b/src/game/client/neo/c_neo_player.h index 6330342ae1..a2bef4f7ce 100644 --- a/src/game/client/neo/c_neo_player.h +++ b/src/game/client/neo/c_neo_player.h @@ -263,6 +263,8 @@ class C_NEO_Player : public C_HL2MP_Player unsigned char m_NeoFlags; private: + friend C_HL2MP_Player; + bool m_bFirstAliveTick; bool m_bFirstDeathTick; bool m_bPreviouslyReloading; @@ -278,9 +280,6 @@ class C_NEO_Player : public C_HL2MP_Player mutable char m_szNeoNameWDupeIdx[MAX_PLAYER_NAME_LENGTH + 10]; mutable int m_szNeoNameLocalDupeIdx; -public: - bool m_rfNeoPlayerIdxsKilledByLocal[MAX_PLAYERS_ARRAY_SAFE]; - private: C_NEO_Player(const C_NEO_Player &); }; diff --git a/src/game/client/neo/ui/neo_hud_deathnotice.cpp b/src/game/client/neo/ui/neo_hud_deathnotice.cpp index 20da8db0cd..42099f06a5 100644 --- a/src/game/client/neo/ui/neo_hud_deathnotice.cpp +++ b/src/game/client/neo/ui/neo_hud_deathnotice.cpp @@ -765,7 +765,8 @@ void CNEOHud_DeathNotice::AddPlayerDeath(IGameEvent* event) { // the event should be "player_death" const int killer = engine->GetPlayerForUserID(event->GetInt("attacker")); - const int victim = engine->GetPlayerForUserID(event->GetInt("userid")); + const int iVictimUserID = event->GetInt("userid"); + const int victim = engine->GetPlayerForUserID(iVictimUserID); const int assistInt = event->GetInt("assists"); const int assist = engine->GetPlayerForUserID(assistInt); const bool hasAssists = assist > 0; @@ -859,9 +860,24 @@ void CNEOHud_DeathNotice::AddPlayerDeath(IGameEvent* event) deathMsg.bInvolved = killer == GetLocalPlayerIndex() || victim == GetLocalPlayerIndex() || assist == GetLocalPlayerIndex(); Assert(victim >= 0 && victim < (MAX_PLAYERS + 1)); C_NEO_Player *localPlayer = C_NEO_Player::GetLocalNEOPlayer(); - if (localPlayer) + if (localPlayer + && killer == localPlayer->entindex() + && g_neoUserIDsLocalKilledSize < MAX_PLAYERS_ARRAY_SAFE) { - localPlayer->m_rfNeoPlayerIdxsKilledByLocal[victim] = (killer == localPlayer->entindex()); + // Sanity check it's not there already just in-case + bool bVictimUserIDExists = false; + for (int i = 0; i < g_neoUserIDsLocalKilledSize; ++i) + { + if (iVictimUserID == g_neoUserIDsLocalKilled[i]) + { + bVictimUserIDExists = true; + break; + } + } + if (false == bVictimUserIDExists) + { + g_neoUserIDsLocalKilled[g_neoUserIDsLocalKilledSize++] = iVictimUserID; + } } SetDeathNoticeItemDimensions(&deathMsg); diff --git a/src/game/client/neo/ui/neo_hud_killer_info.cpp b/src/game/client/neo/ui/neo_hud_killer_info.cpp index 62e4828495..86b558613f 100644 --- a/src/game/client/neo/ui/neo_hud_killer_info.cpp +++ b/src/game/client/neo/ui/neo_hud_killer_info.cpp @@ -63,13 +63,6 @@ void CNEOHud_KillerInfo::resetHUDState() void CNEOHud_KillerInfo::UpdateStateForNeoHudElementDraw() { - const bool bIsPreRoundFreeze = (NEORules()->GetRoundStatus() == NeoRoundStatus::PreRoundFreeze); - if (bIsPreRoundFreeze && false == m_preRoundFreezeCleared) - { - resetHUDState(); - } - m_preRoundFreezeCleared = bIsPreRoundFreeze; - // If to show or not const C_NEO_Player *pLocalPlayer = C_NEO_Player::GetLocalNEOPlayer(); m_bPlayerShownHud = pLocalPlayer @@ -91,8 +84,13 @@ void CNEOHud_KillerInfo::UpdateStateForNeoHudElementDraw() void CNEOHud_KillerInfo::DrawNeoHudElement() { + if (!ShouldDraw() || !m_bPlayerShownHud) + { + return; + } + const C_NEO_Player *pLocalPlayer = C_NEO_Player::GetLocalNEOPlayer(); - if (!ShouldDraw() || !m_bPlayerShownHud || !pLocalPlayer) + if (!pLocalPlayer) { return; } diff --git a/src/game/client/neo/ui/neo_hud_killer_info.h b/src/game/client/neo/ui/neo_hud_killer_info.h index 50f440186e..d78ae8945b 100644 --- a/src/game/client/neo/ui/neo_hud_killer_info.h +++ b/src/game/client/neo/ui/neo_hud_killer_info.h @@ -29,6 +29,5 @@ class CNEOHud_KillerInfo : public CNEOHud_ChildElement, public CHudElement, publ vgui::HFont m_hFontNormal; vgui::HFont m_hFontTitle; CAvatarImage m_avatar; - bool m_preRoundFreezeCleared = false; bool m_bPlayerShownHud = false; }; diff --git a/src/game/client/neo/ui/neo_scoreboard.cpp b/src/game/client/neo/ui/neo_scoreboard.cpp index b9ac0d98b5..d2175c25f0 100644 --- a/src/game/client/neo/ui/neo_scoreboard.cpp +++ b/src/game/client/neo/ui/neo_scoreboard.cpp @@ -392,7 +392,15 @@ void CNEOScoreBoard::Update() pPlayerInfo->iTakenDmgs = pLocalPlayer->GetAttackersScores(pNeoPlayer->entindex()); pPlayerInfo->iTakenHits = pLocalPlayer->GetAttackerHits(pNeoPlayer->entindex()); pPlayerInfo->bKilledYou = (pNeoPlayer->entindex() == g_neoKillerInfos.iEntIndex); - pPlayerInfo->bYouKilled = pLocalPlayer->m_rfNeoPlayerIdxsKilledByLocal[pNeoPlayer->entindex()]; + pPlayerInfo->bYouKilled = false; + for (int i = 0; i < g_neoUserIDsLocalKilledSize; ++i) + { + if (g_neoUserIDsLocalKilled[i] == pPlayerInfo->iUserID) + { + pPlayerInfo->bYouKilled = true; + break; + } + } } else { diff --git a/src/game/client/neo/ui/neo_scoreboard.h b/src/game/client/neo/ui/neo_scoreboard.h index e6cbcfb275..e9a679119c 100644 --- a/src/game/client/neo/ui/neo_scoreboard.h +++ b/src/game/client/neo/ui/neo_scoreboard.h @@ -98,7 +98,7 @@ class CNEOScoreBoard : public vgui::Panel, public IViewPortPanel, public CGameEv int m_HLTVSpectators = 0; int m_iTotalPlayers = 0; - CNEOScoreBoardPlayer m_playersInfo[MAX_PLAYERS + 1] = {}; + CNEOScoreBoardPlayer m_playersInfo[MAX_PLAYERS_ARRAY_SAFE] = {}; CNEOScoreBoardPlayer m_playerPopup = {}; wchar_t m_wszHostname[128] = {};