From fe67df2a3b543ae60a217840b8439bc9f5931b6a Mon Sep 17 00:00:00 2001 From: AdamTadeusz Date: Wed, 6 Nov 2024 15:32:22 +0000 Subject: [PATCH 1/3] prevents respawning mid round through rejoining or reselecting a loadout --- mp/src/game/server/neo/neo_client.cpp | 2 ++ mp/src/game/server/neo/neo_player.cpp | 4 +++ mp/src/game/server/neo/neo_player.h | 3 ++ mp/src/game/shared/neo/neo_gamerules.cpp | 45 ++++++++++++++++++++++-- mp/src/game/shared/neo/neo_gamerules.h | 3 ++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/mp/src/game/server/neo/neo_client.cpp b/mp/src/game/server/neo/neo_client.cpp index 87e36d7cd..c32e904e8 100644 --- a/mp/src/game/server/neo/neo_client.cpp +++ b/mp/src/game/server/neo/neo_client.cpp @@ -50,6 +50,8 @@ void FinishClientPutInServer( CNEO_Player *pPlayer ) const CNEORules::RestoreInfo &restoreInfo = restoredInfos.Element(hdl); pPlayer->m_iXP.Set(restoreInfo.xp); pPlayer->IncrementDeathCount(restoreInfo.deaths); + pPlayer->SetDeathTime(restoreInfo.deathTime); + pPlayer->m_bSpawnedThisRound = restoreInfo.spawnedThisRound; ClientPrint(pPlayer, HUD_PRINTTALK, "Your XP and death count have been restored.\n"); } } diff --git a/mp/src/game/server/neo/neo_player.cpp b/mp/src/game/server/neo/neo_player.cpp index 72f56d177..d8553feac 100644 --- a/mp/src/game/server/neo/neo_player.cpp +++ b/mp/src/game/server/neo/neo_player.cpp @@ -503,6 +503,10 @@ void CNEO_Player::Spawn(void) if (teamNumber == TEAM_JINRAI || teamNumber == TEAM_NSF) { + if (NEORules()->IsRoundOn()) + { + m_bSpawnedThisRound = true; // NEO TODO (Adam) should people who were spectating at the start of the match and potentially have unfair information about the enemy team be allowed to join the game? + } State_Transition(STATE_ACTIVE); } diff --git a/mp/src/game/server/neo/neo_player.h b/mp/src/game/server/neo/neo_player.h index d0449aa36..aebda3b14 100644 --- a/mp/src/game/server/neo/neo_player.h +++ b/mp/src/game/server/neo/neo_player.h @@ -199,6 +199,8 @@ class CNEO_Player : public CHL2MP_Player AttackersTotals GetAttackersTotals() const; void StartShowDmgStats(const CTakeDamageInfo *info); + inline void SetDeathTime(const float deathTime) { m_flDeathTime.Set(deathTime); } + IMPLEMENT_NETWORK_VAR_FOR_DERIVED(m_EyeAngleOffset); private: @@ -258,6 +260,7 @@ class CNEO_Player : public CHL2MP_Player CNetworkVar(bool, m_bClientWantNeoName); bool m_bIsPendingSpawnForThisRound; + bool m_bSpawnedThisRound = false; bool m_bKilledInflicted = false; // Server-side var only int m_iTeamDamageInflicted = 0; int m_iTeamKillsInflicted = 0; diff --git a/mp/src/game/shared/neo/neo_gamerules.cpp b/mp/src/game/shared/neo/neo_gamerules.cpp index ff8d8e127..b23c6fe87 100644 --- a/mp/src/game/shared/neo/neo_gamerules.cpp +++ b/mp/src/game/shared/neo/neo_gamerules.cpp @@ -2012,6 +2012,11 @@ void CNEORules::StartNextRound() continue; } + if (pPlayer->GetTeamNumber() == TEAM_SPECTATOR) + { + continue; + } + pPlayer->m_bKilledInflicted = false; if (pPlayer->GetActiveWeapon()) { @@ -2121,6 +2126,11 @@ bool CNEORules::IsRoundLive() const return m_nRoundStatus == NeoRoundStatus::RoundLive; } +bool CNEORules::IsRoundOn() const +{ + return (m_nRoundStatus == NeoRoundStatus::PreRoundFreeze) || (m_nRoundStatus == NeoRoundStatus::RoundLive) || (m_nRoundStatus == NeoRoundStatus::PostRound); +} + void CNEORules::CreateStandardEntities(void) { BaseClass::CreateStandardEntities(); @@ -3387,9 +3397,11 @@ void CNEORules::ClientDisconnected(edict_t* pClient) const RestoreInfo restoreInfo{ .xp = pNeoPlayer->m_iXP.Get(), .deaths = pNeoPlayer->DeathCount(), + .spawnedThisRound = pNeoPlayer->m_bSpawnedThisRound, + .deathTime = gpGlobals->curtime, // NEOTODO (Adam) prevent players abusing retry command to save themselves in games with respawns. Should award xp to whoever did most damage to disconnecting player, for now simply ensure they can't respawn too quickly }; - if (restoreInfo.xp == 0 && restoreInfo.deaths == 0) + if (restoreInfo.xp == 0 && restoreInfo.deaths == 0 && restoreInfo.deathTime == 0.f && restoreInfo.spawnedThisRound == false) { m_pRestoredInfos.Remove(accountID); } @@ -3441,11 +3453,16 @@ bool CNEORules::FPlayerCanRespawn(CBasePlayer* pPlayer) if (jinrai && nsf) { - if (m_nRoundStatus == NeoRoundStatus::Warmup || m_nRoundStatus == NeoRoundStatus::Idle || - m_nRoundStatus == NeoRoundStatus::Pause) + if (!IsRoundOn()) { return true; } + + CNEO_Player* pNeoPlayer = ToNEOPlayer(pPlayer); + if (pNeoPlayer->m_bSpawnedThisRound) + { + return false; + } } else { @@ -3511,6 +3528,28 @@ void CNEORules::SetRoundStatus(NeoRoundStatus status) #endif } +#ifdef GAME_DLL + if (status == NeoRoundStatus::PostRound) + { + for (int i = 1; i < gpGlobals->maxClients; i++) + { + if (auto player = static_cast(UTIL_PlayerByIndex(i))) + { + player->m_bSpawnedThisRound = false; + player->SetDeathTime(0.f); + } + } + + auto currentHandle = m_pRestoredInfos.FirstHandle(); + while (m_pRestoredInfos.IsValidHandle(currentHandle)) + { + m_pRestoredInfos[currentHandle].spawnedThisRound = false; + m_pRestoredInfos[currentHandle].deathTime = 0.f; + currentHandle = m_pRestoredInfos.NextHandle(currentHandle); + } + } +#endif // GAME_DLL + m_nRoundStatus = status; } diff --git a/mp/src/game/shared/neo/neo_gamerules.h b/mp/src/game/shared/neo/neo_gamerules.h index 21ae48054..fa4e7bc78 100644 --- a/mp/src/game/shared/neo/neo_gamerules.h +++ b/mp/src/game/shared/neo/neo_gamerules.h @@ -246,6 +246,7 @@ class CNEORules : public CHL2MPRules, public CGameEventListener #endif bool IsRoundPreRoundFreeze() const; bool IsRoundLive() const; + bool IsRoundOn() const; bool IsRoundOver() const; #ifdef GAME_DLL void GatherGameTypeVotes(); @@ -349,6 +350,8 @@ class CNEORules : public CHL2MPRules, public CGameEventListener { int xp; int deaths; + bool spawnedThisRound; + float deathTime; }; // AccountID_t <- CSteamID::GetAccountID CUtlHashtable m_pRestoredInfos; From 865b3aa973c4c2b4762e804b80aeef7ca2ddcce9 Mon Sep 17 00:00:00 2001 From: AdamTadeusz Date: Wed, 6 Nov 2024 15:41:31 +0000 Subject: [PATCH 2/3] apply freeze status on spawn --- mp/src/game/server/neo/neo_player.cpp | 11 +++++++++-- mp/src/game/shared/neo/neo_gamerules.cpp | 5 ----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mp/src/game/server/neo/neo_player.cpp b/mp/src/game/server/neo/neo_player.cpp index d8553feac..5e6bf9e7b 100644 --- a/mp/src/game/server/neo/neo_player.cpp +++ b/mp/src/game/server/neo/neo_player.cpp @@ -503,10 +503,17 @@ void CNEO_Player::Spawn(void) if (teamNumber == TEAM_JINRAI || teamNumber == TEAM_NSF) { - if (NEORules()->IsRoundOn()) + if (NEORules()->GetRoundStatus() == NeoRoundStatus::PreRoundFreeze) { - m_bSpawnedThisRound = true; // NEO TODO (Adam) should people who were spectating at the start of the match and potentially have unfair information about the enemy team be allowed to join the game? + AddFlag(FL_GODMODE); + AddNeoFlag(NEO_FL_FREEZETIME); } + + if (NEORules()->IsRoundOn()) + { // NEO TODO (Adam) should people who were spectating at the start of the match and potentially have unfair information about the enemy team be allowed to join the game? + m_bSpawnedThisRound = true; + } + State_Transition(STATE_ACTIVE); } diff --git a/mp/src/game/shared/neo/neo_gamerules.cpp b/mp/src/game/shared/neo/neo_gamerules.cpp index b23c6fe87..61c2cbe35 100644 --- a/mp/src/game/shared/neo/neo_gamerules.cpp +++ b/mp/src/game/shared/neo/neo_gamerules.cpp @@ -2024,11 +2024,6 @@ void CNEORules::StartNextRound() } pPlayer->RemoveAllItems(true); pPlayer->Spawn(); - if (gpGlobals->curtime < m_flNeoRoundStartTime + mp_neo_preround_freeze_time.GetFloat()) - { - pPlayer->AddFlag(FL_GODMODE); - pPlayer->AddNeoFlag(NEO_FL_FREEZETIME); - } pPlayer->m_bInAim = false; pPlayer->m_bInThermOpticCamo = false; From 5cc08d07997a0ec61ae7df24f815102891c36449 Mon Sep 17 00:00:00 2001 From: AdamTadeusz Date: Wed, 6 Nov 2024 15:58:12 +0000 Subject: [PATCH 3/3] don't penalise if player was already dead when disconnecting --- mp/src/game/shared/neo/neo_gamerules.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mp/src/game/shared/neo/neo_gamerules.cpp b/mp/src/game/shared/neo/neo_gamerules.cpp index 61c2cbe35..5e1789d9e 100644 --- a/mp/src/game/shared/neo/neo_gamerules.cpp +++ b/mp/src/game/shared/neo/neo_gamerules.cpp @@ -3393,7 +3393,7 @@ void CNEORules::ClientDisconnected(edict_t* pClient) .xp = pNeoPlayer->m_iXP.Get(), .deaths = pNeoPlayer->DeathCount(), .spawnedThisRound = pNeoPlayer->m_bSpawnedThisRound, - .deathTime = gpGlobals->curtime, // NEOTODO (Adam) prevent players abusing retry command to save themselves in games with respawns. Should award xp to whoever did most damage to disconnecting player, for now simply ensure they can't respawn too quickly + .deathTime = pNeoPlayer->IsAlive() ? gpGlobals->curtime : pNeoPlayer->GetDeathTime(), // NEOTODO (Adam) prevent players abusing retry command to save themselves in games with respawns. Should award xp to whoever did most damage to disconnecting player, for now simply ensure they can't respawn too quickly }; if (restoreInfo.xp == 0 && restoreInfo.deaths == 0 && restoreInfo.deathTime == 0.f && restoreInfo.spawnedThisRound == false)