mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Try to fix "start line skipping"
Previously, tees could go around the start line on some maps, going directly to the finish line while leaving one tee behind at the start. By letting that sole tee start and kill itself, the team could be directly at the finish at time 0:00. Fix this by requiring every tee of a team to hit the start line before being able to finish. Tees can still get some advantage by skipping the start line, but it will no longer be a 0:00 finish.
This commit is contained in:
parent
dbc05f6bb0
commit
35402b07d7
|
@ -20,6 +20,7 @@ void CGameTeams::Reset()
|
|||
{
|
||||
m_TeamState[i] = TEAMSTATE_EMPTY;
|
||||
m_TeamLocked[i] = false;
|
||||
m_TeeStarted[i] = false;
|
||||
m_TeeFinished[i] = false;
|
||||
m_LastChat[i] = 0;
|
||||
m_pSaveTeamResult[i] = nullptr;
|
||||
|
@ -71,6 +72,7 @@ void CGameTeams::OnCharacterStart(int ClientID)
|
|||
if(g_Config.m_SvTeam != 3 &&
|
||||
(m_Core.Team(ClientID) == TEAM_FLOCK || m_Core.Team(ClientID) == TEAM_SUPER))
|
||||
{
|
||||
m_TeeStarted[ClientID] = true;
|
||||
pStartingChar->m_DDRaceState = DDRACE_STARTED;
|
||||
pStartingChar->m_StartTime = Tick;
|
||||
return;
|
||||
|
@ -113,6 +115,11 @@ void CGameTeams::OnCharacterStart(int ClientID)
|
|||
}
|
||||
}
|
||||
|
||||
if(!Waiting)
|
||||
{
|
||||
m_TeeStarted[ClientID] = true;
|
||||
}
|
||||
|
||||
if(m_TeamState[m_Core.Team(ClientID)] < TEAMSTATE_STARTED && !Waiting)
|
||||
{
|
||||
ChangeTeamState(m_Core.Team(ClientID), TEAMSTATE_STARTED);
|
||||
|
@ -183,8 +190,10 @@ void CGameTeams::OnCharacterFinish(int ClientID)
|
|||
}
|
||||
else
|
||||
{
|
||||
m_TeeFinished[ClientID] = true;
|
||||
|
||||
if(m_TeeStarted[ClientID])
|
||||
{
|
||||
m_TeeFinished[ClientID] = true;
|
||||
}
|
||||
CheckTeamFinished(m_Core.Team(ClientID));
|
||||
}
|
||||
}
|
||||
|
@ -203,6 +212,7 @@ void CGameTeams::CheckTeamFinished(int Team)
|
|||
CPlayer *pPlayer = GetPlayer(i);
|
||||
if(pPlayer && pPlayer->IsPlaying())
|
||||
{
|
||||
m_TeeStarted[i] = false;
|
||||
m_TeeFinished[i] = false;
|
||||
|
||||
TeamPlayers[PlayersCount++] = pPlayer;
|
||||
|
@ -287,6 +297,7 @@ const char *CGameTeams::SetCharacterTeam(int ClientID, int Team)
|
|||
|
||||
void CGameTeams::SetForceCharacterTeam(int ClientID, int Team)
|
||||
{
|
||||
m_TeeStarted[ClientID] = false;
|
||||
m_TeeFinished[ClientID] = false;
|
||||
int OldTeam = m_Core.Team(ClientID);
|
||||
|
||||
|
@ -349,6 +360,10 @@ void CGameTeams::ChangeTeamState(int Team, int State)
|
|||
|
||||
bool CGameTeams::TeamFinished(int Team)
|
||||
{
|
||||
if(m_TeamState[Team] != TEAMSTATE_STARTED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < MAX_CLIENTS; ++i)
|
||||
if(m_Core.Team(i) == Team && !m_TeeFinished[i])
|
||||
return false;
|
||||
|
@ -909,6 +924,21 @@ void CGameTeams::OnCharacterDeath(int ClientID, int Weapon)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(m_TeamState[m_Core.Team(ClientID)] == CGameTeams::TEAMSTATE_STARTED && !m_TeeStarted[ClientID])
|
||||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), "This team cannot finish anymore because '%s' left the team before hitting the start", Server()->ClientName(ClientID));
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_Core.Team(i) != Team || i == ClientID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
GameServer()->SendChatTarget(i, aBuf);
|
||||
}
|
||||
|
||||
ChangeTeamState(Team, CGameTeams::TEAMSTATE_STARTED_UNFINISHABLE);
|
||||
}
|
||||
SetForceCharacterTeam(ClientID, TEAM_FLOCK);
|
||||
CheckTeamFinished(Team);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,14 @@
|
|||
class CGameTeams
|
||||
{
|
||||
int m_TeamState[MAX_CLIENTS];
|
||||
// `m_TeeStarted` is used to keep track whether a given tee has hit the
|
||||
// start of the map yet. If a tee that leaves hasn't hit the start line
|
||||
// yet, the team will be marked as "not allowed to finish"
|
||||
// (`TEAMSTATE_STARTED_UNFINISHABLE`). If this were not the case, tees
|
||||
// could go around the startline on a map, leave one tee behind at
|
||||
// start, go to the finish line, let the tee start and kill, allowing
|
||||
// the team to finish instantly.
|
||||
bool m_TeeStarted[MAX_CLIENTS];
|
||||
bool m_TeeFinished[MAX_CLIENTS];
|
||||
bool m_TeamLocked[MAX_CLIENTS];
|
||||
uint64_t m_Invited[MAX_CLIENTS];
|
||||
|
@ -31,6 +39,9 @@ public:
|
|||
TEAMSTATE_EMPTY,
|
||||
TEAMSTATE_OPEN,
|
||||
TEAMSTATE_STARTED,
|
||||
// Happens when a tee that hasn't hit the start tiles leaves
|
||||
// the team.
|
||||
TEAMSTATE_STARTED_UNFINISHABLE,
|
||||
TEAMSTATE_FINISHED
|
||||
};
|
||||
|
||||
|
@ -126,9 +137,9 @@ public:
|
|||
return m_TeamState[Team] == CGameTeams::TEAMSTATE_STARTED;
|
||||
}
|
||||
|
||||
void SetFinished(int ClientID, bool finished)
|
||||
void SetFinished(int ClientID, bool Finished)
|
||||
{
|
||||
m_TeeFinished[ClientID] = finished;
|
||||
m_TeeFinished[ClientID] = Finished;
|
||||
}
|
||||
|
||||
void SetSaving(int TeamID, std::shared_ptr<CScoreSaveResult> &SaveResult)
|
||||
|
|
Loading…
Reference in a new issue