Try fix issue with savegames

This commit is contained in:
Learath2 2024-07-24 16:25:54 +02:00
parent a84a53c5fe
commit 90c4a552ed
5 changed files with 41 additions and 7 deletions

View file

@ -752,6 +752,11 @@ bool CPlayer::CanOverrideDefaultEmote() const
return m_LastEyeEmote == 0 || m_LastEyeEmote + (int64_t)g_Config.m_SvEyeEmoteChangeDelay * Server()->TickSpeed() < Server()->Tick();
}
bool CPlayer::CanSpec() const
{
return m_pCharacter->IsGrounded() && m_pCharacter->m_Pos == m_pCharacter->m_PrevPos;
}
void CPlayer::ProcessPause()
{
if(m_ForcePauseTime && m_ForcePauseTime < Server()->Tick())
@ -760,7 +765,7 @@ void CPlayer::ProcessPause()
Pause(PAUSE_NONE, true);
}
if(m_Paused == PAUSE_SPEC && !m_pCharacter->IsPaused() && m_pCharacter->IsGrounded() && m_pCharacter->m_Pos == m_pCharacter->m_PrevPos)
if(m_Paused == PAUSE_SPEC && !m_pCharacter->IsPaused() && CanSpec())
{
m_pCharacter->Pause(true);
GameServer()->CreateDeath(m_pCharacter->m_Pos, m_ClientId, GameServer()->m_pController->GetMaskForPlayerWorldEvent(m_ClientId));

View file

@ -179,6 +179,7 @@ public:
int Pause(int State, bool Force);
int ForcePause(int Time);
int IsPaused() const;
bool CanSpec() const;
bool IsPlaying() const;
int64_t m_Last_KickVote;

View file

@ -17,7 +17,14 @@ void CSaveTee::Save(CCharacter *pChr)
str_copy(m_aName, pChr->Server()->ClientName(m_ClientId), sizeof(m_aName));
m_Alive = pChr->m_Alive;
// This is extremely suspect code, probably interacts badly with force pause
m_Paused = absolute(pChr->m_pPlayer->IsPaused());
if(m_Paused == CPlayer::PAUSE_SPEC && !pChr->m_Paused)
{
m_Paused = CPlayer::PAUSE_NONE;
}
m_NeededFaketuning = pChr->m_NeededFaketuning;
m_TeeStarted = pChr->Teams()->TeeStarted(m_ClientId);
@ -121,8 +128,10 @@ void CSaveTee::Save(CCharacter *pChr)
FormatUuid(pChr->GameServer()->GameUuid(), m_aGameUuid, sizeof(m_aGameUuid));
}
void CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
bool CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
{
bool Valid = true;
pChr->m_pPlayer->Pause(m_Paused, true);
pChr->m_Alive = m_Alive;
@ -239,6 +248,13 @@ void CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
pChr->ForceSetRescue(RESCUEMODE_AUTO);
pChr->ForceSetRescue(RESCUEMODE_MANUAL);
}
if(pChr->m_pPlayer->IsPaused() == -1 * CPlayer::PAUSE_SPEC && !pChr->m_pPlayer->CanSpec())
{
Valid = false;
}
return Valid;
}
char *CSaveTee::GetString(const CSaveTeam *pTeam)
@ -570,7 +586,7 @@ bool CSaveTeam::HandleSaveError(int Result, int ClientId, CGameContext *pGameCon
return true;
}
void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong)
bool CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong)
{
IGameController *pController = pGameServer->m_pController;
CGameTeams *pTeams = &pController->Teams();
@ -579,6 +595,7 @@ void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakSt
pTeams->SetTeamLock(Team, m_TeamLocked);
pTeams->SetPractice(Team, m_Practice);
bool ContainsInvalidPlayer = false;
int aPlayerCids[MAX_CLIENTS];
for(int i = m_MembersCount; i-- > 0;)
{
@ -587,7 +604,7 @@ void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakSt
if(pGameServer->m_apPlayers[ClientId] && pTeams->m_Core.Team(ClientId) == Team)
{
CCharacter *pChr = MatchCharacter(pGameServer, m_pSavedTees[i].GetClientId(), i, KeepCurrentWeakStrong);
m_pSavedTees[i].Load(pChr, Team);
ContainsInvalidPlayer |= !m_pSavedTees[i].Load(pChr, Team);
}
}
@ -603,6 +620,8 @@ void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakSt
}
// remove projectiles and laser
pGameServer->m_World.RemoveEntitiesFromPlayers(aPlayerCids, m_MembersCount);
return !ContainsInvalidPlayer;
}
CCharacter *CSaveTeam::MatchCharacter(CGameContext *pGameServer, int ClientId, int SaveId, bool KeepCurrentCharacter) const

View file

@ -25,7 +25,7 @@ public:
CSaveTee();
~CSaveTee() = default;
void Save(CCharacter *pchr);
void Load(CCharacter *pchr, int Team, bool IsSwap = false);
bool Load(CCharacter *pchr, int Team, bool IsSwap = false);
char *GetString(const CSaveTeam *pTeam);
int FromString(const char *pString);
void LoadHookedPlayer(const CSaveTeam *pTeam);
@ -149,7 +149,7 @@ public:
// returns true if a team can load, otherwise writes a nice error Message in pMessage
bool MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *pClientId, int NumPlayer, char *pMessage, int MessageLen) const;
int Save(CGameContext *pGameServer, int Team, bool Dry = false);
void Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong);
bool Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong);
CSaveTee *m_pSavedTees = nullptr;

View file

@ -1026,11 +1026,20 @@ void CGameTeams::ProcessSaveTeam()
m_apSaveTeamResult[Team]->m_SaveId,
m_apSaveTeamResult[Team]->m_SavedTeam.GetString());
}
bool TeamValid = false;
if(Count(Team) > 0)
{
// keep current weak/strong order as on some maps there is no other way of switching
m_apSaveTeamResult[Team]->m_SavedTeam.Load(GameServer(), Team, true);
TeamValid = m_apSaveTeamResult[Team]->m_SavedTeam.Load(GameServer(), Team, true);
}
if(!TeamValid)
{
GameServer()->SendChatTeam(Team, "Your team has been killed because it contains an invalid tee state");
KillTeam(Team, -1, -1);
}
char aSaveId[UUID_MAXSTRSIZE];
FormatUuid(m_apSaveTeamResult[Team]->m_SaveId, aSaveId, UUID_MAXSTRSIZE);
dbg_msg("save", "Load successful: %s", aSaveId);