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

Fair spawn mechanics #809

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mp/src/game/server/neo/neo_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
Expand Down
11 changes: 11 additions & 0 deletions mp/src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,17 @@ void CNEO_Player::Spawn(void)

if (teamNumber == TEAM_JINRAI || teamNumber == TEAM_NSF)
{
if (NEORules()->GetRoundStatus() == NeoRoundStatus::PreRoundFreeze)
{
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);
}

Expand Down
3 changes: 3 additions & 0 deletions mp/src/game/server/neo/neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
50 changes: 42 additions & 8 deletions mp/src/game/shared/neo/neo_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2012,18 +2012,18 @@ void CNEORules::StartNextRound()
continue;
}

if (pPlayer->GetTeamNumber() == TEAM_SPECTATOR)
{
continue;
}

pPlayer->m_bKilledInflicted = false;
if (pPlayer->GetActiveWeapon())
{
pPlayer->GetActiveWeapon()->Holster();
}
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;
Expand Down Expand Up @@ -2121,6 +2121,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();
Expand Down Expand Up @@ -3387,9 +3392,11 @@ void CNEORules::ClientDisconnected(edict_t* pClient)
const RestoreInfo restoreInfo{
.xp = pNeoPlayer->m_iXP.Get(),
.deaths = pNeoPlayer->DeathCount(),
.spawnedThisRound = pNeoPlayer->m_bSpawnedThisRound,
.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)
if (restoreInfo.xp == 0 && restoreInfo.deaths == 0 && restoreInfo.deathTime == 0.f && restoreInfo.spawnedThisRound == false)
{
m_pRestoredInfos.Remove(accountID);
}
Expand Down Expand Up @@ -3441,11 +3448,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
{
Expand Down Expand Up @@ -3511,6 +3523,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<CNEO_Player*>(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;
}

Expand Down
3 changes: 3 additions & 0 deletions mp/src/game/shared/neo/neo_gamerules.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -349,6 +350,8 @@ class CNEORules : public CHL2MPRules, public CGameEventListener
{
int xp;
int deaths;
bool spawnedThisRound;
float deathTime;
};
// AccountID_t <- CSteamID::GetAccountID
CUtlHashtable<AccountID_t, RestoreInfo> m_pRestoredInfos;
Expand Down