diff --git a/src/game/client/components/ghost.cpp b/src/game/client/components/ghost.cpp index 38cfec851..61e73e9eb 100644 --- a/src/game/client/components/ghost.cpp +++ b/src/game/client/components/ghost.cpp @@ -216,7 +216,7 @@ void CGhost::CheckStartLocal(bool Predicted) vec2 PrevPos = m_pClient->m_PredictedPrevChar.m_Pos; vec2 Pos = m_pClient->m_PredictedChar.m_Pos; - if(((!m_Rendering && RenderTick == -1) || m_AllowRestart) && CRaceHelper::IsStart(m_pClient, PrevPos, Pos)) + if(((!m_Rendering && RenderTick == -1) || m_AllowRestart) && GameClient()->RaceHelper()->IsStart(PrevPos, Pos)) { if(m_Rendering && !m_RenderingStartedByServer) // race restarted: stop rendering StopRender(); @@ -240,7 +240,7 @@ void CGhost::CheckStartLocal(bool Predicted) int TickDiff = CurTick - PrevTick; for(int i = 0; i < TickDiff; i++) { - if(CRaceHelper::IsStart(m_pClient, mix(PrevPos, Pos, (float)i / TickDiff), mix(PrevPos, Pos, (float)(i + 1) / TickDiff))) + if(GameClient()->RaceHelper()->IsStart(mix(PrevPos, Pos, (float)i / TickDiff), mix(PrevPos, Pos, (float)(i + 1) / TickDiff))) { RecordTick = PrevTick + i + 1; if(!m_AllowRestart) diff --git a/src/game/client/components/race_demo.cpp b/src/game/client/components/race_demo.cpp index 3caef0108..d1de5ef46 100644 --- a/src/game/client/components/race_demo.cpp +++ b/src/game/client/components/race_demo.cpp @@ -79,7 +79,7 @@ void CRaceDemo::OnNewSnapshot() vec2 PrevPos = vec2(m_pClient->m_Snap.m_pLocalPrevCharacter->m_X, m_pClient->m_Snap.m_pLocalPrevCharacter->m_Y); vec2 Pos = vec2(m_pClient->m_Snap.m_pLocalCharacter->m_X, m_pClient->m_Snap.m_pLocalCharacter->m_Y); - if(ForceStart || (!ServerControl && CRaceHelper::IsStart(m_pClient, PrevPos, Pos))) + if(ForceStart || (!ServerControl && GameClient()->RaceHelper()->IsStart(PrevPos, Pos))) { if(m_RaceState == RACE_STARTED) Client()->RaceRecord_Stop(); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index b4ab98477..64ddaf186 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -491,21 +491,7 @@ void CGameClient::OnConnected() m_Layers.Init(Kernel()); m_Collision.Init(Layers()); m_GameWorld.m_Core.InitSwitchers(m_Collision.m_HighestSwitchNumber); - - CRaceHelper::ms_aFlagIndex[0] = -1; - CRaceHelper::ms_aFlagIndex[1] = -1; - - CTile *pGameTiles = static_cast(Layers()->Map()->GetData(Layers()->GameLayer()->m_Data)); - - // get flag positions - for(int i = 0; i < m_Collision.GetWidth() * m_Collision.GetHeight(); i++) - { - if(pGameTiles[i].m_Index - ENTITY_OFFSET == ENTITY_FLAGSTAND_RED) - CRaceHelper::ms_aFlagIndex[TEAM_RED] = i; - else if(pGameTiles[i].m_Index - ENTITY_OFFSET == ENTITY_FLAGSTAND_BLUE) - CRaceHelper::ms_aFlagIndex[TEAM_BLUE] = i; - i += pGameTiles[i].m_Skip; - } + m_RaceHelper.Init(this); // render loading before going through all components m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false); diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 1def52441..fc9f537f6 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -195,6 +196,7 @@ private: CLayers m_Layers; CCollision m_Collision; CUi m_UI; + CRaceHelper m_RaceHelper; void ProcessEvents(); void UpdatePositions(); @@ -258,6 +260,8 @@ public: class CRenderTools *RenderTools() { return &m_RenderTools; } class CLayers *Layers() { return &m_Layers; } CCollision *Collision() { return &m_Collision; } + const CCollision *Collision() const { return &m_Collision; } + const CRaceHelper *RaceHelper() const { return &m_RaceHelper; } class IEditor *Editor() { return m_pEditor; } class IFriends *Friends() { return m_pFriends; } class IFriends *Foes() { return m_pFoes; } diff --git a/src/game/client/race.cpp b/src/game/client/race.cpp index 1ab7a0f41..2b5c5f4ef 100644 --- a/src/game/client/race.cpp +++ b/src/game/client/race.cpp @@ -1,12 +1,39 @@ #include -#include +#include #include +#include #include #include "race.h" -int CRaceHelper::ms_aFlagIndex[2] = {-1, -1}; +void CRaceHelper::Init(const CGameClient *pGameClient) +{ + m_pGameClient = pGameClient; + + m_aFlagIndex[TEAM_RED] = -1; + m_aFlagIndex[TEAM_BLUE] = -1; + + const CTile *pGameTiles = m_pGameClient->Collision()->GameLayer(); + const int MapSize = m_pGameClient->Collision()->GetWidth() * m_pGameClient->Collision()->GetHeight(); + for(int Index = 0; Index < MapSize; Index++) + { + const int EntityIndex = pGameTiles[Index].m_Index - ENTITY_OFFSET; + if(EntityIndex == ENTITY_FLAGSTAND_RED) + { + m_aFlagIndex[TEAM_RED] = Index; + if(m_aFlagIndex[TEAM_BLUE] != -1) + break; // Found both flags + } + else if(EntityIndex == ENTITY_FLAGSTAND_BLUE) + { + m_aFlagIndex[TEAM_BLUE] = Index; + if(m_aFlagIndex[TEAM_RED] != -1) + break; // Found both flags + } + Index += pGameTiles[Index].m_Skip; + } +} int CRaceHelper::TimeFromSecondsStr(const char *pStr) { @@ -66,30 +93,32 @@ int CRaceHelper::TimeFromFinishMessage(const char *pStr, char *pNameBuf, int Nam return TimeFromStr(pFinished + str_length(s_pFinishedStr)); } -bool CRaceHelper::IsStart(CGameClient *pClient, vec2 Prev, vec2 Pos) +bool CRaceHelper::IsStart(vec2 Prev, vec2 Pos) const { - CCollision *pCollision = pClient->Collision(); - if(pClient->m_GameInfo.m_FlagStartsRace) + if(m_pGameClient->m_GameInfo.m_FlagStartsRace) { - int EnemyTeam = pClient->m_aClients[pClient->m_Snap.m_LocalClientId].m_Team ^ 1; - return ms_aFlagIndex[EnemyTeam] != -1 && distance(Pos, pCollision->GetPos(ms_aFlagIndex[EnemyTeam])) < 32; + int EnemyTeam = m_pGameClient->m_aClients[m_pGameClient->m_Snap.m_LocalClientId].m_Team ^ 1; + return m_aFlagIndex[EnemyTeam] != -1 && distance(Pos, m_pGameClient->Collision()->GetPos(m_aFlagIndex[EnemyTeam])) < 32; } else { - std::vector vIndices = pCollision->GetMapIndices(Prev, Pos); + std::vector vIndices = m_pGameClient->Collision()->GetMapIndices(Prev, Pos); if(!vIndices.empty()) - for(int &Indice : vIndices) + { + for(const int Index : vIndices) { - if(pCollision->GetTileIndex(Indice) == TILE_START) + if(m_pGameClient->Collision()->GetTileIndex(Index) == TILE_START) return true; - if(pCollision->GetFTileIndex(Indice) == TILE_START) + if(m_pGameClient->Collision()->GetFTileIndex(Index) == TILE_START) return true; } + } else { - if(pCollision->GetTileIndex(pCollision->GetPureMapIndex(Pos)) == TILE_START) + const int Index = m_pGameClient->Collision()->GetPureMapIndex(Pos); + if(m_pGameClient->Collision()->GetTileIndex(Index) == TILE_START) return true; - if(pCollision->GetFTileIndex(pCollision->GetPureMapIndex(Pos)) == TILE_START) + if(m_pGameClient->Collision()->GetFTileIndex(Index) == TILE_START) return true; } } diff --git a/src/game/client/race.h b/src/game/client/race.h index ae82461b4..b9b67ec64 100644 --- a/src/game/client/race.h +++ b/src/game/client/race.h @@ -3,17 +3,23 @@ #include +class CGameClient; + class CRaceHelper { + const CGameClient *m_pGameClient; + + int m_aFlagIndex[2] = {-1, -1}; + public: - static int ms_aFlagIndex[2]; + void Init(const CGameClient *pGameClient); // these functions return the time in milliseconds, time -1 is invalid static int TimeFromSecondsStr(const char *pStr); // x.xxx static int TimeFromStr(const char *pStr); // x minute(s) x.xxx second(s) static int TimeFromFinishMessage(const char *pStr, char *pNameBuf, int NameBufSize); // xxx finished in: x minute(s) x.xxx second(s) - static bool IsStart(class CGameClient *pClient, vec2 Prev, vec2 Pos); + bool IsStart(vec2 Prev, vec2 Pos) const; }; #endif // GAME_CLIENT_RACE_H diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 28ca23aaf..b640e04c3 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -123,8 +123,8 @@ void CCollision::Init(class CLayers *pLayers) { for(int i = 0; i < m_Width * m_Height; i++) { - int Number = TeleLayer()[i].m_Number; - int Type = TeleLayer()[i].m_Type; + int Number = m_pTele[i].m_Number; + int Type = m_pTele[i].m_Type; if(Number > 0) { if(Type == TILE_TELEIN) @@ -171,7 +171,7 @@ void CCollision::Unload() m_pDoor = nullptr; } -void CCollision::FillAntibot(CAntibotMapData *pMapData) +void CCollision::FillAntibot(CAntibotMapData *pMapData) const { pMapData->m_Width = m_Width; pMapData->m_Height = m_Height; diff --git a/src/game/collision.h b/src/game/collision.h index 91f0f0eed..e6fc4dcb5 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -9,6 +9,14 @@ #include #include +class CTile; +class CLayers; +class CTeleTile; +class CSpeedupTile; +class CSwitchTile; +class CTuneTile; +class CDoorTile; + enum { CANTMOVE_LEFT = 1 << 0, @@ -28,9 +36,9 @@ public: CCollision(); ~CCollision(); - void Init(class CLayers *pLayers); + void Init(CLayers *pLayers); void Unload(); - void FillAntibot(CAntibotMapData *pMapData); + void FillAntibot(CAntibotMapData *pMapData) const; bool CheckPoint(float x, float y) const { return IsSolid(round_to_int(x), round_to_int(y)); } bool CheckPoint(vec2 Pos) const { return CheckPoint(Pos.x, Pos.y); } @@ -60,7 +68,7 @@ public: int GetFIndex(int x, int y) const; int GetMoveRestrictions(CALLBACK_SWITCHACTIVE pfnSwitchActive, void *pUser, vec2 Pos, float Distance = 18.0f, int OverrideCenterTileIndex = -1) const; - int GetMoveRestrictions(vec2 Pos, float Distance = 18.0f) + int GetMoveRestrictions(vec2 Pos, float Distance = 18.0f) const { return GetMoveRestrictions(nullptr, nullptr, Pos, Distance); } @@ -107,10 +115,14 @@ public: vec2 CpSpeed(int index, int Flags = 0) const; - class CTeleTile *TeleLayer() { return m_pTele; } - class CSwitchTile *SwitchLayer() { return m_pSwitch; } - class CTuneTile *TuneLayer() { return m_pTune; } - class CLayers *Layers() { return m_pLayers; } + const CLayers *Layers() const { return m_pLayers; } + const CTile *GameLayer() const { return m_pTiles; } + const CTeleTile *TeleLayer() const { return m_pTele; } + const CSpeedupTile *SpeedupLayer() const { return m_pSpeedup; } + const CTile *FrontLayer() const { return m_pFront; } + const CSwitchTile *SwitchLayer() const { return m_pSwitch; } + const CTuneTile *TuneLayer() const { return m_pTune; } + int m_HighestSwitchNumber; /** @@ -137,10 +149,18 @@ public: const std::vector &TeleOthers(int Number) { return m_TeleOthers[Number]; } private: - class CTile *m_pTiles; + CLayers *m_pLayers; + int m_Width; int m_Height; - class CLayers *m_pLayers; + + CTile *m_pTiles; + CTeleTile *m_pTele; + CSpeedupTile *m_pSpeedup; + CTile *m_pFront; + CSwitchTile *m_pSwitch; + CTuneTile *m_pTune; + CDoorTile *m_pDoor; // TILE_TELEIN std::map> m_TeleIns; @@ -150,13 +170,6 @@ private: std::map> m_TeleCheckOuts; // TILE_TELEINEVIL, TILE_TELECHECK, TILE_TELECHECKIN, TILE_TELECHECKINEVIL std::map> m_TeleOthers; - - class CTeleTile *m_pTele; - class CSpeedupTile *m_pSpeedup; - class CTile *m_pFront; - class CSwitchTile *m_pSwitch; - class CTuneTile *m_pTune; - class CDoorTile *m_pDoor; }; void ThroughOffset(vec2 Pos0, vec2 Pos1, int *pOffsetX, int *pOffsetY);