Switch to loading screen, when map creation takes too long

This commit is contained in:
Jupeyy 2022-06-23 19:59:38 +02:00
parent fda0eccf37
commit b62894dad4
17 changed files with 219 additions and 88 deletions

View file

@ -8,6 +8,7 @@
#include "message.h"
#include <base/hash.h>
#include <engine/friends.h>
#include <functional>
struct SWarning;
@ -28,9 +29,45 @@ struct CChecksumData;
class IClient : public IInterface
{
MACRO_INTERFACE("client", 0)
public:
/* Constants: Client States
STATE_OFFLINE - The client is offline.
STATE_CONNECTING - The client is trying to connect to a server.
STATE_LOADING - The client has connected to a server and is loading resources.
STATE_ONLINE - The client is connected to a server and running the game.
STATE_DEMOPLAYBACK - The client is playing a demo
STATE_QUITTING - The client is quitting.
*/
enum EClientState
{
STATE_OFFLINE = 0,
STATE_CONNECTING,
STATE_LOADING,
STATE_ONLINE,
STATE_DEMOPLAYBACK,
STATE_QUITTING,
STATE_RESTARTING,
};
/**
* More precise state for @see STATE_LOADING
* Sets what is actually happening in the client right now
*/
enum ELoadingStateDetail
{
LOADING_STATE_DETAIL_INITIAL,
LOADING_STATE_DETAIL_LOADING_MAP,
LOADING_STATE_DETAIL_SENDING_READY,
LOADING_STATE_DETAIL_GETTING_READY,
};
typedef std::function<void()> TMapLoadingCallbackFunc;
protected:
// quick access to state of the client
int m_State;
EClientState m_State;
ELoadingStateDetail m_LoadingStateDetail;
int64_t m_StateStartTime;
// quick access to time variables
@ -50,6 +87,8 @@ protected:
float m_FrameTimeAvg;
TMapLoadingCallbackFunc m_MapLoadingCBFunc;
public:
char m_aNews[3000];
char m_aMapDownloadUrl[256];
@ -72,26 +111,6 @@ public:
NUM_CONNS,
};
/* Constants: Client States
STATE_OFFLINE - The client is offline.
STATE_CONNECTING - The client is trying to connect to a server.
STATE_LOADING - The client has connected to a server and is loading resources.
STATE_ONLINE - The client is connected to a server and running the game.
STATE_DEMOPLAYBACK - The client is playing a demo
STATE_QUITTING - The client is quitting.
*/
enum
{
STATE_OFFLINE = 0,
STATE_CONNECTING,
STATE_LOADING,
STATE_ONLINE,
STATE_DEMOPLAYBACK,
STATE_QUITTING,
STATE_RESTARTING,
};
enum
{
CONNECTIVITY_UNKNOWN,
@ -104,8 +123,12 @@ public:
};
//
inline int State() const { return m_State; }
inline EClientState State() const { return m_State; }
inline ELoadingStateDetail LoadingStateDetail() const { return m_LoadingStateDetail; }
inline int64_t StateStartTime() const { return m_StateStartTime; }
void SetLoadingStateDetail(ELoadingStateDetail LoadingStateDetail) { m_LoadingStateDetail = LoadingStateDetail; }
void SetMapLoadingCBFunc(TMapLoadingCallbackFunc &&Func) { m_MapLoadingCBFunc = std::move(Func); }
// tick time access
inline int PrevGameTick(int Conn) const { return m_PrevGameTick[Conn]; }

View file

@ -630,7 +630,7 @@ int *CClient::GetInput(int Tick, int IsDummy) const
}
// ------ state handling -----
void CClient::SetState(int s)
void CClient::SetState(EClientState s)
{
if(m_State == IClient::STATE_QUITTING || m_State == IClient::STATE_RESTARTING)
return;
@ -1197,6 +1197,10 @@ const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DI
static char s_aErrorMsg[128];
SetState(IClient::STATE_LOADING);
SetLoadingStateDetail(IClient::LOADING_STATE_DETAIL_LOADING_MAP);
if((bool)m_MapLoadingCBFunc)
m_MapLoadingCBFunc();
if(!m_pMap->Load(pFilename))
{
@ -1279,6 +1283,7 @@ const char *CClient::LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedS
str_format(aBuf, sizeof(aBuf), "loading map, map=%s wanted %scrc=%08x", pMapName, aWanted, WantedCrc);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
SetState(IClient::STATE_LOADING);
SetLoadingStateDetail(IClient::LOADING_STATE_DETAIL_LOADING_MAP);
// try the normal maps folder
str_format(aBuf, sizeof(aBuf), "maps/%s.map", pMapName);
@ -1689,6 +1694,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
if(!pError)
{
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
SetLoadingStateDetail(IClient::LOADING_STATE_DETAIL_SENDING_READY);
SendReady();
}
else
@ -2438,6 +2444,7 @@ void CClient::PumpNetwork()
// we switched to online
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", "connected, sending info", ClientNetworkPrintColor);
SetState(IClient::STATE_LOADING);
SetLoadingStateDetail(IClient::LOADING_STATE_DETAIL_INITIAL);
SendInfo();
}
}

View file

@ -344,7 +344,7 @@ public:
const char *LatestVersion() const override;
// ------ state handling -----
void SetState(int s);
void SetState(EClientState s);
// called when the map is loaded and we should init for a new round
void OnEnterGame(bool Dummy);

View file

@ -15,6 +15,7 @@
#include <game/client/components/camera.h>
#include <game/client/components/mapimages.h>
#include <game/localization.h>
#include "maplayers.h"
@ -414,6 +415,18 @@ void CMapLayers::OnMapLoad()
{
if(!Graphics()->IsTileBufferingEnabled() && !Graphics()->IsQuadBufferingEnabled())
return;
const char *pConnectCaption = GameClient()->DemoPlayer()->IsPlaying() ? Localize("Preparing demo playback") : Localize("Connected");
const char *pLoadMapContent = Localize("Uploading map data to GPU");
auto CurTime = time_get_nanoseconds();
auto &&RenderLoading = [&]() {
if(CanRenderMenuBackground())
GameClient()->m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false);
else if(time_get_nanoseconds() - CurTime > 500ms)
GameClient()->m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false, false);
};
//clear everything and destroy all buffers
if(!m_vpTileLayerVisuals.empty())
{
@ -434,6 +447,8 @@ void CMapLayers::OnMapLoad()
delete m_vpQuadLayerVisuals[i];
}
m_vpQuadLayerVisuals.clear();
RenderLoading();
}
bool PassedGameLayer = false;
@ -864,6 +879,8 @@ void CMapLayers::OnMapLoad()
Visuals.m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo);
// and finally inform the backend how many indices are required
Graphics()->IndicesNumRequiredNotify(vtmpTiles.size() * 6);
RenderLoading();
}
++CurOverlay;
@ -974,6 +991,8 @@ void CMapLayers::OnMapLoad()
pQLayerVisuals->m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo);
// and finally inform the backend how many indices are required
Graphics()->IndicesNumRequiredNotify(pQLayer->m_NumQuads * 6);
RenderLoading();
}
}
}

View file

@ -134,6 +134,9 @@ class CMapLayers : public CComponent
void RenderTileBorderCornerTiles(int WidthOffsetToOrigin, int HeightOffsetToOrigin, int TileCountWidth, int TileCountHeight, int BufferContainerIndex, float *pColor, offset_ptr_size IndexBufferOffset, float *pOffset, float *pDir);
protected:
virtual bool CanRenderMenuBackground() { return true; }
public:
enum
{

View file

@ -32,6 +32,9 @@ class CMenuBackground : public CBackground
{
std::chrono::nanoseconds m_ThemeScanStartTime{0};
protected:
bool CanRenderMenuBackground() override { return false; }
public:
enum
{

View file

@ -1,6 +1,7 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <algorithm>
#include <chrono>
#include <cmath>
#include <vector>
@ -9,6 +10,7 @@
#include <base/system.h>
#include <base/vmath.h>
#include <engine/client.h>
#include <engine/editor.h>
#include <engine/friends.h>
#include <engine/graphics.h>
@ -915,14 +917,13 @@ int CMenus::RenderMenubar(CUIRect r)
return 0;
}
void CMenus::RenderLoading(bool IncreaseCounter, bool RenderLoadingBar)
void CMenus::RenderLoading(const char *pCaption, const char *pContent, int IncreaseCounter, bool RenderLoadingBar, bool RenderMenuBackgroundMap)
{
// TODO: not supported right now due to separate render thread
static std::chrono::nanoseconds LastLoadRender{0};
auto CurLoadRenderCount = m_LoadCurrent;
if(IncreaseCounter)
++m_LoadCurrent;
m_LoadCurrent += IncreaseCounter;
float Percent = CurLoadRenderCount / (float)m_LoadTotal;
// make sure that we don't render for each little thing we load
@ -936,41 +937,44 @@ void CMenus::RenderLoading(bool IncreaseCounter, bool RenderLoadingBar)
ms_GuiColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_UiColor, true));
CUIRect Screen = *UI()->Screen();
// some margin around the screen
Screen.Margin(10.0f, &Screen);
UI()->MapScreen();
if(!m_pBackground->Render())
if(!RenderMenuBackgroundMap || !m_pBackground->Render())
{
RenderBackground();
}
float w = 700;
float h = 200;
float x = Screen.w / 2 - w / 2;
float y = Screen.h / 2 - h / 2;
CUIRect Box = Screen;
Box.Margin(150.0f, &Box);
Graphics()->BlendNormal();
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0, 0, 0, 0.50f);
RenderTools()->DrawRoundRect(x, y, w, h, 40.0f);
Graphics()->QuadsEnd();
RenderTools()->DrawUIRect(&Box, ColorRGBA{0, 0, 0, 0.50f}, CUI::CORNER_ALL, 15.0f);
const char *pCaption = Localize("Loading DDNet Client");
CUIRect Part;
CUIRect r;
r.x = x;
r.y = y + 20;
r.w = w;
r.h = h - 130;
UI()->DoLabel(&r, pCaption, 48.0f, TEXTALIGN_CENTER);
Box.HSplitTop(20.f, &Part, &Box);
Box.HSplitTop(24.f, &Part, &Box);
Part.VMargin(20.f, &Part);
SLabelProperties Props;
Props.m_MaxWidth = (int)Part.w;
UI()->DoLabel(&Part, pCaption, 24.f, TEXTALIGN_CENTER);
Box.HSplitTop(20.f, &Part, &Box);
Box.HSplitTop(24.f, &Part, &Box);
Part.VMargin(20.f, &Part);
Props.m_MaxWidth = (int)Part.w;
UI()->DoLabel(&Part, pContent, 20.0f, TEXTALIGN_CENTER);
if(RenderLoadingBar)
{
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1, 1, 1, 0.75f);
RenderTools()->DrawRoundRect(x + 40, y + h - 75, (w - 80) * Percent, 25, 5.0f);
RenderTools()->DrawRoundRect(Box.x + 40, Box.y + Box.h - 75, (Box.w - 80) * Percent, 25, 5.0f);
Graphics()->QuadsEnd();
}
@ -1035,7 +1039,7 @@ void CMenus::OnInit()
// setup load amount
const int NumMenuImages = 5;
m_LoadCurrent = 0;
m_LoadTotal = g_pData->m_NumImages + NumMenuImages;
m_LoadTotal = g_pData->m_NumImages + NumMenuImages + GameClient()->ComponentCount();
if(!g_Config.m_ClThreadsoundloading)
m_LoadTotal += g_pData->m_NumSounds;
@ -1487,6 +1491,29 @@ int CMenus::Render()
pTitle = aBuf;
pExtraText = "";
}
else if(Client()->State() == IClient::STATE_LOADING)
{
if(Client()->LoadingStateDetail() == IClient::LOADING_STATE_DETAIL_INITIAL)
{
pTitle = Localize("Connected");
pExtraText = Localize("Getting game info");
}
else if(Client()->LoadingStateDetail() == IClient::LOADING_STATE_DETAIL_LOADING_MAP)
{
pTitle = Localize("Connected");
pExtraText = Localize("Loading map file from storage");
}
else if(Client()->LoadingStateDetail() == IClient::LOADING_STATE_DETAIL_SENDING_READY)
{
pTitle = Localize("Connected");
pExtraText = Localize("Requesting to join the game");
}
else if(Client()->LoadingStateDetail() == IClient::LOADING_STATE_DETAIL_GETTING_READY)
{
pTitle = Localize("Connected");
pExtraText = Localize("Sending intial client info");
}
}
}
else if(m_Popup == POPUP_DISCONNECTED)
{
@ -2667,41 +2694,54 @@ int CMenus::MenuImageScan(const char *pName, int IsDir, int DirType, void *pUser
return 0;
char aBuf[IO_MAX_PATH_LENGTH];
str_format(aBuf, sizeof(aBuf), "menuimages/%s", pName);
CImageInfo Info;
if(!pSelf->Graphics()->LoadPNG(&Info, aBuf, DirType))
bool ImgExists = false;
for(const auto &Img : pSelf->m_vMenuImages)
{
str_format(aBuf, sizeof(aBuf), "failed to load menu image from %s", pName);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
return 0;
str_format(aBuf, std::size(aBuf), "%s.png", Img.m_aName);
if(str_comp(aBuf, pName) == 0)
{
ImgExists = true;
break;
}
}
CMenuImage MenuImage;
MenuImage.m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
unsigned char *d = (unsigned char *)Info.m_pData;
//int Pitch = Info.m_Width*4;
// create colorless version
int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3;
// make the texture gray scale
for(int i = 0; i < Info.m_Width * Info.m_Height; i++)
if(!ImgExists)
{
int v = (d[i * Step] + d[i * Step + 1] + d[i * Step + 2]) / 3;
d[i * Step] = v;
d[i * Step + 1] = v;
d[i * Step + 2] = v;
str_format(aBuf, sizeof(aBuf), "menuimages/%s", pName);
CImageInfo Info;
if(!pSelf->Graphics()->LoadPNG(&Info, aBuf, DirType))
{
str_format(aBuf, sizeof(aBuf), "failed to load menu image from %s", pName);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
return 0;
}
CMenuImage MenuImage;
MenuImage.m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
unsigned char *d = (unsigned char *)Info.m_pData;
//int Pitch = Info.m_Width*4;
// create colorless version
int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3;
// make the texture gray scale
for(int i = 0; i < Info.m_Width * Info.m_Height; i++)
{
int v = (d[i * Step] + d[i * Step + 1] + d[i * Step + 2]) / 3;
d[i * Step] = v;
d[i * Step + 1] = v;
d[i * Step + 2] = v;
}
MenuImage.m_GreyTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
pSelf->Graphics()->FreePNG(&Info);
// set menu image data
str_truncate(MenuImage.m_aName, sizeof(MenuImage.m_aName), pName, str_length(pName) - 4);
pSelf->m_vMenuImages.push_back(MenuImage);
pSelf->RenderLoading(Localize("Loading DDNet Client"), Localize("Loading menu images"), 1);
}
MenuImage.m_GreyTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
pSelf->Graphics()->FreePNG(&Info);
// set menu image data
str_truncate(MenuImage.m_aName, sizeof(MenuImage.m_aName), pName, str_length(pName) - 4);
pSelf->m_vMenuImages.push_back(MenuImage);
pSelf->RenderLoading(true);
return 0;
}

View file

@ -549,7 +549,7 @@ public:
CMenus();
virtual int Sizeof() const override { return sizeof(*this); }
void RenderLoading(bool IncreaseCounter, bool RenderLoadingBar = true);
void RenderLoading(const char *pCaption, const char *pContent, int IncreaseCounter, bool RenderLoadingBar = true, bool RenderMenuBackgroundMap = true);
bool IsInit() { return m_IsInit; }

View file

@ -771,7 +771,7 @@ int CMenus::DemolistFetchCallback(const CFsFileInfo *pInfo, int IsDir, int Stora
if(time_get_nanoseconds() - pSelf->m_DemoPopulateStartTime > 500ms)
{
pSelf->GameClient()->m_Menus.RenderLoading(false, false);
pSelf->GameClient()->m_Menus.RenderLoading(Localize("Loading demo files"), "", 0, false);
}
return 0;

View file

@ -871,7 +871,7 @@ int CMenus::GhostlistFetchCallback(const char *pName, int IsDir, int StorageType
if(time_get_nanoseconds() - pSelf->m_GhostPopulateStartTime > 500ms)
{
pSelf->GameClient()->m_Menus.RenderLoading(false, false);
pSelf->GameClient()->m_Menus.RenderLoading(Localize("Loading ghost files"), "", 0, false);
}
return 0;

View file

@ -823,7 +823,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
// if skin refreshing takes to long, swap to a loading screen
if(time_get_nanoseconds() - SkinStartLoadTime > 500ms)
{
RenderLoading(false, false);
RenderLoading(Localize("Loading skin files"), "", 0, false);
}
});
s_InitSkinlist = true;

View file

@ -392,7 +392,7 @@ void CMenus::RenderSettingsCustom(CUIRect MainView)
User.m_pUser = this;
User.m_LoadedFunc = [&]() {
if(time_get_nanoseconds() - LoadStartTime > 500ms)
RenderLoading(false, false);
RenderLoading(Localize("Loading assets"), "", 0, false);
};
if(s_CurCustomTab == ASSETS_TAB_ENTITIES)
{

View file

@ -7,6 +7,7 @@
#include <engine/storage.h>
#include <game/client/race.h>
#include <game/localization.h>
#include "race_demo.h"
@ -223,7 +224,7 @@ int CRaceDemo::RaceDemolistFetchCallback(const CFsFileInfo *pInfo, int IsDir, in
if(time_get_nanoseconds() - pRealUser->m_pThis->m_RaceDemosLoadStartTime > 500ms)
{
pRealUser->m_pThis->GameClient()->m_Menus.RenderLoading(false, false);
pRealUser->m_pThis->GameClient()->m_Menus.RenderLoading(Localize("Loading race demo files"), "", 0, false);
}
return 0;

View file

@ -13,6 +13,7 @@
#include <game/generated/client_data.h>
#include <game/client/gameclient.h>
#include <game/localization.h>
#include "skins.h"
@ -317,7 +318,7 @@ void CSkins::OnInit()
// load skins;
Refresh([this](int SkinID) {
GameClient()->m_Menus.RenderLoading(false);
GameClient()->m_Menus.RenderLoading(Localize("Loading DDNet Client"), Localize("Loading skin files"), 0);
});
}

View file

@ -2,6 +2,7 @@
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include "sounds.h"
#include <engine/engine.h>
#include <engine/shared/config.h>
#include <engine/sound.h>
@ -9,6 +10,7 @@
#include <game/client/components/menus.h>
#include <game/client/gameclient.h>
#include <game/generated/client_data.h>
#include <game/localization.h>
CSoundLoading::CSoundLoading(CGameClient *pGameClient, bool Render) :
m_pGameClient(pGameClient),
@ -20,17 +22,20 @@ void CSoundLoading::Run()
{
for(int s = 0; s < g_pData->m_NumSounds; s++)
{
const char *pLoadingCaption = Localize("Loading DDNet Client");
const char *pLoadingContent = Localize("Loading sound files");
for(int i = 0; i < g_pData->m_aSounds[s].m_NumSounds; i++)
{
int Id = m_pGameClient->Sound()->LoadWV(g_pData->m_aSounds[s].m_aSounds[i].m_pFilename);
g_pData->m_aSounds[s].m_aSounds[i].m_Id = Id;
// try to render a frame
if(m_Render)
m_pGameClient->m_Menus.RenderLoading(false);
m_pGameClient->m_Menus.RenderLoading(pLoadingCaption, pLoadingContent, 0);
}
if(m_Render)
m_pGameClient->m_Menus.RenderLoading(true);
m_pGameClient->m_Menus.RenderLoading(pLoadingCaption, pLoadingContent, 1);
}
}
@ -80,7 +85,7 @@ void CSounds::OnInit()
m_pSoundJob = std::make_shared<CSoundLoading>(m_pClient, false);
m_pClient->Engine()->AddJob(m_pSoundJob);
m_WaitForSoundJob = true;
m_pClient->m_Menus.RenderLoading(true);
m_pClient->m_Menus.RenderLoading(Localize("Loading DDNet Client"), Localize("Loading sound files"), 0);
}
else
{

View file

@ -216,6 +216,10 @@ void CGameClient::OnConsoleInit()
void CGameClient::OnInit()
{
Client()->SetMapLoadingCBFunc([this]() {
m_Menus.RenderLoading(DemoPlayer()->IsPlaying() ? Localize("Preparing demo playback") : Localize("Connected"), Localize("Loading map file from storage"), 0, false);
});
m_pGraphics = Kernel()->RequestInterface<IGraphics>();
m_pGraphics->AddWindowResizeListener(OnWindowResizeCB, this);
@ -248,13 +252,27 @@ void CGameClient::OnInit()
// update and swap after font loading, they are quite huge
Client()->UpdateAndSwap();
const char *pLoadingDDNetCaption = Localize("Loading DDNet Client");
// init all components
int SkippedComps = 0;
int CompCounter = 0;
for(int i = m_vpAll.size() - 1; i >= 0; --i)
{
m_vpAll[i]->OnInit();
// try to render a frame after each component, also flushes GPU uploads
if(m_Menus.IsInit())
m_Menus.RenderLoading(false);
{
char aBuff[256];
str_format(aBuff, std::size(aBuff), "%s [%d/%d]", Localize("Initializing components"), (CompCounter + 1), (int)ComponentCount());
m_Menus.RenderLoading(pLoadingDDNetCaption, aBuff, 1 + SkippedComps);
SkippedComps = 0;
}
else
{
++SkippedComps;
}
++CompCounter;
}
char aBuf[256];
@ -264,7 +282,7 @@ void CGameClient::OnInit()
m_EmoticonsSkinLoaded = false;
m_HudSkinLoaded = false;
// setup load amount// load textures
// setup load amount, load textures
for(int i = 0; i < g_pData->m_NumImages; i++)
{
if(i == IMAGE_GAME)
@ -277,7 +295,7 @@ void CGameClient::OnInit()
LoadHudSkin(g_Config.m_ClAssetHud);
else
g_pData->m_aImages[i].m_Id = Graphics()->LoadTexture(g_pData->m_aImages[i].m_pFilename, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_Menus.RenderLoading(false);
m_Menus.RenderLoading(pLoadingDDNetCaption, Localize("Initializing assets"), 1);
}
for(auto &pComponent : m_vpAll)
@ -444,6 +462,10 @@ int CGameClient::OnSnapInput(int *pData, bool Dummy, bool Force)
void CGameClient::OnConnected()
{
const char *pConnectCaption = DemoPlayer()->IsPlaying() ? Localize("Preparing demo playback") : Localize("Connected");
const char *pLoadMapContent = Localize("Initializing map logic");
// render loading before skip is calculated
m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false);
m_Layers.Init(Kernel());
m_Collision.Init(Layers());
m_GameWorld.m_Core.InitSwitchers(m_Collision.m_HighestSwitchNumber);
@ -463,12 +485,17 @@ void CGameClient::OnConnected()
i += pGameTiles[i].m_Skip;
}
// render loading before going through all components
m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false);
for(auto &pComponent : m_vpAll)
{
pComponent->OnMapLoad();
pComponent->OnReset();
}
Client()->SetLoadingStateDetail(IClient::LOADING_STATE_DETAIL_GETTING_READY);
m_Menus.RenderLoading(pConnectCaption, Localize("Sending initial client info"), 0, false);
m_ServerMode = SERVERMODE_PURE;
// send the initial info

View file

@ -440,6 +440,8 @@ public:
void OnReset();
size_t ComponentCount() { return m_vpAll.size(); }
// hooks
void OnConnected() override;
void OnRender() override;