From 5b3e9e4bbf4f09aa583d66d7536c9af5e4788ddb Mon Sep 17 00:00:00 2001 From: Redix Date: Sun, 10 Sep 2017 03:48:22 +0200 Subject: [PATCH] Improved ghost file management --- src/engine/client.h | 2 +- src/engine/client/client.cpp | 4 +- src/engine/client/client.h | 2 +- src/game/client/components/ghost.cpp | 52 +++++++++----- src/game/client/components/ghost.h | 4 ++ src/game/client/components/menus.h | 2 + src/game/client/components/menus_ingame.cpp | 80 +++++++++++++++++---- 7 files changed, 111 insertions(+), 35 deletions(-) diff --git a/src/engine/client.h b/src/engine/client.h index 157021fc8..fdc48049b 100644 --- a/src/engine/client.h +++ b/src/engine/client.h @@ -184,7 +184,7 @@ public: virtual bool RaceRecord_IsRecording() = 0; virtual void Ghost_GetPath(char *pBuf, int Size, int Time = -1) = 0; - virtual void GhostRecorder_Start() = 0; + virtual void GhostRecorder_Start(int Time = -1) = 0; virtual bool GhostLoader_Load(const char *pFilename) = 0; virtual bool GhostLoader_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader) = 0; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 91c1e23ea..b789a97cd 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -3661,10 +3661,10 @@ void CClient::Ghost_GetPath(char *pBuf, int Size, int Time) str_format(pBuf, Size, "ghosts/%s_%s_%d.%03d_%08x.gho", m_aCurrentMap, aPlayerName, Time / 1000, Time % 1000, m_pMap->Crc()); } -void CClient::GhostRecorder_Start() +void CClient::GhostRecorder_Start(int Time) { char aFilename[128]; - Ghost_GetPath(aFilename, sizeof(aFilename)); + Ghost_GetPath(aFilename, sizeof(aFilename), Time); m_GhostRecorder.Start(Storage(), m_pConsole, aFilename, m_aCurrentMap, m_pMap->Crc(), g_Config.m_PlayerName); } diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 7777cb955..c8d9cd8d1 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -392,7 +392,7 @@ public: bool RaceRecord_IsRecording(); void Ghost_GetPath(char *pBuf, int Size, int Time = -1); - void GhostRecorder_Start(); + void GhostRecorder_Start(int Time = -1); bool GhostLoader_Load(const char *pFilename); bool GhostLoader_GetGhostInfo(const char *pFilename, struct CGhostHeader *pGhostHeader); diff --git a/src/game/client/components/ghost.cpp b/src/game/client/components/ghost.cpp index ea55b360f..4ece7f7f7 100644 --- a/src/game/client/components/ghost.cpp +++ b/src/game/client/components/ghost.cpp @@ -233,15 +233,7 @@ void CGhost::StopRecord(int Time) char aFilename[128] = { 0 }; if(RecordingToFile) - { - // remove old ghost - if(pOwnGhost && pOwnGhost->HasFile()) - Storage()->RemoveFile(pOwnGhost->m_aFilename, IStorage::TYPE_SAVE); - - // save new ghost Client()->Ghost_GetPath(aFilename, sizeof(aFilename), Time); - Storage()->RenameFile(aTmpFilename, aFilename, IStorage::TYPE_SAVE); - } // create ghost item CMenus::CGhostItem Item; @@ -249,14 +241,13 @@ void CGhost::StopRecord(int Time) str_copy(Item.m_aPlayer, g_Config.m_PlayerName, sizeof(Item.m_aPlayer)); Item.m_Time = Time; Item.m_Slot = Slot; - Item.m_Own = true; + + // save new ghost file + if(Item.HasFile()) + Storage()->RenameFile(aTmpFilename, aFilename, IStorage::TYPE_SAVE); // add item to menu list - if(pOwnGhost) - *pOwnGhost = Item; - else - m_pClient->m_pMenus->m_lGhosts.add(Item); - m_pClient->m_pMenus->m_lGhosts.sort_range(); + m_pClient->m_pMenus->UpdateOwnGhost(Item); } else if(RecordingToFile) // no new record Storage()->RemoveFile(aTmpFilename, IStorage::TYPE_SAVE); @@ -364,6 +355,36 @@ void CGhost::Unload(int Slot) m_aActiveGhosts[Slot].Reset(); } +void CGhost::UnloadAll() +{ + for(int i = 0; i < MAX_ACTIVE_GHOSTS; i++) + Unload(i); +} + +void CGhost::SaveGhost(CMenus::CGhostItem *pItem) +{ + int Slot = pItem->m_Slot; + if(Slot < 0 || pItem->HasFile() || m_aActiveGhosts[Slot].Empty() || GhostRecorder()->IsRecording()) + return; + + int NumTicks = m_aActiveGhosts[Slot].m_lPath.size(); + Client()->GhostRecorder_Start(pItem->m_Time); + + const CGameClient::CClientData *pClientData = &m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID]; + CGhostSkin Skin; + StrToInts(&Skin.m_Skin0, 6, pClientData->m_aSkinName); + Skin.m_UseCustomColor = pClientData->m_UseCustomColor; + Skin.m_ColorBody = pClientData->m_ColorBody; + Skin.m_ColorFeet = pClientData->m_ColorFeet; + GhostRecorder()->WriteData(GHOSTDATA_TYPE_SKIN, (const char*)&Skin, sizeof(Skin)); + + for(int i = 0; i < NumTicks; i++) + GhostRecorder()->WriteData(GHOSTDATA_TYPE_CHARACTER, (const char*)&m_aActiveGhosts[Slot].m_lPath[i], sizeof(CGhostCharacter)); + + GhostRecorder()->Stop(NumTicks, pItem->m_Time); + Client()->Ghost_GetPath(pItem->m_aFilename, sizeof(pItem->m_aFilename), pItem->m_Time); +} + void CGhost::ConGPlay(IConsole::IResult *pResult, void *pUserData) { ((CGhost *)pUserData)->StartRender(); @@ -424,8 +445,7 @@ void CGhost::OnReset() void CGhost::OnMapLoad() { OnReset(); - for(int i = 0; i < MAX_ACTIVE_GHOSTS; i++) - Unload(i); + UnloadAll(); m_pClient->m_pMenus->GhostlistPopulate(); m_IsSolo = true; } diff --git a/src/game/client/components/ghost.h b/src/game/client/components/ghost.h index 5b043aec1..1b97ed649 100644 --- a/src/game/client/components/ghost.h +++ b/src/game/client/components/ghost.h @@ -110,6 +110,10 @@ public: int Load(const char *pFilename); void Unload(int Slot); + void UnloadAll(); + + void SaveGhost(CMenus::CGhostItem *pItem); + class IGhostLoader *GhostLoader() const { return m_pGhostLoader; } class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; } }; diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index dd5a8bc43..2071df91f 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -351,6 +351,8 @@ public: void GhostlistPopulate(); CGhostItem *GetOwnGhost(); + void UpdateOwnGhost(CGhostItem Item); + void DeleteGhostItem(int Index); void setPopup(int Popup) { m_Popup = Popup; } diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index 1247f5f67..728c5df74 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -885,6 +885,32 @@ CMenus::CGhostItem *CMenus::GetOwnGhost() return 0; } +void CMenus::UpdateOwnGhost(CGhostItem Item) +{ + int Own = -1; + for(int i = 0; i < m_lGhosts.size(); i++) + if(m_lGhosts[i].m_Own) + Own = i; + + if(Own != -1) + { + m_lGhosts[Own].m_Slot = -1; + m_lGhosts[Own].m_Own = false; + if(Item.HasFile() || !m_lGhosts[Own].HasFile()) + DeleteGhostItem(Own); + } + + Item.m_Own = true; + m_lGhosts.add(Item); +} + +void CMenus::DeleteGhostItem(int Index) +{ + if(m_lGhosts[Index].HasFile()) + Storage()->RemoveFile(m_lGhosts[Index].m_aFilename, IStorage::TYPE_SAVE); + m_lGhosts.remove_index(Index); +} + void CMenus::RenderGhost(CUIRect MainView) { // render background @@ -1045,11 +1071,11 @@ void CMenus::RenderGhost(CUIRect MainView) } } + vec3 rgb = vec3(1.0f, 1.0f, 1.0f); if(pItem->m_Own) - { - vec3 rgb = HslToRgb(vec3(0.33f, 1.0f, 0.75f)); - TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.0f); - } + rgb = HslToRgb(vec3(0.33f, 1.0f, 0.75f)); + + TextRender()->TextColor(rgb.r, rgb.g, rgb.b, pItem->HasFile() ? 1.0f : 0.5f); for(int c = 0; c < NumCols; c++) { @@ -1108,22 +1134,46 @@ void CMenus::RenderGhost(CUIRect MainView) Status.Margin(5.0f, &Status); CUIRect Button; - Status.VSplitRight(120.0f, &Status, &Button); static int s_GhostButton = 0; - bool Delete = !pGhost->HasFile(); - const char *pText = pGhost->Active() ? (Delete ? Localize("Delete") : Localize("Deactivate")) : Localize("Activate"); + static int s_DeleteButton = 0; + static int s_SaveButton = 0; - if(DoButton_Menu(&s_GhostButton, pText, 0, &Button) || (NewSelected != -1 && Input()->MouseDoubleClick())) + if(pGhost->HasFile()) + { + Status.VSplitRight(120.0f, &Status, &Button); + + const char *pText = pGhost->Active() ? Localize("Deactivate") : Localize("Activate"); + if(DoButton_Menu(&s_GhostButton, pText, 0, &Button) || (NewSelected != -1 && Input()->MouseDoubleClick())) + { + if(pGhost->Active()) + { + m_pClient->m_pGhost->Unload(pGhost->m_Slot); + pGhost->m_Slot = -1; + } + else + pGhost->m_Slot = m_pClient->m_pGhost->Load(pGhost->m_aFilename); + } + + Status.VSplitRight(5.0f, &Status, 0); + } + + Status.VSplitRight(120.0f, &Status, &Button); + + if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &Button)) { if(pGhost->Active()) - { m_pClient->m_pGhost->Unload(pGhost->m_Slot); - pGhost->m_Slot = -1; - if(Delete) - m_lGhosts.remove_index(s_SelectedIndex); - } - else - pGhost->m_Slot = m_pClient->m_pGhost->Load(pGhost->m_aFilename); + DeleteGhostItem(s_SelectedIndex); + } + + Status.VSplitRight(5.0f, &Status, 0); + + bool Recording = m_pClient->m_pGhost->GhostRecorder()->IsRecording(); + if(!pGhost->HasFile() && !Recording && pGhost->Active()) + { + Status.VSplitRight(120.0f, &Status, &Button); + if(DoButton_Menu(&s_SaveButton, Localize("Save"), 0, &Button)) + m_pClient->m_pGhost->SaveGhost(pGhost); } }