Merge pull request #8682 from Robyt3/Client-RaceHelper-Refactoring

Refactor `CRaceHelper`, mark `CCollision` functions as `const` and add tile getters
This commit is contained in:
heinrich5991 2024-08-14 08:09:05 +00:00 committed by GitHub
commit e4bc5bde5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 90 additions and 52 deletions

View file

@ -216,7 +216,7 @@ void CGhost::CheckStartLocal(bool Predicted)
vec2 PrevPos = m_pClient->m_PredictedPrevChar.m_Pos; vec2 PrevPos = m_pClient->m_PredictedPrevChar.m_Pos;
vec2 Pos = m_pClient->m_PredictedChar.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 if(m_Rendering && !m_RenderingStartedByServer) // race restarted: stop rendering
StopRender(); StopRender();
@ -240,7 +240,7 @@ void CGhost::CheckStartLocal(bool Predicted)
int TickDiff = CurTick - PrevTick; int TickDiff = CurTick - PrevTick;
for(int i = 0; i < TickDiff; i++) 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; RecordTick = PrevTick + i + 1;
if(!m_AllowRestart) if(!m_AllowRestart)

View file

@ -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 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); 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) if(m_RaceState == RACE_STARTED)
Client()->RaceRecord_Stop(); Client()->RaceRecord_Stop();

View file

@ -491,21 +491,7 @@ void CGameClient::OnConnected()
m_Layers.Init(Kernel()); m_Layers.Init(Kernel());
m_Collision.Init(Layers()); m_Collision.Init(Layers());
m_GameWorld.m_Core.InitSwitchers(m_Collision.m_HighestSwitchNumber); m_GameWorld.m_Core.InitSwitchers(m_Collision.m_HighestSwitchNumber);
m_RaceHelper.Init(this);
CRaceHelper::ms_aFlagIndex[0] = -1;
CRaceHelper::ms_aFlagIndex[1] = -1;
CTile *pGameTiles = static_cast<CTile *>(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;
}
// render loading before going through all components // render loading before going through all components
m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false); m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false);

View file

@ -16,6 +16,7 @@
#include <game/teamscore.h> #include <game/teamscore.h>
#include <game/client/prediction/gameworld.h> #include <game/client/prediction/gameworld.h>
#include <game/client/race.h>
#include <game/generated/protocol7.h> #include <game/generated/protocol7.h>
#include <game/generated/protocolglue.h> #include <game/generated/protocolglue.h>
@ -195,6 +196,7 @@ private:
CLayers m_Layers; CLayers m_Layers;
CCollision m_Collision; CCollision m_Collision;
CUi m_UI; CUi m_UI;
CRaceHelper m_RaceHelper;
void ProcessEvents(); void ProcessEvents();
void UpdatePositions(); void UpdatePositions();
@ -258,6 +260,8 @@ public:
class CRenderTools *RenderTools() { return &m_RenderTools; } class CRenderTools *RenderTools() { return &m_RenderTools; }
class CLayers *Layers() { return &m_Layers; } class CLayers *Layers() { return &m_Layers; }
CCollision *Collision() { return &m_Collision; } 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 IEditor *Editor() { return m_pEditor; }
class IFriends *Friends() { return m_pFriends; } class IFriends *Friends() { return m_pFriends; }
class IFriends *Foes() { return m_pFoes; } class IFriends *Foes() { return m_pFoes; }

View file

@ -1,12 +1,39 @@
#include <cctype> #include <cctype>
#include <list> #include <vector>
#include <game/client/gameclient.h> #include <game/client/gameclient.h>
#include <game/collision.h>
#include <game/mapitems.h> #include <game/mapitems.h>
#include "race.h" #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) 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)); 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(m_pGameClient->m_GameInfo.m_FlagStartsRace)
if(pClient->m_GameInfo.m_FlagStartsRace)
{ {
int EnemyTeam = pClient->m_aClients[pClient->m_Snap.m_LocalClientId].m_Team ^ 1; int EnemyTeam = m_pGameClient->m_aClients[m_pGameClient->m_Snap.m_LocalClientId].m_Team ^ 1;
return ms_aFlagIndex[EnemyTeam] != -1 && distance(Pos, pCollision->GetPos(ms_aFlagIndex[EnemyTeam])) < 32; return m_aFlagIndex[EnemyTeam] != -1 && distance(Pos, m_pGameClient->Collision()->GetPos(m_aFlagIndex[EnemyTeam])) < 32;
} }
else else
{ {
std::vector<int> vIndices = pCollision->GetMapIndices(Prev, Pos); std::vector<int> vIndices = m_pGameClient->Collision()->GetMapIndices(Prev, Pos);
if(!vIndices.empty()) 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; return true;
if(pCollision->GetFTileIndex(Indice) == TILE_START) if(m_pGameClient->Collision()->GetFTileIndex(Index) == TILE_START)
return true; return true;
} }
}
else 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; return true;
if(pCollision->GetFTileIndex(pCollision->GetPureMapIndex(Pos)) == TILE_START) if(m_pGameClient->Collision()->GetFTileIndex(Index) == TILE_START)
return true; return true;
} }
} }

View file

@ -3,17 +3,23 @@
#include <base/vmath.h> #include <base/vmath.h>
class CGameClient;
class CRaceHelper class CRaceHelper
{ {
const CGameClient *m_pGameClient;
int m_aFlagIndex[2] = {-1, -1};
public: public:
static int ms_aFlagIndex[2]; void Init(const CGameClient *pGameClient);
// these functions return the time in milliseconds, time -1 is invalid // these functions return the time in milliseconds, time -1 is invalid
static int TimeFromSecondsStr(const char *pStr); // x.xxx static int TimeFromSecondsStr(const char *pStr); // x.xxx
static int TimeFromStr(const char *pStr); // x minute(s) x.xxx second(s) 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 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 #endif // GAME_CLIENT_RACE_H

View file

@ -123,8 +123,8 @@ void CCollision::Init(class CLayers *pLayers)
{ {
for(int i = 0; i < m_Width * m_Height; i++) for(int i = 0; i < m_Width * m_Height; i++)
{ {
int Number = TeleLayer()[i].m_Number; int Number = m_pTele[i].m_Number;
int Type = TeleLayer()[i].m_Type; int Type = m_pTele[i].m_Type;
if(Number > 0) if(Number > 0)
{ {
if(Type == TILE_TELEIN) if(Type == TILE_TELEIN)
@ -171,7 +171,7 @@ void CCollision::Unload()
m_pDoor = nullptr; m_pDoor = nullptr;
} }
void CCollision::FillAntibot(CAntibotMapData *pMapData) void CCollision::FillAntibot(CAntibotMapData *pMapData) const
{ {
pMapData->m_Width = m_Width; pMapData->m_Width = m_Width;
pMapData->m_Height = m_Height; pMapData->m_Height = m_Height;

View file

@ -9,6 +9,14 @@
#include <map> #include <map>
#include <vector> #include <vector>
class CTile;
class CLayers;
class CTeleTile;
class CSpeedupTile;
class CSwitchTile;
class CTuneTile;
class CDoorTile;
enum enum
{ {
CANTMOVE_LEFT = 1 << 0, CANTMOVE_LEFT = 1 << 0,
@ -28,9 +36,9 @@ public:
CCollision(); CCollision();
~CCollision(); ~CCollision();
void Init(class CLayers *pLayers); void Init(CLayers *pLayers);
void Unload(); 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(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); } bool CheckPoint(vec2 Pos) const { return CheckPoint(Pos.x, Pos.y); }
@ -60,7 +68,7 @@ public:
int GetFIndex(int x, int y) const; 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(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); return GetMoveRestrictions(nullptr, nullptr, Pos, Distance);
} }
@ -107,10 +115,14 @@ public:
vec2 CpSpeed(int index, int Flags = 0) const; vec2 CpSpeed(int index, int Flags = 0) const;
class CTeleTile *TeleLayer() { return m_pTele; } const CLayers *Layers() const { return m_pLayers; }
class CSwitchTile *SwitchLayer() { return m_pSwitch; } const CTile *GameLayer() const { return m_pTiles; }
class CTuneTile *TuneLayer() { return m_pTune; } const CTeleTile *TeleLayer() const { return m_pTele; }
class CLayers *Layers() { return m_pLayers; } 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; int m_HighestSwitchNumber;
/** /**
@ -137,10 +149,18 @@ public:
const std::vector<vec2> &TeleOthers(int Number) { return m_TeleOthers[Number]; } const std::vector<vec2> &TeleOthers(int Number) { return m_TeleOthers[Number]; }
private: private:
class CTile *m_pTiles; CLayers *m_pLayers;
int m_Width; int m_Width;
int m_Height; 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 // TILE_TELEIN
std::map<int, std::vector<vec2>> m_TeleIns; std::map<int, std::vector<vec2>> m_TeleIns;
@ -150,13 +170,6 @@ private:
std::map<int, std::vector<vec2>> m_TeleCheckOuts; std::map<int, std::vector<vec2>> m_TeleCheckOuts;
// TILE_TELEINEVIL, TILE_TELECHECK, TILE_TELECHECKIN, TILE_TELECHECKINEVIL // TILE_TELEINEVIL, TILE_TELECHECK, TILE_TELECHECKIN, TILE_TELECHECKINEVIL
std::map<int, std::vector<vec2>> m_TeleOthers; std::map<int, std::vector<vec2>> 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); void ThroughOffset(vec2 Pos0, vec2 Pos1, int *pOffsetX, int *pOffsetY);