mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Kill unfinishable teams if they don't enter /practice within a minute
This is to avoid players playing in unfinishable teams for a long time if they don't understand the system messages. Fixes #4088.
This commit is contained in:
parent
1feea5f25c
commit
d6c344853a
|
@ -29,6 +29,7 @@ void CGameTeams::Reset()
|
|||
m_Practice[i] = false;
|
||||
m_LastSwap[i] = 0;
|
||||
m_TeamSentStartWarning[i] = false;
|
||||
m_TeamUnfinishableKillTick[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +39,8 @@ void CGameTeams::ResetRoundState(int Team)
|
|||
ResetSwitchers(Team);
|
||||
m_LastSwap[Team] = 0;
|
||||
|
||||
m_Practice[Team] = 0;
|
||||
m_Practice[Team] = false;
|
||||
m_TeamUnfinishableKillTick[Team] = -1;
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_Core.Team(i) == Team && GameServer()->m_apPlayers[i])
|
||||
|
@ -127,6 +129,7 @@ void CGameTeams::OnCharacterStart(int ClientID)
|
|||
{
|
||||
ChangeTeamState(m_Core.Team(ClientID), TEAMSTATE_STARTED);
|
||||
m_TeamSentStartWarning[m_Core.Team(ClientID)] = false;
|
||||
m_TeamUnfinishableKillTick[m_Core.Team(ClientID)] = -1;
|
||||
|
||||
int NumPlayers = Count(m_Core.Team(ClientID));
|
||||
|
||||
|
@ -205,6 +208,31 @@ void CGameTeams::OnCharacterFinish(int ClientID)
|
|||
void CGameTeams::Tick()
|
||||
{
|
||||
int Now = Server()->Tick();
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_TeamUnfinishableKillTick[i] == -1 || m_TeamState[i] != TEAMSTATE_STARTED_UNFINISHABLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(Now >= m_TeamUnfinishableKillTick[i])
|
||||
{
|
||||
if(m_Practice[i])
|
||||
{
|
||||
m_TeamUnfinishableKillTick[i] = -1;
|
||||
continue;
|
||||
}
|
||||
KillTeam(i, -1);
|
||||
for(int j = 0; j < MAX_CLIENTS; j++)
|
||||
{
|
||||
if(m_Core.Team(j) == i)
|
||||
{
|
||||
GameServer()->SendChatTarget(j, "Your team was killed because it couldn't finish anymore and hasn't entered /practice mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Frequency = Server()->TickSpeed() * 60;
|
||||
int Remainder = Server()->TickSpeed() * 30;
|
||||
uint64_t TeamHasWantedStartTime = 0;
|
||||
|
@ -434,6 +462,22 @@ void CGameTeams::ChangeTeamState(int Team, int State)
|
|||
m_TeamState[Team] = State;
|
||||
}
|
||||
|
||||
void CGameTeams::KillTeam(int Team, int NewStrongID)
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_Core.Team(i) == Team && GameServer()->m_apPlayers[i])
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->m_VotedForPractice = false;
|
||||
GameServer()->m_apPlayers[i]->KillCharacter(WEAPON_SELF);
|
||||
if(NewStrongID != -1 && i != NewStrongID)
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->Respawn(true); // spawn the rest of team with weak hook on the killer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CGameTeams::TeamFinished(int Team)
|
||||
{
|
||||
if(m_TeamState[Team] != TEAMSTATE_STARTED)
|
||||
|
@ -982,20 +1026,17 @@ void CGameTeams::OnCharacterDeath(int ClientID, int Weapon)
|
|||
|
||||
m_Practice[Team] = false;
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(m_Core.Team(i) == Team && GameServer()->m_apPlayers[i])
|
||||
KillTeam(Team, Weapon == WEAPON_SELF ? ClientID : -1);
|
||||
if(Count(Team) > 1)
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->m_VotedForPractice = false;
|
||||
|
||||
if(i != ClientID)
|
||||
if(m_Core.Team(i) == Team && GameServer()->m_apPlayers[i])
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->KillCharacter(WEAPON_SELF);
|
||||
if(Weapon == WEAPON_SELF)
|
||||
GameServer()->m_apPlayers[i]->Respawn(true); // spawn the rest of team with weak hook on the killer
|
||||
}
|
||||
if(Count(Team) > 1)
|
||||
GameServer()->SendChatTarget(i, aBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1003,7 +1044,7 @@ void CGameTeams::OnCharacterDeath(int ClientID, int Weapon)
|
|||
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));
|
||||
str_format(aBuf, sizeof(aBuf), "This team cannot finish anymore because '%s' left the team before hitting the start, enter /practice mode to avoid being killed in 60 seconds", Server()->ClientName(ClientID));
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_Core.Team(i) != Team || i == ClientID)
|
||||
|
@ -1013,6 +1054,7 @@ void CGameTeams::OnCharacterDeath(int ClientID, int Weapon)
|
|||
GameServer()->SendChatTarget(i, aBuf);
|
||||
}
|
||||
|
||||
m_TeamUnfinishableKillTick[Team] = Server()->Tick() + 60 * Server()->TickSpeed();
|
||||
ChangeTeamState(Team, CGameTeams::TEAMSTATE_STARTED_UNFINISHABLE);
|
||||
}
|
||||
SetForceCharacterTeam(ClientID, TEAM_FLOCK);
|
||||
|
@ -1044,14 +1086,7 @@ void CGameTeams::SetClientInvited(int Team, int ClientID, bool Invited)
|
|||
|
||||
void CGameTeams::KillSavedTeam(int ClientID, int Team)
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_Core.Team(i) == Team && GameServer()->m_apPlayers[i])
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->m_VotedForPractice = false;
|
||||
GameServer()->m_apPlayers[i]->KillCharacter(WEAPON_SELF);
|
||||
}
|
||||
}
|
||||
KillTeam(Team, -1);
|
||||
}
|
||||
|
||||
void CGameTeams::ResetSavedTeam(int ClientID, int Team)
|
||||
|
|
|
@ -27,9 +27,18 @@ class CGameTeams
|
|||
std::shared_ptr<CScoreSaveResult> m_pSaveTeamResult[MAX_CLIENTS];
|
||||
uint64_t m_LastSwap[MAX_CLIENTS];
|
||||
bool m_TeamSentStartWarning[MAX_CLIENTS];
|
||||
// `m_TeamUnfinishableKillTick` is -1 by default and gets set when a
|
||||
// team becomes unfinishable. If the team hasn't entered practice mode
|
||||
// by that time, it'll get killed to prevent people not understanding
|
||||
// the message from playing for a long time in an unfinishable team.
|
||||
int m_TeamUnfinishableKillTick[MAX_CLIENTS];
|
||||
|
||||
class CGameContext *m_pGameContext;
|
||||
|
||||
// Kill the whole team, making the player `NewStrongID` have strong
|
||||
// hook on everyone else. `NewStrongID` can be -1 to get the normal
|
||||
// spawning order.
|
||||
void KillTeam(int Team, int NewStrongID);
|
||||
bool TeamFinished(int Team);
|
||||
void OnTeamFinish(CPlayer **Players, unsigned int Size, float Time, const char *pTimestamp);
|
||||
void OnFinish(CPlayer *Player, float Time, const char *pTimestamp);
|
||||
|
|
Loading…
Reference in a new issue