diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index f791d355eb..c67e7b7905 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -150,6 +150,7 @@ MACRO_CONFIG_INT(SvFastDownload, sv_fast_download, 0, 0, 1, CFGFLAG_SERVER, "Ena MACRO_CONFIG_INT(SvShotgunBulletSound, sv_shotgun_bullet_sound, 0, 0, 1, CFGFLAG_SERVER, "Crazy shotgun bullet sound on/off") MACRO_CONFIG_INT(SvCheckpointSave, sv_checkpoint_save, 1, 0, 1, CFGFLAG_SERVER, "Whether to save checkpoint times to the score file") +MACRO_CONFIG_INT(SvStrictCheckpoints, sv_strict_checkpoints, 0, 0, 1, CFGFLAG_SERVER, "Whether one has to pass all checkpoints in the right order to finish a race") MACRO_CONFIG_STR(SvScoreFolder, sv_score_folder, 32, "records", CFGFLAG_SERVER, "Folder to save score files to") #if defined(CONF_SQL) diff --git a/src/game/collision.cpp b/src/game/collision.cpp index fd184a3606..12e470a624 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -38,6 +38,7 @@ void CCollision::Init(class CLayers *pLayers) m_Width = m_pLayers->GameLayer()->m_Width; m_Height = m_pLayers->GameLayer()->m_Height; m_pTiles = static_cast(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data)); + m_MaxCheckpoint = -1; if(m_pLayers->TeleLayer()) m_pTele = static_cast(m_pLayers->Map()->GetData(m_pLayers->TeleLayer()->m_Tele)); @@ -137,6 +138,14 @@ void CCollision::Init(class CLayers *pLayers) if(Index == TILE_THROUGH || (Index >= TILE_FREEZE && Index <= TILE_UNFREEZE) || (Index >= TILE_SWITCHOPEN && Index <= TILE_TELECHECKIN) || (Index >= TILE_BEGIN && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_NPH) || (Index >= TILE_EHOOK_START && Index <= TILE_SOLO_END) || (Index >= TILE_DFREEZE && Index <= TILE_DUNFREEZE)) m_pTiles[i].m_Index = Index; } + + int cp = IsCheckpoint(i); + if (cp > m_MaxCheckpoint) + m_MaxCheckpoint = cp; + + int cpf = IsFCheckpoint(i); + if (cpf > m_MaxCheckpoint) + m_MaxCheckpoint = cpf; } if(m_NumSwitchers) { diff --git a/src/game/collision.h b/src/game/collision.h index f28e2ad148..dd3ab14fca 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -87,6 +87,7 @@ class CCollision int IsCheckpoint(int Index); int IsFCheckpoint(int Index); + int m_MaxCheckpoint; int IsMover(int x, int y, int* Flags); diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index eac8e6a9ca..7a7f7621fd 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -1190,6 +1190,9 @@ void CCharacter::HandleTiles(int Index) int cp = GameServer()->Collision()->IsCheckpoint(MapIndex); if(cp != -1 && m_DDRaceState == DDRACE_STARTED && cp > m_CpActive) { + if (g_Config.m_SvStrictCheckpoints && cp != m_CpActive + 1) + return; + m_CpActive = cp; m_CpCurrent[cp] = m_Time; m_CpTick = Server()->Tick() + Server()->TickSpeed() * 2; @@ -1215,6 +1218,9 @@ void CCharacter::HandleTiles(int Index) int cpf = GameServer()->Collision()->IsFCheckpoint(MapIndex); if(cpf != -1 && m_DDRaceState == DDRACE_STARTED && cpf > m_CpActive) { + if (g_Config.m_SvStrictCheckpoints && cp != m_CpActive + 1) + return; + m_CpActive = cpf; m_CpCurrent[cpf] = m_Time; m_CpTick = Server()->Tick() + Server()->TickSpeed()*2; @@ -1265,14 +1271,17 @@ void CCharacter::HandleTiles(int Index) if(CanBegin) { Teams()->OnCharacterStart(m_pPlayer->GetCID()); - m_CpActive = -2; + m_CpActive = -1; } else { } } if(((m_TileIndex == TILE_END) || (m_TileFIndex == TILE_END) || FTile1 == TILE_END || FTile2 == TILE_END || FTile3 == TILE_END || FTile4 == TILE_END || Tile1 == TILE_END || Tile2 == TILE_END || Tile3 == TILE_END || Tile4 == TILE_END) && m_DDRaceState == DDRACE_STARTED) - Controller->m_Teams.OnCharacterFinish(m_pPlayer->GetCID()); + { + if (!g_Config.m_SvStrictCheckpoints || m_CpActive == GameServer()->Collision()->m_MaxCheckpoint) + Controller->m_Teams.OnCharacterFinish(m_pPlayer->GetCID()); + } if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Super && !m_DeepFreeze) Freeze(); else if(((m_TileIndex == TILE_UNFREEZE) || (m_TileFIndex == TILE_UNFREEZE)) && !m_DeepFreeze) diff --git a/src/game/server/teams.cpp b/src/game/server/teams.cpp index ac1e102868..ffc1beede4 100644 --- a/src/game/server/teams.cpp +++ b/src/game/server/teams.cpp @@ -342,7 +342,7 @@ void CGameTeams::OnFinish(CPlayer* Player) return; CPlayerData *pData = GameServer()->Score()->PlayerData(Player->GetCID()); char aBuf[128]; - SetCpActive(Player, -2); + SetCpActive(Player, -1); str_format(aBuf, sizeof(aBuf), "%s finished in: %d minute(s) %5.2f second(s)", Server()->ClientName(Player->GetCID()), (int) time / 60,